Software APIs
dt_mbx.c
Go to the documentation of this file.
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4//
5// Device table API auto-generated by `dtgen`
6
7/**
8 * @file
9 * @brief Device Tables (DT) for IP mbx and top darjeeling.
10 */
11
12#include "dt/dt_mbx.h"
13
14
15
16/**
17 * Description of instances.
18 */
19typedef struct dt_desc_mbx {
20 dt_instance_id_t inst_id; /**< Instance ID */
21 uint32_t base_addr[kDtMbxRegBlockCount]; /**< Base address of each register block */
22 /**
23 * PLIC ID of the first IRQ of this instance
24 *
25 * This can be `kDtPlicIrqIdNone` if the block is not connected to the PLIC.
26 */
28 /**
29 * Alert ID of the first Alert of this instance.
30 *
31 * This value is undefined if the block is not connected to the Alert Handler.
32 */
34 dt_clock_t clock[kDtMbxClockCount]; /**< Clock signal connected to each clock port */
35 dt_reset_t reset[kDtMbxResetCount]; /**< Reset signal connected to each reset port */
37
38
39
40
41static const dt_desc_mbx_t mbx_desc[kDtMbxCount] = {
42 [kDtMbx0] = {
43 .inst_id = kDtInstanceIdMbx0,
44 .base_addr = {
45 [kDtMbxRegBlockCore] = 0x22000000,
46 [kDtMbxRegBlockSoc] = 0xffffffff,
47 },
50 .clock = {
52 },
53 .reset = {
55 },
56 },
57 [kDtMbx1] = {
58 .inst_id = kDtInstanceIdMbx1,
59 .base_addr = {
60 [kDtMbxRegBlockCore] = 0x22000100,
61 [kDtMbxRegBlockSoc] = 0xffffffff,
62 },
65 .clock = {
67 },
68 .reset = {
70 },
71 },
72 [kDtMbx2] = {
73 .inst_id = kDtInstanceIdMbx2,
74 .base_addr = {
75 [kDtMbxRegBlockCore] = 0x22000200,
76 [kDtMbxRegBlockSoc] = 0xffffffff,
77 },
80 .clock = {
82 },
83 .reset = {
85 },
86 },
87 [kDtMbx3] = {
88 .inst_id = kDtInstanceIdMbx3,
89 .base_addr = {
90 [kDtMbxRegBlockCore] = 0x22000300,
91 [kDtMbxRegBlockSoc] = 0xffffffff,
92 },
95 .clock = {
97 },
98 .reset = {
100 },
101 },
102 [kDtMbx4] = {
103 .inst_id = kDtInstanceIdMbx4,
104 .base_addr = {
105 [kDtMbxRegBlockCore] = 0x22000400,
106 [kDtMbxRegBlockSoc] = 0xffffffff,
107 },
110 .clock = {
112 },
113 .reset = {
115 },
116 },
117 [kDtMbx5] = {
118 .inst_id = kDtInstanceIdMbx5,
119 .base_addr = {
120 [kDtMbxRegBlockCore] = 0x22000500,
121 [kDtMbxRegBlockSoc] = 0xffffffff,
122 },
125 .clock = {
127 },
128 .reset = {
130 },
131 },
132 [kDtMbx6] = {
133 .inst_id = kDtInstanceIdMbx6,
134 .base_addr = {
135 [kDtMbxRegBlockCore] = 0x22000600,
136 [kDtMbxRegBlockSoc] = 0xffffffff,
137 },
140 .clock = {
142 },
143 .reset = {
145 },
146 },
147 [kDtMbxJtag] = {
148 .inst_id = kDtInstanceIdMbxJtag,
149 .base_addr = {
150 [kDtMbxRegBlockCore] = 0x22000800,
151 [kDtMbxRegBlockSoc] = 0xffffffff,
152 },
155 .clock = {
157 },
158 .reset = {
160 },
161 },
162 [kDtMbxPcie0] = {
163 .inst_id = kDtInstanceIdMbxPcie0,
164 .base_addr = {
165 [kDtMbxRegBlockCore] = 0x22040000,
166 [kDtMbxRegBlockSoc] = 0xffffffff,
167 },
170 .clock = {
172 },
173 .reset = {
175 },
176 },
177 [kDtMbxPcie1] = {
178 .inst_id = kDtInstanceIdMbxPcie1,
179 .base_addr = {
180 [kDtMbxRegBlockCore] = 0x22040100,
181 [kDtMbxRegBlockSoc] = 0xffffffff,
182 },
185 .clock = {
187 },
188 .reset = {
190 },
191 },
192};
193
194/**
195 * Return a pointer to the `dt_mbx_desc_t` structure of the requested
196 * `dt` if it's a valid index. Otherwise, this macro will `return` (i.e. exit
197 * the function) with the provided default value.
198 */
199#define TRY_GET_DT(dt, default) ({ if ((dt) < (dt_mbx_t)0 || (dt) >= kDtMbxCount) return (default); &mbx_desc[dt]; })
200
202 if (inst_id >= kDtInstanceIdMbx0 && inst_id <= kDtInstanceIdMbxPcie1) {
203 return (dt_mbx_t)(inst_id - kDtInstanceIdMbx0);
204 }
205 return (dt_mbx_t)0;
206}
207
212
214 dt_mbx_t dt,
215 dt_mbx_reg_block_t reg_block) {
216 // Return a recognizable address in case of wrong argument.
217 return TRY_GET_DT(dt, 0xdeadbeef)->base_addr[reg_block];
218}
219
221 dt_mbx_t dt,
222 dt_mbx_irq_t irq) {
223 dt_plic_irq_id_t first_irq = TRY_GET_DT(dt, kDtPlicIrqIdNone)->first_irq;
224 if (first_irq == kDtPlicIrqIdNone) {
225 return kDtPlicIrqIdNone;
226 }
227 return (dt_plic_irq_id_t)((uint32_t)first_irq + (uint32_t)irq);
228}
229
231 dt_mbx_t dt,
232 dt_plic_irq_id_t irq) {
233 dt_mbx_irq_t count = kDtMbxIrqCount;
234 dt_plic_irq_id_t first_irq = TRY_GET_DT(dt, count)->first_irq;
235 if (first_irq == kDtPlicIrqIdNone) {
236 return count;
237 }
238 if (irq < first_irq || irq >= first_irq + (dt_plic_irq_id_t)count) {
239 return count;
240 }
241 return (dt_mbx_irq_t)(irq - first_irq);
242}
243
244
246 dt_mbx_t dt,
247 dt_mbx_alert_t alert) {
248 return (dt_alert_id_t)((uint32_t)mbx_desc[dt].first_alert + (uint32_t)alert);
249}
250
252 dt_mbx_t dt,
253 dt_alert_id_t alert) {
254 dt_mbx_alert_t count = kDtMbxAlertCount;
255 if (alert < mbx_desc[dt].first_alert || alert >= mbx_desc[dt].first_alert + (dt_alert_id_t)count) {
256 return count;
257 }
258 return (dt_mbx_alert_t)(alert - mbx_desc[dt].first_alert);
259}
260
261
262
264 dt_mbx_t dt,
265 dt_mbx_clock_t clk) {
266 // Return the first clock in case of invalid argument.
267 return TRY_GET_DT(dt, (dt_clock_t)0)->clock[clk];
268}
269
271 dt_mbx_t dt,
272 dt_mbx_reset_t rst) {
273 const dt_mbx_reset_t count = kDtMbxResetCount;
274 if (rst >= count) {
275 return kDtResetUnknown;
276 }
277 return TRY_GET_DT(dt, kDtResetUnknown)->reset[rst];
278}
279
280