Pavona Software APIs
dif_otp_ctrl.h
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
#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_
5
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_
6
7
/**
8
* @file
9
* @brief <a href="/hw/top_egret/ip_autogen/otp_ctrl/doc/">
10
* OTP Controller</a> Device Interface Functions
11
*/
12
13
#include <stdint.h>
14
15
#include "
sw/device/lib/base/macros.h
"
16
#include "
sw/device/lib/base/mmio.h
"
17
#include "
sw/device/lib/dif/dif_base.h
"
18
19
#include "sw/device/lib/dif/autogen/dif_otp_ctrl_autogen.h"
20
21
// Header Extern Guard (so header can be used from C and C++)
22
#ifdef __cplusplus
23
extern
"C"
{
24
#endif
// __cplusplus
25
26
/**
27
* Runtime configuration for OTP.
28
*
29
* This struct describes runtime information for one-time configuration of the
30
* hardware.
31
*/
32
typedef
struct
dif_otp_ctrl_config
{
33
/**
34
* The timeout for an integrity or consistency check to succeed, in cycles.
35
*
36
* 100'000 is recommended as a minimum safe value.
37
*/
38
uint32_t
check_timeout
;
39
/**
40
* A mask for the pseudo-random integrity check period.
41
*
42
* The value of this mask limits the period of the integrity check; when the
43
* pseudo-random period is computed, this mask is applied to limit it. For
44
* example, a value of 0x3'ffff would correspond to a maximum period of about
45
* 2.8s at 24MHz.
46
*
47
* A value of zero disables the check.
48
*/
49
uint32_t
integrity_period_mask
;
50
/**
51
* A mask for the pseudo-random consistency check period.
52
*
53
* The value of this mask limits the period of the consistency check; when the
54
* pseudo-random period is computed, this mask is applied to limit it. For
55
* example, a value of 0x3ff'ffff would correspond to a maximum period of
56
* about 716s at 24MHz.
57
*
58
* A value of zero disables the check.
59
*/
60
uint32_t
consistency_period_mask
;
61
}
dif_otp_ctrl_config_t
;
62
63
/**
64
* A hardware-level status code.
65
*/
66
typedef
enum
dif_otp_ctrl_status_code
{
67
// Note that these enum variants are intended as bit indices, so
68
// their values should not be randomized.
69
/**
70
* Indicates that at least one partition raised an error.
71
*/
72
kDifOtpCtrlStatusCodePartitionError
= 0,
73
/**
74
* Indicates an error occurred in the direct access interface.
75
*/
76
kDifOtpCtrlStatusCodeDaiError
,
77
/**
78
* Indicates an error occurred in the lifecycle interface.
79
*/
80
kDifOtpCtrlStatusCodeLciError
,
81
/**
82
* Indicates that an integrity or consistency check has timed out.
83
*
84
* This error is unrecoverable.
85
*/
86
kDifOtpCtrlStatusCodeTimeoutError
,
87
/**
88
* Indicates that the LFSR that generates pseudo-random integrity and
89
* consistency checks is in a bad state.
90
*
91
* This error is unrecoverable.
92
*/
93
kDifOtpCtrlStatusCodeLfsrError
,
94
/**
95
* Indicates that the scrambling hardware is in a bad state.
96
*
97
* This error is unrecoverable.
98
*/
99
kDifOtpCtrlStatusCodeScramblingError
,
100
/**
101
* Indicates that the key derivation hardware is in a bad state.
102
*
103
* This error is unrecoverable.
104
*/
105
kDifOtpCtrlStatusCodeKdfError
,
106
/**
107
* Indicates a bus integrity error.
108
*
109
* This error will raise an alert.
110
*/
111
kDifOtpCtrlStatusCodeBusIntegError
,
112
/**
113
* Indicates that the direct access interface is idle.
114
*/
115
kDifOtpCtrlStatusCodeDaiIdle
,
116
/**
117
* Indicates that an integrity or consistency check is currently pending.
118
*/
119
kDifOtpCtrlStatusCodeCheckPending
,
120
}
dif_otp_ctrl_status_code_t
;
121
122
/**
123
* A hardware-level error code, associated with a particular error defined in
124
* `dif_otp_ctrl_status_t`.
125
*/
126
typedef
enum
dif_otp_ctrl_error
{
127
/**
128
* Indicates no error.
129
*/
130
kDifOtpCtrlErrorOk
,
131
/**
132
* Indicates that an OTP macro command was invalid or did not
133
* complete successfully.
134
*
135
* This error indicates non-recoverable hardware malfunction.
136
*/
137
kDifOtpCtrlErrorMacroUnspecified
,
138
/**
139
* Indicates a recoverable error during a read operation.
140
*
141
* A followup read should work as expected.
142
*/
143
kDifOtpCtrlErrorMacroRecoverableRead
,
144
/**
145
* Indicates an unrecoverable error during a read operation.
146
*
147
* This error indicates non-recoverable hardware malfunction.
148
*/
149
kDifOtpCtrlErrorMacroUnrecoverableRead
,
150
/**
151
* Indicates that the blank write check failed during a write operation.
152
*/
153
kDifOtpCtrlErrorMacroBlankCheckFailed
,
154
/**
155
* Indicates a locked memory region was accessed.
156
*/
157
kDifOtpCtrlErrorLockedAccess
,
158
/**
159
* Indicates a parity, integrity or consistency check failed in the buffer
160
* registers.
161
*
162
* This error indicates non-recoverable hardware malfunction.
163
*/
164
kDifOtpCtrlErrorBackgroundCheckFailed
,
165
/**
166
* Indicates that the FSM of the controller is in a bad state or that the
167
* controller's FSM has been moved into its terminal state due to escalation
168
* via the alert subsystem.
169
*
170
* This error indicates that the device has been glitched by an attacker.
171
*/
172
kDifOtpCtrlErrorFsmBadState
,
173
}
dif_otp_ctrl_error_t
;
174
175
/**
176
* The overall status of the OTP controller.
177
*
178
* See `dif_otp_ctrl_get_status()`.
179
*/
180
typedef
struct
dif_otp_ctrl_status
{
181
/**
182
* Currently active statuses, given as a bit vector. To check whether a
183
* particular status code was returned, write
184
*
185
* bool has_code = (status.codes >> kMyStatusCode) & 1;
186
*
187
* Note that it is possible to quickly check that the controller is idle and
188
* error-free by writing
189
*
190
* bool is_ok = status.codes == (1 << kDifOtpStatusCodeDaiIdle);
191
*
192
* Note this mapes to the "status" hw register.
193
*/
194
uint32_t
codes
;
195
/**
196
* A list of root causes for each partition as well as for DAI and LCI.
197
* otp_partition_t can be used for indexing.
198
*/
199
dif_otp_ctrl_error_t
causes
[kOtpPartitionCount + 2];
200
}
dif_otp_ctrl_status_t
;
201
202
/**
203
* Configures OTP with runtime information.
204
*
205
* This function should need to be called at most once for the lifetime of
206
* `otp`.
207
*
208
* @param otp An OTP handle.
209
* @param config Runtime configuration parameters.
210
* @return The result of the operation.
211
*/
212
OT_WARN_UNUSED_RESULT
213
dif_result_t
dif_otp_ctrl_configure
(
const
dif_otp_ctrl_t
*otp,
214
dif_otp_ctrl_config_t
config);
215
216
/**
217
* Runs an integrity check on the OTP hardware.
218
*
219
* This function can be used to trigger an integrity check independent of the
220
* pseudo-random hardware-generated checks.
221
*
222
* @param otp An OTP handle.
223
* @return The result of the operation.
224
*/
225
OT_WARN_UNUSED_RESULT
226
dif_result_t
dif_otp_ctrl_check_integrity
(
const
dif_otp_ctrl_t
*otp);
227
228
/**
229
* Runs a consistency check on the OTP hardware.
230
*
231
* This function can be used to trigger a consistency check independent of the
232
* pseudo-random hardware-generated checks.
233
*
234
* @param otp An OTP handle.
235
* @return The result of the operation.
236
*/
237
OT_WARN_UNUSED_RESULT
238
dif_result_t
dif_otp_ctrl_check_consistency
(
const
dif_otp_ctrl_t
*otp);
239
240
/**
241
* Locks out access to the direct access interface registers.
242
*
243
* This function is idempotent: calling it while functionality is locked will
244
* have no effect and return `kDifOk`.
245
*
246
* @param otp An OTP handle.
247
* @return The result of the operation.
248
*/
249
OT_WARN_UNUSED_RESULT
250
dif_result_t
dif_otp_ctrl_dai_lock
(
const
dif_otp_ctrl_t
*otp);
251
252
/**
253
* Checks whether access to the direct access interface is locked.
254
*
255
* Note that besides locking the DAI out until the next reset using the
256
* dif_otp_ctrl_dai_lock function, the DAI is also temporarily locked by the
257
* HW itself when it is busy processing a DAI command. In such a case, the
258
* kDifOtpCtrlStatusCodeDaiIdle status bit will be set to 0 as well.
259
*
260
* @param otp An OTP handle.
261
* @param[out] is_locked Out-param for the locked state.
262
* @return The result of the operation.
263
*/
264
OT_WARN_UNUSED_RESULT
265
dif_result_t
dif_otp_ctrl_dai_is_locked
(
const
dif_otp_ctrl_t
*otp,
266
bool
*is_locked);
267
268
/**
269
* Locks out `dif_otp_ctrl_configure()` function.
270
*
271
* This function is idempotent: calling it while functionality is locked will
272
* have no effect and return `kDifOk`.
273
*
274
* @param otp An OTP handle.
275
* @return The result of the operation.
276
*/
277
OT_WARN_UNUSED_RESULT
278
dif_result_t
dif_otp_ctrl_lock_config
(
const
dif_otp_ctrl_t
*otp);
279
280
/**
281
* Checks whether `dif_otp_ctrl_configure()` function is locked-out.
282
*
283
* @param otp An OTP handle.
284
* @param[out] is_locked Out-param for the locked state.
285
* @return The result of the operation.
286
*/
287
OT_WARN_UNUSED_RESULT
288
dif_result_t
dif_otp_ctrl_config_is_locked
(
const
dif_otp_ctrl_t
*otp,
289
bool
*is_locked);
290
291
/**
292
* Locks out `dif_otp_ctrl_check_*()` functions.
293
*
294
* This function is idempotent: calling it while functionality is locked will
295
* have no effect and return `kDifOk`.
296
*
297
* @param otp An OTP handle.
298
* @return The result of the operation.
299
*/
300
OT_WARN_UNUSED_RESULT
301
dif_result_t
dif_otp_ctrl_lock_check_trigger
(
const
dif_otp_ctrl_t
*otp);
302
303
/**
304
* Checks whether the `dif_otp_ctrl_check_*()` functions are locked-out.
305
*
306
* @param otp An OTP handle.
307
* @param[out] is_locked Out-param for the locked state.
308
* @return The result of the operation.
309
*/
310
OT_WARN_UNUSED_RESULT
311
dif_result_t
dif_otp_ctrl_check_trigger_is_locked
(
const
dif_otp_ctrl_t
*otp,
312
bool
*is_locked);
313
314
/**
315
* Locks out reads to a SW partition.
316
*
317
* This function should only be called on SW partitions; doing otherwise will
318
* return an error.
319
*
320
* Note that this is distinct from the write-locking performed by calling
321
* `dif_otp_ctrl_dai_digest()`. In particular, the effects of this function will
322
* not persist past a system reset.
323
*
324
* This function is idempotent: calling it while functionality is locked will
325
* have no effect and return `kDifOk`.
326
*
327
* @param otp An OTP handle.
328
* @param partition The SW partition to lock.
329
* @return The result of the operation.
330
*/
331
OT_WARN_UNUSED_RESULT
332
dif_result_t
dif_otp_ctrl_lock_reading
(
const
dif_otp_ctrl_t
*otp,
333
otp_partition_t
partition);
334
335
/**
336
* Checks whether reads to a SW partition are locked out.
337
*
338
* This function should only be called on SW partitions; doing otherwise will
339
* return an error.
340
*
341
* @param otp An OTP handle.
342
* @param partition the SW partition to check for locking.
343
* @param[out] is_locked Out-param for the locked state.
344
* @return The result of the operation.
345
*/
346
OT_WARN_UNUSED_RESULT
347
dif_result_t
dif_otp_ctrl_reading_is_locked
(
const
dif_otp_ctrl_t
*otp,
348
otp_partition_t
partition,
349
bool
*is_locked);
350
351
/**
352
* Gets the current status of the OTP controller.
353
*
354
* @param otp An OTP handle.
355
* @param[out] status Out-param for the controller's status.
356
* @return The result of the operation.
357
*/
358
OT_WARN_UNUSED_RESULT
359
dif_result_t
dif_otp_ctrl_get_status
(
const
dif_otp_ctrl_t
*otp,
360
dif_otp_ctrl_status_t
*
status
);
361
362
/**
363
* Calculates a `relative_address` with respect to a `partition` start
364
* address.
365
*
366
* @param partition The partition to use to calculate the reference start
367
* address.
368
* @param abs_address Input address relative to the OTP memory start address.
369
* @param[out] relative_address The result relative address with respect to the
370
* `partition` start address.
371
* @return The result of the operation.
372
*/
373
OT_WARN_UNUSED_RESULT
374
dif_result_t
dif_otp_ctrl_relative_address
(
const
dif_otp_ctrl_t
*otp,
375
otp_partition_t
partition,
376
uint32_t abs_address,
377
uint32_t *relative_address);
378
379
/**
380
* Schedules a read on the Direct Access Interface.
381
*
382
* Reads are performed relative to a partition; `address` should be given
383
* relative to the start of `partition`. An error is returned for out-of-bounds
384
* access.
385
*
386
* Furthermore, `address` must be well-aligned: it must be four-byte aligned for
387
* normal partitions and eight-byte-aligned for secret partitions. An error is
388
* returned for unaligned access.
389
*
390
* @param otp An OTP handle.
391
* @param partition The partition to read from.
392
* @param address A partition-relative address to read from.
393
* @return The result of the operation.
394
*/
395
OT_WARN_UNUSED_RESULT
396
dif_result_t
dif_otp_ctrl_dai_read_start
(
const
dif_otp_ctrl_t
*otp,
397
otp_partition_t
partition,
398
uint32_t address);
399
400
/**
401
* Gets the result of a completed 32-bit read operation on the Direct Access
402
* Interface.
403
*
404
* Whether this function or its 64-bit variant should be called is dependent on
405
* the most recent partition read from.
406
*
407
* @param otp An OTP handle.
408
* @param[out] value Out-param for the read value.
409
* @return The result of the operation.
410
*/
411
OT_WARN_UNUSED_RESULT
412
dif_result_t
dif_otp_ctrl_dai_read32_end
(
const
dif_otp_ctrl_t
*otp,
413
uint32_t *value);
414
415
/**
416
* Gets the result of a completed 64-bit read operation on the Direct Access
417
* Interface.
418
*
419
* Whether this function or its 32-bit variant should be called is dependent on
420
* the most recent partition read from.
421
*
422
* @param otp An OTP handle.
423
* @param[out] value Out-param for the read value.
424
* @return The result of the operation.
425
*/
426
OT_WARN_UNUSED_RESULT
427
dif_result_t
dif_otp_ctrl_dai_read64_end
(
const
dif_otp_ctrl_t
*otp,
428
uint64_t *value);
429
430
/**
431
* Schedules a 32-bit write on the Direct Access Interface.
432
*
433
* Writes are performed relative to a partition; `address` should be given
434
* relative to the start of `partition`. An error is returned for out-of-bounds
435
* access.
436
*
437
* Furthermore, `address` must be four-byte-aligned, and `partition` must not be
438
* a secret partition. An error is returned if neither condition is met.
439
*
440
* Note that this function cannot be used to program the digest at the end of a
441
* `SW` partition; `dif_otp_ctrl_dai_digest()` must be used instead.
442
*
443
* @param otp An OTP handle.
444
* @param partition The partition to program.
445
* @param address A partition-relative address to program.
446
* @param value The value to program into the OTP.
447
* @return The result of the operation.
448
*/
449
OT_WARN_UNUSED_RESULT
450
dif_result_t
dif_otp_ctrl_dai_program32
(
const
dif_otp_ctrl_t
*otp,
451
otp_partition_t
partition,
452
uint32_t address, uint32_t value);
453
454
/**
455
* Schedules a 64-bit write on the Direct Access Interface.
456
*
457
* Writes are performed relative to a partition; `address` should be given
458
* relative to the start of `partition`. An error is returned for out-of-bounds
459
* access.
460
*
461
* Furthermore, `address` must be eight-byte-aligned, and `partition` must be
462
* a secret partition. An error is returned if neither condition is met.
463
*
464
* @param otp An OTP handle.
465
* @param partition The partition to program.
466
* @param address A partition-relative address to program.
467
* @param value The value to program into the OTP.
468
* @return The result of the operation.
469
*/
470
OT_WARN_UNUSED_RESULT
471
dif_result_t
dif_otp_ctrl_dai_program64
(
const
dif_otp_ctrl_t
*otp,
472
otp_partition_t
partition,
473
uint32_t address, uint64_t value);
474
475
/**
476
* Schedules a hardware digest operation on the Direct Access Interface.
477
*
478
* **This operation will also lock writes for the given partition.**
479
*
480
* If `partition` is a SW partition, `digest` must be non-zero; if it is a
481
* partition with a hardware-managed digest, `digest` *must* be zero (since the
482
* digest will be generated by the hardware). An error is returned if either
483
* precondition is not met.
484
*
485
* This function does not work with the lifecycle state partition, and will
486
* return an error in that case.
487
*
488
* @param otp An OTP handle.
489
* @param partition The partition to digest and lock.
490
* @param digest The digest to program (for SW partitions).
491
* @return The result of the operation.
492
*/
493
OT_WARN_UNUSED_RESULT
494
dif_result_t
dif_otp_ctrl_dai_digest
(
const
dif_otp_ctrl_t
*otp,
495
otp_partition_t
partition,
496
uint64_t digest);
497
498
/**
499
* Checks if the digest value for the given partition has been computed. Once a
500
* digest has been computed for a partition, the partition is write-locked
501
* (additionally, read-locked if the partition is secret).
502
*
503
* The lifecycle partition does not have a digest, and checking if this region
504
* has a computed digest will return an error.
505
*
506
* @param otp An OTP handle.
507
* @param partition The partition to check the digest of.
508
* @param[out] is_computed Indicates if the digest has been computed.
509
* @return The result of the operation.
510
*/
511
OT_WARN_UNUSED_RESULT
512
dif_result_t
dif_otp_ctrl_is_digest_computed
(
const
dif_otp_ctrl_t
*otp,
513
otp_partition_t
partition,
514
bool
*is_computed);
515
516
/**
517
* Gets the buffered digest value for the given partition.
518
*
519
* Note that this value is only updated when the device is reset; if the digest
520
* has not been computed yet, or has been computed but not since device reset,
521
* this function will return an error.
522
*
523
* The lifecycle partition does not have a digest and will result in an error
524
* being returned.
525
*
526
* @param otp An OTP handle.
527
* @param partition The partition to get a digest for.
528
* @param[out] digest Out-param for the digest.
529
* @return The result of the operation.
530
*/
531
OT_WARN_UNUSED_RESULT
532
dif_result_t
dif_otp_ctrl_get_digest
(
const
dif_otp_ctrl_t
*otp,
533
otp_partition_t
partition,
534
uint64_t *digest);
535
536
/**
537
* Performs a memory-mapped read of the given partition, if it supports them.
538
*
539
* In particular, this function will read `len` words, starting at `address`,
540
* relative to the start of `partition`.
541
*
542
* The same caveats for `dif_otp_ctrl_dai_read_start()` apply to `address`; in
543
* addition, `address + len` must also be in-range and must not overflow.
544
*
545
* This function will block until the read completes, unlike Direct Access
546
* Interface functions.
547
*
548
* @param otp An OTP handle.
549
* @param partition The partition to read from.
550
* @param address A partition-relative address to read from.
551
* @param[out] buf A buffer of words to write read values to.
552
* @param len The number of words to read.
553
* @return The result of the operation.
554
*/
555
OT_WARN_UNUSED_RESULT
556
dif_result_t
dif_otp_ctrl_read_blocking
(
const
dif_otp_ctrl_t
*otp,
557
otp_partition_t
partition,
558
uint32_t address, uint32_t *buf,
559
size_t
len);
560
561
#ifdef __cplusplus
562
}
// extern "C"
563
#endif
// __cplusplus
564
565
#endif
// OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_
sw
device
lib
dif
dif_otp_ctrl.h
Generated by
1.13.2