Pavona Software APIs
otp_ctrl.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 otp_ctrl and top egret.
10 */
11
12#include "hw/top/dt/otp_ctrl.h"
13
14
15#include "hw/top/otp_ctrl_regs.h"
16
17
18/**
19 * Description of instances.
20 */
21typedef struct dt_desc_otp_ctrl {
22 dt_instance_id_t inst_id; /**< Instance ID */
23 uint32_t reg_addr[kDtOtpCtrlRegBlockCount]; /**< Base address of each register block */
24 /**
25 * PLIC ID of the first IRQ of this instance
26 *
27 * This can be `kDtPlicIrqIdNone` if the block is not connected to the PLIC.
28 */
30 /**
31 * Alert ID of the first Alert of this instance.
32 *
33 * This value is undefined if the block is not connected to the Alert Handler.
34 */
36 dt_clock_t clock[kDtOtpCtrlClockCount]; /**< Clock signal connected to each clock port */
37 dt_reset_t reset[kDtOtpCtrlResetCount]; /**< Reset signal connected to each reset port */
38 struct {
39 dt_otp_partition_info_t info[11]; /**< List of OTP partitions */
40 } partitions; /**< Extension */
42
43
44
45
46static const dt_desc_otp_ctrl_t otp_ctrl_desc[kDtOtpCtrlCount] = {
47 [kDtOtpCtrl] = {
48 .inst_id = kDtInstanceIdOtpCtrl,
49 .reg_addr = {
50 [kDtOtpCtrlRegBlockCore] = 0x40130000,
51 },
54 .clock = {
57 },
58 .reset = {
61 },
62 .partitions = {
63 .info = {
64 [kOtpPartitionVendorTest] = {
65 .start_addr = OTP_CTRL_PARAM_VENDOR_TEST_OFFSET,
66 .size = OTP_CTRL_PARAM_VENDOR_TEST_SIZE - OTP_CTRL_PARAM_VENDOR_TEST_DIGEST_SIZE,
67 .sw_readable = 1,
68 .sw_digest = 1,
69 .hw_digest = 0,
70 .digest_reg_offset = OTP_CTRL_VENDOR_TEST_DIGEST_0_REG_OFFSET,
71 .read_lockable = 1,
72 .lock_reg_offset = OTP_CTRL_VENDOR_TEST_READ_LOCK_REG_OFFSET,
73 .read_lock_bit = OTP_CTRL_VENDOR_TEST_READ_LOCK_VENDOR_TEST_READ_LOCK_BIT,
74 .zeroizable = 0,
75 .is_lifecycle = 0,
76 .align_mask = 0x3,
77 },
78 [kOtpPartitionCreatorSwCfg] = {
79 .start_addr = OTP_CTRL_PARAM_CREATOR_SW_CFG_OFFSET,
80 .size = OTP_CTRL_PARAM_CREATOR_SW_CFG_SIZE - OTP_CTRL_PARAM_CREATOR_SW_CFG_DIGEST_SIZE,
81 .sw_readable = 1,
82 .sw_digest = 1,
83 .hw_digest = 0,
84 .digest_reg_offset = OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_REG_OFFSET,
85 .read_lockable = 1,
86 .lock_reg_offset = OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_REG_OFFSET,
87 .read_lock_bit = OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_CREATOR_SW_CFG_READ_LOCK_BIT,
88 .zeroizable = 0,
89 .is_lifecycle = 0,
90 .align_mask = 0x3,
91 },
92 [kOtpPartitionOwnerSwCfg] = {
93 .start_addr = OTP_CTRL_PARAM_OWNER_SW_CFG_OFFSET,
94 .size = OTP_CTRL_PARAM_OWNER_SW_CFG_SIZE - OTP_CTRL_PARAM_OWNER_SW_CFG_DIGEST_SIZE,
95 .sw_readable = 1,
96 .sw_digest = 1,
97 .hw_digest = 0,
98 .digest_reg_offset = OTP_CTRL_OWNER_SW_CFG_DIGEST_0_REG_OFFSET,
99 .read_lockable = 1,
100 .lock_reg_offset = OTP_CTRL_OWNER_SW_CFG_READ_LOCK_REG_OFFSET,
101 .read_lock_bit = OTP_CTRL_OWNER_SW_CFG_READ_LOCK_OWNER_SW_CFG_READ_LOCK_BIT,
102 .zeroizable = 0,
103 .is_lifecycle = 0,
104 .align_mask = 0x3,
105 },
106 [kOtpPartitionRotCreatorAuthCodesign] = {
107 .start_addr = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_OFFSET,
108 .size = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_SIZE - OTP_CTRL_PARAM_ROT_CREATOR_AUTH_CODESIGN_DIGEST_SIZE,
109 .sw_readable = 1,
110 .sw_digest = 1,
111 .hw_digest = 0,
112 .digest_reg_offset = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_DIGEST_0_REG_OFFSET,
113 .read_lockable = 1,
114 .lock_reg_offset = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_REG_OFFSET,
115 .read_lock_bit = OTP_CTRL_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_ROT_CREATOR_AUTH_CODESIGN_READ_LOCK_BIT,
116 .zeroizable = 0,
117 .is_lifecycle = 0,
118 .align_mask = 0x3,
119 },
120 [kOtpPartitionRotCreatorAuthState] = {
121 .start_addr = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_OFFSET,
122 .size = OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_SIZE - OTP_CTRL_PARAM_ROT_CREATOR_AUTH_STATE_DIGEST_SIZE,
123 .sw_readable = 1,
124 .sw_digest = 1,
125 .hw_digest = 0,
126 .digest_reg_offset = OTP_CTRL_ROT_CREATOR_AUTH_STATE_DIGEST_0_REG_OFFSET,
127 .read_lockable = 1,
128 .lock_reg_offset = OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_REG_OFFSET,
129 .read_lock_bit = OTP_CTRL_ROT_CREATOR_AUTH_STATE_READ_LOCK_ROT_CREATOR_AUTH_STATE_READ_LOCK_BIT,
130 .zeroizable = 0,
131 .is_lifecycle = 0,
132 .align_mask = 0x3,
133 },
134 [kOtpPartitionHwCfg0] = {
135 .start_addr = OTP_CTRL_PARAM_HW_CFG0_OFFSET,
136 .size = OTP_CTRL_PARAM_HW_CFG0_SIZE - OTP_CTRL_PARAM_HW_CFG0_DIGEST_SIZE,
137 .sw_readable = 1,
138 .sw_digest = 0,
139 .hw_digest = 1,
140 .digest_reg_offset = OTP_CTRL_HW_CFG0_DIGEST_0_REG_OFFSET,
141 .read_lockable = 0,
142 .lock_reg_offset = 0xdeadbeef,
143 .read_lock_bit = 0xdeadbeef,
144 .zeroizable = 0,
145 .is_lifecycle = 0,
146 .align_mask = 0x3,
147 },
148 [kOtpPartitionHwCfg1] = {
149 .start_addr = OTP_CTRL_PARAM_HW_CFG1_OFFSET,
150 .size = OTP_CTRL_PARAM_HW_CFG1_SIZE - OTP_CTRL_PARAM_HW_CFG1_DIGEST_SIZE,
151 .sw_readable = 1,
152 .sw_digest = 0,
153 .hw_digest = 1,
154 .digest_reg_offset = OTP_CTRL_HW_CFG1_DIGEST_0_REG_OFFSET,
155 .read_lockable = 0,
156 .lock_reg_offset = 0xdeadbeef,
157 .read_lock_bit = 0xdeadbeef,
158 .zeroizable = 0,
159 .is_lifecycle = 0,
160 .align_mask = 0x3,
161 },
162 [kOtpPartitionSecret0] = {
163 .start_addr = OTP_CTRL_PARAM_SECRET0_OFFSET,
164 .size = OTP_CTRL_PARAM_SECRET0_SIZE - OTP_CTRL_PARAM_SECRET0_DIGEST_SIZE,
165 .sw_readable = 0,
166 .sw_digest = 0,
167 .hw_digest = 1,
168 .digest_reg_offset = OTP_CTRL_SECRET0_DIGEST_0_REG_OFFSET,
169 .read_lockable = 0,
170 .lock_reg_offset = 0xdeadbeef,
171 .read_lock_bit = 0xdeadbeef,
172 .zeroizable = 0,
173 .is_lifecycle = 0,
174 .align_mask = 0x7,
175 },
176 [kOtpPartitionSecret1] = {
177 .start_addr = OTP_CTRL_PARAM_SECRET1_OFFSET,
178 .size = OTP_CTRL_PARAM_SECRET1_SIZE - OTP_CTRL_PARAM_SECRET1_DIGEST_SIZE,
179 .sw_readable = 0,
180 .sw_digest = 0,
181 .hw_digest = 1,
182 .digest_reg_offset = OTP_CTRL_SECRET1_DIGEST_0_REG_OFFSET,
183 .read_lockable = 0,
184 .lock_reg_offset = 0xdeadbeef,
185 .read_lock_bit = 0xdeadbeef,
186 .zeroizable = 0,
187 .is_lifecycle = 0,
188 .align_mask = 0x7,
189 },
190 [kOtpPartitionSecret2] = {
191 .start_addr = OTP_CTRL_PARAM_SECRET2_OFFSET,
192 .size = OTP_CTRL_PARAM_SECRET2_SIZE - OTP_CTRL_PARAM_SECRET2_DIGEST_SIZE,
193 .sw_readable = 0,
194 .sw_digest = 0,
195 .hw_digest = 1,
196 .digest_reg_offset = OTP_CTRL_SECRET2_DIGEST_0_REG_OFFSET,
197 .read_lockable = 0,
198 .lock_reg_offset = 0xdeadbeef,
199 .read_lock_bit = 0xdeadbeef,
200 .zeroizable = 0,
201 .is_lifecycle = 0,
202 .align_mask = 0x7,
203 },
204 [kOtpPartitionLifeCycle] = {
205 .start_addr = OTP_CTRL_PARAM_LIFE_CYCLE_OFFSET,
206 .size = OTP_CTRL_PARAM_LIFE_CYCLE_SIZE,
207 .sw_readable = 0,
208 .sw_digest = 0,
209 .hw_digest = 0,
210 .digest_reg_offset = 0xdeadbeef,
211 .read_lockable = 0,
212 .lock_reg_offset = 0xdeadbeef,
213 .read_lock_bit = 0xdeadbeef,
214 .zeroizable = 0,
215 .is_lifecycle = 1,
216 .align_mask = 0x3,
217 },
218 },
219 },
220 },
221};
222
223/**
224 * Return a pointer to the `dt_otp_ctrl_desc_t` structure of the requested
225 * `dt` if it's a valid index. Otherwise, this macro will `return` (i.e. exit
226 * the function) with the provided default value.
227 */
228#define TRY_GET_DT(dt, default) ({ if ((dt) < (dt_otp_ctrl_t)0 || (int)(dt) >= kDtOtpCtrlCount) return (default); &otp_ctrl_desc[dt]; })
229
231 if (inst_id >= kDtInstanceIdOtpCtrl && inst_id <= kDtInstanceIdOtpCtrl) {
232 return (dt_otp_ctrl_t)(inst_id - kDtInstanceIdOtpCtrl);
233 }
234 return (dt_otp_ctrl_t)0;
235}
236
241
243 dt_otp_ctrl_t dt,
244 dt_otp_ctrl_reg_block_t reg_block) {
245 // Return a recognizable address in case of wrong argument.
246 return TRY_GET_DT(dt, 0xdeadbeef)->reg_addr[reg_block];
247}
248
250 dt_otp_ctrl_t dt,
251 dt_otp_ctrl_irq_t irq) {
252 dt_plic_irq_id_t first_irq = TRY_GET_DT(dt, kDtPlicIrqIdNone)->first_irq;
253 if (first_irq == kDtPlicIrqIdNone) {
254 return kDtPlicIrqIdNone;
255 }
256 return (dt_plic_irq_id_t)((uint32_t)first_irq + (uint32_t)irq);
257}
258
260 dt_otp_ctrl_t dt,
261 dt_plic_irq_id_t irq) {
263 dt_plic_irq_id_t first_irq = TRY_GET_DT(dt, count)->first_irq;
264 if (first_irq == kDtPlicIrqIdNone) {
265 return count;
266 }
267 if (irq < first_irq || irq >= first_irq + (dt_plic_irq_id_t)count) {
268 return count;
269 }
270 return (dt_otp_ctrl_irq_t)(irq - first_irq);
271}
272
273
275 dt_otp_ctrl_t dt,
276 dt_otp_ctrl_alert_t alert) {
277 return (dt_alert_id_t)((uint32_t)otp_ctrl_desc[dt].first_alert + (uint32_t)alert);
278}
279
281 dt_otp_ctrl_t dt,
282 dt_alert_id_t alert) {
284 if (alert < otp_ctrl_desc[dt].first_alert || alert >= otp_ctrl_desc[dt].first_alert + (dt_alert_id_t)count) {
285 return count;
286 }
287 return (dt_otp_ctrl_alert_t)(alert - otp_ctrl_desc[dt].first_alert);
288}
289
290
291
293 dt_otp_ctrl_t dt,
295 // Return the first clock in case of invalid argument.
296 return TRY_GET_DT(dt, (dt_clock_t)0)->clock[clk];
297}
298
300 dt_otp_ctrl_t dt,
303 if (rst >= count) {
304 return kDtResetUnknown;
305 }
306 return TRY_GET_DT(dt, kDtResetUnknown)->reset[rst];
307}
308
309
310
311
314 dt_otp_partition_info_t invalid_part = {
315 .start_addr = 0xdeadbeef,
316 .size = 0x0,
317 .sw_readable = 0,
318 .sw_digest = 0,
319 .hw_digest = 0,
320 .digest_reg_offset = 0xdeadbeef,
321 .read_lockable = 0,
322 .lock_reg_offset = 0xdeadbeef,
323 .read_lock_bit = 0xdeadbeef,
324 .zeroizable = 0,
325 .is_lifecycle = 0,
326 .align_mask = 0x0,
327 };
328 return TRY_GET_DT(dt, invalid_part)->partitions.info[partition];
329}
330
331
332