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_earlgrey/ip_autogen/otp_ctrl/doc/">
10 * OTP Controller</a> Device Interface Functions
11 */
12
13#include <stdint.h>
14
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
23extern "C" {
24#endif // __cplusplus
25
26/**
27 * A partition within OTP memory.
28 */
30 /**
31 * Vendor test partition.
32 *
33 * This is reserved for manufacturing smoke checks. The OTP wrapper
34 * control logic inside prim_otp is allowed to read/write to this
35 * region. ECC uncorrectable errors seen on the functional prim_otp
36 * interface will not lead to an alert for this partition.
37 * Instead, such errors will be reported as correctable ECC errors.
38 */
40 /**
41 * Software configuration partition.
42 *
43 * This is for device-specific calibration data, e.g, clock, LDO, RNG,
44 * and configuration settings set by the ROM.
45 */
47 /**
48 * Software configuration partition.
49 *
50 * This contains data that changes software behavior in the ROM, for
51 * example enabling defensive features in ROM or selecting failure
52 * modes if verification fails.
53 */
55#if defined(OPENTITAN_IS_EARLGREY)
56 /**
57 * This OTP partition is used to store four P-256 keys and four Sphincs+ keys.
58 *
59 * The partition requires 464
60 * bytes of software visible storage. The partition is
61 * locked at manufacturing time to protect against
62 * malicious write attempts.
63 */
64 kDifOtpCtrlPartitionRotCreatorAuthCodesign,
65 /**
66 * This OTP partition is used to capture the state of each key slot.
67 *
68 * Each key can be in one of the
69 * following states: BLANK, ENABLED, DISABLED. The
70 * encoded values are such that transitions between
71 * BLANK -> ENABLED -> DISABLED are possible without
72 * causing ECC errors (this is a mechanism similar to
73 * how we manage life cycle state transitions). The
74 * partition is left unlocked to allow STATE updates in
75 * the field. The ROM_EXT is required to lock access to
76 * the OTP Direct Access Interface to prevent DoS
77 * attacks from malicious code executing on Silicon
78 * Owner partitions. DAI write locking is available in
79 * EarlGrey.
80 */
81 kDifOtpCtrlPartitionRotCreatorAuthState,
82#elif defined(OPENTITAN_IS_DARJEELING)
83 /**
84 * SW managed asset ownership states partition.
85 *
86 * Multibit enable value for the tracking the asset ownership states.
87 * Note that the states can be written multiple times in a device lifetime.
88 * The values to be written are engineered in the same way as the LC_CTRL
89 * state encoding words so that the ECC encoding remains valid even after
90 * updating the values.
91 *
92 * The constants can be found in the lc_ctrl_state_pkg.sv package.
93 *
94 * The programming order has to adhere to:
95 *
96 * OWNERSHIP_ST_RAW (factory all-zero state) ->
97 * OWNERSHIP_ST_LOCKED0 ->
98 * OWNERSHIP_ST_RELEASED0 ->
99 * ...
100 * OWNERSHIP_ST_SCRAPPED
101 *
102 * Note that if there are less than 4 slots available the higher slot states
103 * become logically equivalent to OWNERSHIP_SCRAPPED (firmware has to handle
104 * this correctly).
105 */
106 kDifOtpCtrlPartitionOwnershipSlotState,
107 /**
108 * Software managed creator partition.
109 *
110 */
111 kDifOtpCtrlPartitionRotCreatorAuth,
112 /**
113 * Software managed owner slot 0 partition.
114 *
115 */
116 kDifOtpCtrlPartitionRotOwnerAuthSlot0,
117 /**
118 * Software managed owner slot 1 partition.
119 *
120 */
121 kDifOtpCtrlPartitionRotOwnerAuthSlot1,
122 /**
123 * Software managed platform integrator slot 0 partition.
124 *
125 */
126 kDifOtpCtrlPartitionPlatIntegAuthSlot0,
127 /**
128 * Software managed platform integrator slot 1 partition.
129 *
130 */
131 kDifOtpCtrlPartitionPlatIntegAuthSlot1,
132 /**
133 * Software managed platform owner slot 0 partition.
134 *
135 */
136 kDifOtpCtrlPartitionPlatOwnerAuthSlot0,
137 /**
138 * Software managed platform owner slot 1 partition.
139 *
140 */
141 kDifOtpCtrlPartitionPlatOwnerAuthSlot1,
142 /**
143 * Software managed platform owner slot 2 partition.
144 *
145 */
146 kDifOtpCtrlPartitionPlatOwnerAuthSlot2,
147 /**
148 * Software managed platform owner slot 3 partition.
149 *
150 */
151 kDifOtpCtrlPartitionPlatOwnerAuthSlot3,
152 /**
153 * Anti-replay protection Strike Counters partition.
154 *
155 */
156 kDifOtpCtrlPartitionExtNvm,
157 /**
158 * ROM Patch Code section.
159 *
160 * May contain multiple signed ROM2 patches.
161 */
162 kDifOtpCtrlPartitionRomPatch,
163#else
164#error "dif_otp_ctrl does not support this top"
165#endif
166 /**
167 * Hardware configuration 0 partition.
168 *
169 * This contains a device identifier and manufacturing state.
170 */
172 /**
173 * Hardware configuration 1 partition.
174 *
175 * This contains several hardware feature switches.
176 */
178 /**
179 * Secret partition 0.
180 *
181 * This contains TEST lifecycle unlock tokens.
182 */
184 /**
185 * Secret partition 1.
186 *
187 * This contains SRAM and flash scrambling keys.
188 */
190 /**
191 * Secret partition 2.
192 *
193 * This contains RMA unlock token, creator root key, and creator seed.
194 */
196#if defined(OPENTITAN_IS_DARJEELING)
197 /**
198 * Secret partition 3.
199 *
200 * This contains the owner seed.
201 */
202 kDifOtpCtrlPartitionSecret3,
203#elif defined(OPENTITAN_IS_EARLGREY)
204// Earlgrey only has 3 secret partitions.
205#else
206#error "dif_otp_ctrl does not support this top"
207#endif
208 /**
209 * Lifecycle partition.
210 *
211 * This contains lifecycle transition count and state. This partition
212 * cannot be locked since the life cycle state needs to advance to RMA
213 * in-field. Note that while this partition is not marked secret, it
214 * is not readable nor writeable via the DAI. Only the LC controller
215 * can access this partition, and even via the LC controller it is not
216 * possible to read the raw manufacturing life cycle state in encoded
217 * form, since that encoding is considered a netlist secret. The LC
218 * controller only exposes a decoded version of this state.
219 */
222
223/**
224 * Runtime configuration for OTP.
225 *
226 * This struct describes runtime information for one-time configuration of the
227 * hardware.
228 */
229typedef struct dif_otp_ctrl_config {
230 /**
231 * The timeout for an integrity or consistency check to succeed, in cycles.
232 *
233 * 100'000 is recommended as a minimum safe value.
234 */
236 /**
237 * A mask for the pseudo-random integrity check period.
238 *
239 * The value of this mask limits the period of the integrity check; when the
240 * pseudo-random period is computed, this mask is applied to limit it. For
241 * example, a value of 0x3'ffff would correspond to a maximum period of about
242 * 2.8s at 24MHz.
243 *
244 * A value of zero disables the check.
245 */
247 /**
248 * A mask for the pseudo-random consistency check period.
249 *
250 * The value of this mask limits the period of the consistency check; when the
251 * pseudo-random period is computed, this mask is applied to limit it. For
252 * example, a value of 0x3ff'ffff would correspond to a maximum period of
253 * about 716s at 24MHz.
254 *
255 * A value of zero disables the check.
256 */
259
260/**
261 * A hardware-level status code.
262 */
264 // NOTE: This enum's API *requires* that all "error"-like codes (that is,
265 // those which have associated cause registers) be a prefix of the enum
266 // values.
267 //
268 // Note furthermore that these enum variants are intended as bit indices, so
269 // their values should not be randomized.
270 /**
271 * Indicates an error occurred in the `VendorTest` partition.
272 */
274 /**
275 * Indicates an error occurred in the `CreatorSwCfg` partition.
276 */
278 /**
279 * Indicates an error occurred in the `OwnerSwCfg` partition.
280 */
282#if defined(OPENTITAN_IS_EARLGREY)
283 /**
284 * Indicates an error occurred in the `RotCreatorAuthCodesign` partition.
285 */
286 kDifOtpCtrlStatusCodeRotCreatorAuthCodesignError,
287 /**
288 * Indicates an error occurred in the `RotCreatorAuthState` partition.
289 */
290 kDifOtpCtrlStatusCodeRotCreatorAuthStateError,
291#elif defined(OPENTITAN_IS_DARJEELING)
292 /**
293 * Indicates an error occurred in the `OwnershipSlotState` partition.
294 */
295 kDifOtpCtrlStatusCodeOwnershipSlotStateError,
296 /**
297 * Indicates an error occurred in the `RotCreatorAuth` partition.
298 */
299 kDifOtpCtrlStatusCodeRotCreatorAuthError,
300 /**
301 * Indicates an error occurred in the `RotOwnerAuthSlot0` partition.
302 */
303 kDifOtpCtrlStatusCodeRotOwnerAuthSlot0Error,
304 /**
305 * Indicates an error occurred in the `RotOwnerAuthSlot1` partition.
306 */
307 kDifOtpCtrlStatusCodeRotOwnerAuthSlot1Error,
308 /**
309 * Indicates an error occurred in the `PlatIntegAuthSlot0` partition.
310 */
311 kDifOtpCtrlStatusCodePlatIntegAuthSlot0Error,
312 /**
313 * Indicates an error occurred in the `PlatIntegAuthSlot1` partition.
314 */
315 kDifOtpCtrlStatusCodePlatIntegAuthSlot1Error,
316 /**
317 * Indicates an error occurred in the `PlatOwnerAuthSlot0` partition.
318 */
319 kDifOtpCtrlStatusCodePlatOwnerAuthSlot0Error,
320 /**
321 * Indicates an error occurred in the `PlatOwnerAuthSlot1` partition.
322 */
323 kDifOtpCtrlStatusCodePlatOwnerAuthSlot1Error,
324 /**
325 * Indicates an error occurred in the `PlatOwnerAuthSlot2` partition.
326 */
327 kDifOtpCtrlStatusCodePlatOwnerAuthSlot2Error,
328 /**
329 * Indicates an error occurred in the `PlatOwnerAuthSlot3` partition.
330 */
331 kDifOtpCtrlStatusCodePlatOwnerAuthSlot3Error,
332 /**
333 * Indicates an error occurred in the `ExtNvm` partition.
334 */
335 kDifOtpCtrlStatusCodeExtNvmError,
336 /**
337 * Indicates an error occurred in the `RomPatch` partition.
338 */
339 kDifOtpCtrlStatusCodeRomPatchError,
340#else
341#error "dif_otp_ctrl does not support this top"
342#endif
343 /**
344 * Indicates an error occurred in the `HwCfg0` partition.
345 */
347 /**
348 * Indicates an error occurred in the `HwCfg1` partition.
349 */
351 /**
352 * Indicates an error occurred in the `Secret0` partition.
353 */
355 /**
356 * Indicates an error occurred in the `Secret1` partition.
357 */
359 /**
360 * Indicates an error occurred in the `Secret2` partition.
361 */
363#if defined(OPENTITAN_IS_DARJEELING)
364 /**
365 * Indicates an error occurred in the `Secret3` partition.
366 */
367 kDifOtpCtrlStatusCodeSecret3Error,
368#elif defined(OPENTITAN_IS_EARLGREY)
369// Earlgrey only has 3 secret partitions.
370#else
371#error "dif_otp_ctrl does not support this top"
372#endif
373 /**
374 * Indicates an error occurred in the `LifeCycle` partition.
375 */
377 /**
378 * Indicates an error occurred in the direct access interface.
379 */
381 /**
382 * Indicates an error occurred in the lifecycle interface.
383 */
385 /**
386 * This is not a status code; rather, it represents the last error code which
387 * has a corresponding "cause" register.
388 *
389 * See `dif_otp_ctrl_status_t` for information on how to use this.
390 */
392 /**
393 * Indicates that an integrity or consistency check has timed out.
394 *
395 * This error is unrecoverable.
396 */
398 /**
399 * Indicates that the LFSR that generates pseudo-random integrity and
400 * consistency checks is in a bad state.
401 *
402 * This error is unrecoverable.
403 */
405 /**
406 * Indicates that the scrambling hardware is in a bad state.
407 *
408 * This error is unrecoverable.
409 */
411 /**
412 * Indicates that the key derivation hardware is in a bad state.
413 *
414 * This error is unrecoverable.
415 */
417 /**
418 * Indicates a bus integrity error.
419 *
420 * This error will raise an alert.
421 */
423 /**
424 * Indicates that the direct access interface is idle.
425 */
427 /**
428 * Indicates that an integrity or consistency check is currently pending.
429 */
432
433/**
434 * A hardware-level error code, associated with a particular error defined in
435 * `dif_otp_ctrl_status_t`.
436 */
437typedef enum dif_otp_ctrl_error {
438 /**
439 * Indicates no error.
440 */
442 /**
443 * Indicates that an OTP macro command was invalid or did not
444 * complete successfully.
445 *
446 * This error indicates non-recoverable hardware malfunction.
447 */
449 /**
450 * Indicates a recoverable error during a read operation.
451 *
452 * A followup read should work as expected.
453 */
455 /**
456 * Indicates an unrecoverable error during a read operation.
457 *
458 * This error indicates non-recoverable hardware malfunction.
459 */
461 /**
462 * Indicates that the blank write check failed during a write operation.
463 */
465 /**
466 * Indicates a locked memory region was accessed.
467 */
469 /**
470 * Indicates a parity, integrity or consistency check failed in the buffer
471 * registers.
472 *
473 * This error indicates non-recoverable hardware malfunction.
474 */
476 /**
477 * Indicates that the FSM of the controller is in a bad state or that the
478 * controller's FSM has been moved into its terminal state due to escalation
479 * via the alert subsystem.
480 *
481 * This error indicates that the device has been glitched by an attacker.
482 */
485
486/**
487 * The overall status of the OTP controller.
488 *
489 * See `dif_otp_ctrl_get_status()`.
490 */
491typedef struct dif_otp_ctrl_status {
492 /**
493 * Currently active statuses, given as a bit vector. To check whether a
494 * particular status code was returned, write
495 *
496 * bool has_code = (status.codes >> kMyStatusCode) & 1;
497 *
498 * Note that it is possible to quickly check that the controller is idle and
499 * error-free by writing
500 *
501 * bool is_ok = status.codes == (1 << kDifOtpStatusCodeDaiIdle);
502 */
503 uint32_t codes;
504 /**
505 * A list of root causes for each error status code.
506 *
507 * If the error status code `error` is present in `codes`, and
508 * `error <= kDifOtpCtrlStatusCodeHasCauseLast`, then `causes[error]`
509 * will contain its root cause.
510 */
513
514/**
515 * Configures OTP with runtime information.
516 *
517 * This function should need to be called at most once for the lifetime of
518 * `otp`.
519 *
520 * @param otp An OTP handle.
521 * @param config Runtime configuration parameters.
522 * @return The result of the operation.
523 */
526 dif_otp_ctrl_config_t config);
527
528/**
529 * Runs an integrity check on the OTP hardware.
530 *
531 * This function can be used to trigger an integrity check independent of the
532 * pseudo-random hardware-generated checks.
533 *
534 * @param otp An OTP handle.
535 * @return The result of the operation.
536 */
539
540/**
541 * Runs a consistency check on the OTP hardware.
542 *
543 * This function can be used to trigger a consistency check independent of the
544 * pseudo-random hardware-generated checks.
545 *
546 * @param otp An OTP handle.
547 * @return The result of the operation.
548 */
551
552/**
553 * Locks out access to the direct access interface registers.
554 *
555 * This function is idempotent: calling it while functionality is locked will
556 * have no effect and return `kDifOk`.
557 *
558 * @param otp An OTP handle.
559 * @return The result of the operation.
560 */
563
564/**
565 * Checks whether access to the direct access interface is locked.
566 *
567 * Note that besides locking the DAI out until the next reset using the
568 * dif_otp_ctrl_dai_lock function, the DAI is also temporarily locked by the
569 * HW itself when it is busy processing a DAI command. In such a case, the
570 * kDifOtpCtrlStatusCodeDaiIdle status bit will be set to 0 as well.
571 *
572 * @param otp An OTP handle.
573 * @param[out] is_locked Out-param for the locked state.
574 * @return The result of the operation.
575 */
578 bool *is_locked);
579
580/**
581 * Locks out `dif_otp_ctrl_configure()` function.
582 *
583 * This function is idempotent: calling it while functionality is locked will
584 * have no effect and return `kDifOk`.
585 *
586 * @param otp An OTP handle.
587 * @return The result of the operation.
588 */
591
592/**
593 * Checks whether `dif_otp_ctrl_configure()` function is locked-out.
594 *
595 * @param otp An OTP handle.
596 * @param[out] is_locked Out-param for the locked state.
597 * @return The result of the operation.
598 */
601 bool *is_locked);
602
603/**
604 * Locks out `dif_otp_ctrl_check_*()` functions.
605 *
606 * This function is idempotent: calling it while functionality is locked will
607 * have no effect and return `kDifOk`.
608 *
609 * @param otp An OTP handle.
610 * @return The result of the operation.
611 */
614
615/**
616 * Checks whether the `dif_otp_ctrl_check_*()` functions are locked-out.
617 *
618 * @param otp An OTP handle.
619 * @param[out] is_locked Out-param for the locked state.
620 * @return The result of the operation.
621 */
624 bool *is_locked);
625
626/**
627 * Locks out reads to a SW partition.
628 *
629 * This function should only be called on SW partitions; doing otherwise will
630 * return an error.
631 *
632 * Note that this is distinct from the write-locking performed by calling
633 * `dif_otp_ctrl_dai_digest()`. In particular, the effects of this function will
634 * not persist past a system reset.
635 *
636 * This function is idempotent: calling it while functionality is locked will
637 * have no effect and return `kDifOk`.
638 *
639 * @param otp An OTP handle.
640 * @param partition The SW partition to lock.
641 * @return The result of the operation.
642 */
645 dif_otp_ctrl_partition_t partition);
646
647/**
648 * Checks whether reads to a SW partition are locked out.
649 *
650 * This function should only be called on SW partitions; doing otherwise will
651 * return an error.
652 *
653 * @param otp An OTP handle.
654 * @param partition the SW partition to check for locking.
655 * @param[out] is_locked Out-param for the locked state.
656 * @return The result of the operation.
657 */
660 dif_otp_ctrl_partition_t partition,
661 bool *is_locked);
662
663/**
664 * Gets the current status of the OTP controller.
665 *
666 * @param otp An OTP handle.
667 * @param[out] status Out-param for the controller's status.
668 * @return The result of the operation.
669 */
673
674/**
675 * Calculates a `relative_address` with respect to a `partition` start
676 * address.
677 *
678 * @param partition The partition to use to calculate the reference start
679 * address.
680 * @param abs_address Input address relative to the OTP memory start address.
681 * @param[out] relative_address The result relative address with respect to the
682 * `partition` start address.
683 * @return The result of the operation.
684 */
687 uint32_t abs_address,
688 uint32_t *relative_address);
689
690/**
691 * Schedules a read on the Direct Access Interface.
692 *
693 * Reads are performed relative to a partition; `address` should be given
694 * relative to the start of `partition`. An error is returned for out-of-bounds
695 * access.
696 *
697 * Furthermore, `address` must be well-aligned: it must be four-byte aligned for
698 * normal partitions and eight-byte-aligned for secret partitions. An error is
699 * returned for unaligned access.
700 *
701 * @param otp An OTP handle.
702 * @param partition The partition to read from.
703 * @param address A partition-relative address to read from.
704 * @return The result of the operation.
705 */
708 dif_otp_ctrl_partition_t partition,
709 uint32_t address);
710
711/**
712 * Gets the result of a completed 32-bit read operation on the Direct Access
713 * Interface.
714 *
715 * Whether this function or its 64-bit variant should be called is dependent on
716 * the most recent partition read from.
717 *
718 * @param otp An OTP handle.
719 * @param[out] value Out-param for the read value.
720 * @return The result of the operation.
721 */
724 uint32_t *value);
725
726/**
727 * Gets the result of a completed 64-bit read operation on the Direct Access
728 * Interface.
729 *
730 * Whether this function or its 32-bit variant should be called is dependent on
731 * the most recent partition read from.
732 *
733 * @param otp An OTP handle.
734 * @param[out] value Out-param for the read value.
735 * @return The result of the operation.
736 */
739 uint64_t *value);
740
741/**
742 * Schedules a 32-bit write on the Direct Access Interface.
743 *
744 * Writes are performed relative to a partition; `address` should be given
745 * relative to the start of `partition`. An error is returned for out-of-bounds
746 * access.
747 *
748 * Furthermore, `address` must be four-byte-aligned, and `partition` must not be
749 * a secret partition. An error is returned if neither condition is met.
750 *
751 * Note that this function cannot be used to program the digest at the end of a
752 * `SW` partition; `dif_otp_ctrl_dai_digest()` must be used instead.
753 *
754 * @param otp An OTP handle.
755 * @param partition The partition to program.
756 * @param address A partition-relative address to program.
757 * @param value The value to program into the OTP.
758 * @return The result of the operation.
759 */
762 dif_otp_ctrl_partition_t partition,
763 uint32_t address, uint32_t value);
764
765/**
766 * Schedules a 64-bit write on the Direct Access Interface.
767 *
768 * Writes are performed relative to a partition; `address` should be given
769 * relative to the start of `partition`. An error is returned for out-of-bounds
770 * access.
771 *
772 * Furthermore, `address` must be eight-byte-aligned, and `partition` must be
773 * a secret partition. An error is returned if neither condition is met.
774 *
775 * @param otp An OTP handle.
776 * @param partition The partition to program.
777 * @param address A partition-relative address to program.
778 * @param value The value to program into the OTP.
779 * @return The result of the operation.
780 */
783 dif_otp_ctrl_partition_t partition,
784 uint32_t address, uint64_t value);
785
786/**
787 * Schedules a hardware digest operation on the Direct Access Interface.
788 *
789 * **This operation will also lock writes for the given partition.**
790 *
791 * If `partition` is a SW partition, `digest` must be non-zero; if it is a
792 * partition with a hardware-managed digest, `digest` *must* be zero (since the
793 * digest will be generated by the hardware). An error is returned if either
794 * precondition is not met.
795 *
796 * This function does not work with the lifecycle state partition, and will
797 * return an error in that case.
798 *
799 * @param otp An OTP handle.
800 * @param partition The partition to digest and lock.
801 * @param digest The digest to program (for SW partitions).
802 * @return The result of the operation.
803 */
806 dif_otp_ctrl_partition_t partition,
807 uint64_t digest);
808
809/**
810 * Checks if the digest value for the given partition has been computed. Once a
811 * digest has been computed for a partition, the partition is write-locked
812 * (additionally, read-locked if the partition is secret).
813 *
814 * The lifecycle partition does not have a digest, and checking if this region
815 * has a computed digest will return an error.
816 *
817 * @param otp An OTP handle.
818 * @param partition The partition to check the digest of.
819 * @param[out] is_computed Indicates if the digest has been computed.
820 * @return The result of the operation.
821 */
824 dif_otp_ctrl_partition_t partition,
825 bool *is_computed);
826
827/**
828 * Gets the buffered digest value for the given partition.
829 *
830 * Note that this value is only updated when the device is reset; if the digest
831 * has not been computed yet, or has been computed but not since device reset,
832 * this function will return an error.
833 *
834 * The lifecycle partition does not have a digest and will result in an error
835 * being returned.
836 *
837 * @param otp An OTP handle.
838 * @param partition The partition to get a digest for.
839 * @param[out] digest Out-param for the digest.
840 * @return The result of the operation.
841 */
844 dif_otp_ctrl_partition_t partition,
845 uint64_t *digest);
846
847/**
848 * Performs a memory-mapped read of the given partition, if it supports them.
849 *
850 * In particular, this function will read `len` words, starting at `address`,
851 * relative to the start of `partition`.
852 *
853 * The same caveats for `dif_otp_ctrl_dai_read_start()` apply to `address`; in
854 * addition, `address + len` must also be in-range and must not overflow.
855 *
856 * This function will block until the read completes, unlike Direct Access
857 * Interface functions.
858 *
859 * @param otp An OTP handle.
860 * @param partition The partition to read from.
861 * @param address A partition-relative address to read from.
862 * @param[out] buf A buffer of words to write read values to.
863 * @param len The number of words to read.
864 * @return The result of the operation.
865 */
868 dif_otp_ctrl_partition_t partition,
869 uint32_t address, uint32_t *buf,
870 size_t len);
871
872#ifdef __cplusplus
873} // extern "C"
874#endif // __cplusplus
875
876#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_