Software APIs
dif_otp_ctrl.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors.
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/ip/otp_ctrl/doc/">OTP</a> Device Interface Functions
11  */
12 
13 #include <stdint.h>
14 
17 
18 // Header Extern Guard (so header can be used from C and C++)
19 #ifdef __cplusplus
20 extern "C" {
21 #endif // __cplusplus
22 
23 /**
24  * A toggle state: enabled, or disabled.
25  *
26  * This enum may be used instead of a `bool` when describing an enabled/disabled
27  * state.
28  */
29 typedef enum dif_otp_ctrl_toggle {
30  /*
31  * The "enabled" state.
32  */
33  kDifOtpCtrlToggleEnabled,
34  /**
35  * The "disabled" state.
36  */
39 
40 /**
41  * A partition within OTP memory.
42  */
43 typedef enum dif_otp_ctrl_partition {
44  /**
45  * The creator software configuration area.
46  *
47  * This partition contains device-specific calibration data.
48  */
50  /**
51  * The owner software configuration area.
52  *
53  * This partition contains data to e.g. enable ROM hardening features.
54  */
56  /**
57  * The hardware configuration area.
58  */
60  /**
61  * The device lifecycle area.
62  */
64  /**
65  * Scrambled partition 0.
66  *
67  * This paritition contains TEST lifecycle state unlock tokens.
68  */
70  /**
71  * Scrambled partition 1.
72  *
73  * This partition contains SRAM and flash scrambling keys.
74  */
76  /**
77  * Scrambled partition 2.
78  *
79  * This partition contains the RMA unlock token and the CreatorRootKey.
80  */
83 
84 /**
85  * Hardware instantiation parameters for OTP.
86  *
87  * This struct describes information about the underlying hardware that is
88  * not determined until the hardware design is used as part of a top-level
89  * design.
90  */
91 typedef struct dif_otp_ctrl_params {
92  /**
93  * The base address for the OTP hardware registers.
94  */
97 
98 /**
99  * Runtime configuration for OTP.
100  *
101  * This struct describes runtime information for one-time configuration of the
102  * hardware.
103  */
104 typedef struct dif_otp_ctrl_config {
105  /**
106  * The timeout for an integrity or consistency check to succeed, in cycles.
107  *
108  * 100'000 is recommended as a minimum safe value.
109  */
110  uint32_t check_timeout;
111  /**
112  * A mask for the pseudo-random integrity check period.
113  *
114  * The value of this mask limits the period of the integrity check; when the
115  * pseudo-random period is computed, this mask is applied to limit it. For
116  * example, a value of 0x3'ffff would correspond to a maximum period of about
117  * 2.8s at 24MHz.
118  *
119  * A value of zero disables the check.
120  */
122  /**
123  * A mask for the pseudo-random consistency check period.
124  *
125  * The value of this mask limits the period of the consistency check; when the
126  * pseudo-random period is computed, this mask is applied to limit it. For
127  * example, a value of 0x3ff'ffff would correspond to a maximum period of
128  * about 716s at 24MHz.
129  *
130  * A value of zero disables the check.
131  */
134 
135 /**
136  * A handle to OTP.
137  *
138  * This type should be treated as opaque by users.
139  */
140 typedef struct dif_otp_ctrl {
141  dif_otp_ctrl_params_t params;
143 
144 /**
145  * The result of an OTP operation.
146  */
147 typedef enum dif_otp_ctrl_result {
148  /**
149  * Indicates that the operation succeeded.
150  */
152  /**
153  * Indicates some unspecified failure.
154  */
156  /**
157  * Indicates that some parameter passed into a function failed a
158  * precondition.
159  *
160  * When this value is returned, no hardware operations occurred.
161  */
164 
165 /**
166  * The result of a lockable operation.
167  */
169  /**
170  * Indicates that the operation succeeded.
171  */
173  /**
174  * Indicates some unspecified failure.
175  */
177  /**
178  * Indicates that some parameter passed into a function failed a
179  * precondition.
180  *
181  * When this value is returned, no hardware operations occurred.
182  */
184  /**
185  * Indicates that this operation has been locked out, and can never
186  * succeed until hardware reset.
187  */
190 
191 /**
192  * The result of a Direct Access Interface (DAI) operation.
193  */
195  /**
196  * Indicates that the operation succeeded.
197  */
199  /**
200  * Indicates some unspecified failure.
201  */
203  /**
204  * Indicates that some parameter passed into a function failed a
205  * precondition.
206  *
207  * When this value is returned, no hardware operations occurred.
208  */
210  /**
211  * Indicates that the DAI is busy and can't accept another incomming command.
212  */
214  /**
215  * Indicates that the given partition does not support this operation.
216  */
218  /**
219  * Indicates that the attempted DAI operation would go out of range of the
220  * requested partition.
221  */
223  /**
224  * Indicates that the given address was not correctly aligned.
225  */
228 
229 /**
230  * The result of a digest operation.
231  */
233  /**
234  * Indicates that the operation succeeded.
235  */
237  /**
238  * Indicates some unspecified failure.
239  */
241  /**
242  * Indicates that some parameter passed into a function failed a
243  * precondition.
244  *
245  * When this value is returned, no hardware operations occurred.
246  */
248  /**
249  * Indicates that a digest lookup failed because the digest had not been
250  * programmed yet.
251  */
254 
255 /**
256  * An OTP interrupt request type.
257  */
258 typedef enum dif_otp_ctrl_irq {
259  /**
260  * Indicates that an asynchronous transaction completed.
261  */
263  /**
264  * Indicates that an error has occurred in the OTP controller.
265  */
268 
269 /**
270  * A snapshot of the enablement state of the interrupts for OTP.
271  *
272  * This is an opaque type, to be used with the `dif_otp_ctrl_irq_disable_all()`
273  * and
274  * `dif_otp_ctrl_irq_restore_all()` functions.
275  */
277 
278 /**
279  * A hardware-level status code.
280  */
282  // NOTE: This enum's API *requires* that all "error"-like codes (that is,
283  // those which have associated cause registers) be a prefix of the enum
284  // values.
285  //
286  // Note furthermore that these enum variants are intended as bit indices, so
287  // their values should not be randomized.
288  /**
289  * Indicates an error occurred in the `CreatorSwCfg` partition.
290  */
292  /**
293  * Indicates an error occurred in the `OwnerSwCfg` partition.
294  */
296  /**
297  * Indicates an error occurred in the `HwCfg` partition.
298  */
300  /**
301  * Indicates an error occurred in the `LifeCycle` partition.
302  */
304  /**
305  * Indicates an error occurred in the `Secret0` partition.
306  */
308  /**
309  * Indicates an error occurred in the `Secret1` partition.
310  */
312  /**
313  * Indicates an error occurred in the `Secret2` partition.
314  */
316 
317  /**
318  * Indicates an error occurred in the direct access interface.
319  */
321  /**
322  * Indicates an error occurred in the lifecycle interface.
323  */
325 
326  /**
327  * This is not a status code; rather, it represents the last error code which
328  * has a corresponding "cause" register.
329  *
330  * See `dif_otp_ctrl_status_t` for information on how to use this.
331  */
333 
334  /**
335  * Indicates that an integrity or consistency check has timed out.
336  *
337  * This error is unrecoverable.
338  */
340  /**
341  * Indicates that the LFSR that generates pseudo-random integrity and
342  * consistency checks is in a bad state.
343  *
344  * This error is unrecoverable.
345  */
347  /**
348  * Indicates that the scrambling hardware is in a bad state.
349  *
350  * This error is unrecoverable.
351  */
353  /**
354  * Indicates that the key derivation hardware is in a bad state.
355  *
356  * This error is unrecoverable.
357  */
359 
360  /**
361  * Indicates that the direct access interface is idle.
362  */
364  /**
365  * Indicates that an integrity or consistency check is currently pending.
366  */
369 
370 /**
371  * A hardware-level error code, associated with a particular error defined in
372  * `dif_otp_ctrl_status_t`.
373  */
374 typedef enum dif_otp_ctrl_error {
375  /**
376  * Indicates no error.
377  */
379  /**
380  * Indicates that an OTP macro command was invalid or did not
381  * complete successfully.
382  *
383  * This error indicates non-recoverable hardware malfunction.
384  */
386  /**
387  * Indicates a recoverable error during a read operation.
388  *
389  * A followup read should work as expected.
390  */
392  /**
393  * Indicates an unrecoverable error during a read operation.
394  *
395  * This error indicates non-recoverable hardware malfunction.
396  */
398  /**
399  * Indicates that the blank write check failed during a write operation.
400  */
402  /**
403  * Indicates a locked memory region was accessed.
404  */
406  /**
407  * Indicates a parity, integrity or consistency check failed in the buffer
408  * registers.
409  *
410  * This error indicates non-recoverable hardware malfunction.
411  */
413  /**
414  * Indicates that the FSM of the controller is in a bad state or that the
415  * controller's FSM has been moved into its terminal state due to escalation
416  * via the alert subsystem.
417  *
418  * This error indicates that the device has been glitched by an attacker.
419  */
422 
423 /**
424  * The overall status of the OTP controller.
425  *
426  * See `dif_otp_ctrl_get_status()`.
427  */
428 typedef struct dif_otp_ctrl_status {
429  /**
430  * Currently active statuses, given as a bit vector. To check whether a
431  * particular status code was returned, write
432  *
433  * bool has_code = (status.codes >> kMyStatusCode) & 1;
434  *
435  * Note that it is possible to quickly check that the controller is idle and
436  * error-free by writing
437  *
438  * bool is_ok = status.codes == (1 << kDifOtpStatusCodeDaiIdle);
439  */
440  uint32_t codes;
441  /**
442  * A list of root causes for each error status code.
443  *
444  * If the error status code `error` is present in `codes`, and
445  * `error <= kDifOtpCtrlStatusHasCauseLast`, then `causes[error]`
446  * will contain its root cause.
447  */
448  dif_otp_ctrl_error_t causes[kDifOtpCtrlStatusCodeHasCauseLast + 1];
450 
451 /**
452  * Creates a new handle for OTP.
453  *
454  * This function does not actuate the hardware.
455  *
456  * @param params Hardware instantiation parameters.
457  * @param[out] otp Out param for the initialized handle.
458  * @return The result of the operation.
459  */
462  dif_otp_ctrl_t *otp);
463 
464 /**
465  * Configures OTP with runtime information.
466  *
467  * This function should need to be called at most once for the lifetime of
468  * `otp`.
469  *
470  * @param otp An OTP handle.
471  * @param config Runtime configuration parameters.
472  * @return The result of the operation.
473  */
475 dif_otp_ctrl_lockable_result_t dif_otp_ctrl_configure(
476  const dif_otp_ctrl_t *otp, dif_otp_ctrl_config_t config);
477 
478 /**
479  * Runs an integrity check on the OTP hardware.
480  *
481  * This function can be used to trigger an integrity check independent of the
482  * pseudo-random hardware-generated checks.
483  *
484  * @param otp An OTP handle.
485  * @return The result of the operation.
486  */
488 dif_otp_ctrl_lockable_result_t dif_otp_ctrl_check_integrity(
489  const dif_otp_ctrl_t *otp);
490 
491 /**
492  * Runs a consistency check on the OTP hardware.
493  *
494  * This function can be used to trigger a consistency check independent of the
495  * pseudo-random hardware-generated checks.
496  *
497  * @param otp An OTP handle.
498  * @return The result of the operation.
499  */
501 dif_otp_ctrl_lockable_result_t dif_otp_ctrl_check_consistency(
502  const dif_otp_ctrl_t *otp);
503 
504 /**
505  * Locks out `dif_otp_ctrl_configure()` and the
506  * `dif_otp_ctrl_check_*()` functions.
507  *
508  * This function is reentrant: calling it while functionality is locked will
509  * have no effect and return `kDifOtpCtrlOk`.
510  *
511  * @param otp An OTP handle.
512  * @return The result of the operation.
513  */
516 
517 /**
518  * Checks whether `dif_otp_ctrl_configure()` and the `dif_otp_ctrl_check_*()`
519  * functions are locked-out.
520  *
521  * @param otp An OTP handle.
522  * @param[out] is_locked Out-param for the locked state.
523  * @return The result of the operation.
524  */
527  bool *is_locked);
528 
529 /**
530  * Locks out reads to a SW partition.
531  *
532  * This function should only be called on SW partitions; doing otherwise will
533  * return an error.
534  *
535  * Note that this is distinct from the write-locking performed by calling
536  * `dif_otp_ctrl_dai_digest()`. In particular, the effects of this function will
537  * not persist past a system reset.
538  *
539  * This function is reentrant: calling it while functionality is locked will
540  * have no effect and return `kDifOtpCtrlOk`.
541  *
542  * @param otp An OTP handle.
543  * @param partition The SW partition to lock.
544  * @return The result of the operation.
545  */
548  const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition);
549 
550 /**
551  * Checks whether reads to a SW partition are locked out.
552  *
553  * This function should only be called on SW partitions; doing otherwise will
554  * return an error.
555  *
556  * @param otp An OTP handle.
557  * @param partition the SW partition to check for locking.
558  * @param[out] is_locked Out-param for the locked state.
559  * @return The result of the operation.
560  */
563  const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
564  bool *is_locked);
565 
566 /**
567  * Returns whether a particular interrupt is currently pending.
568  *
569  * @param otp An OTP handle.
570  * @param irq An interrupt type.
571  * @param[out] is_pending Out-param for whether the interrupt is pending.
572  * @return The result of the operation.
573  */
576  dif_otp_ctrl_irq_t irq,
577  bool *is_pending);
578 
579 /**
580  * Acknowledges a particular interrupt, indicating to the hardware that it has
581  * been successfully serviced.
582  *
583  * @param otp An OTP handle.
584  * @param irq An interrupt type.
585  * @return The result of the operation.
586  */
589  dif_otp_ctrl_irq_t irq);
590 
591 /**
592  * Checks whether a particular interrupt is currently enabled or disabled.
593  *
594  * @param otp An OTP handle.
595  * @param irq An interrupt type.
596  * @param[out] state Out-param toggle state of the interrupt.
597  * @return The result of the operation.
598  */
601  const dif_otp_ctrl_t *otp, dif_otp_ctrl_irq_t irq,
602  dif_otp_ctrl_toggle_t *state);
603 
604 /**
605  * Sets whether a particular interrupt is currently enabled or disabled.
606  *
607  * @param otp An OTP handle.
608  * @param irq An interrupt type.
609  * @param state The new toggle state for the interrupt.
610  * @return The result of the operation.
611  */
614  dif_otp_ctrl_irq_t irq,
615  dif_otp_ctrl_toggle_t state);
616 
617 /**
618  * Forces a particular interrupt, causing it to be serviced as if hardware had
619  * asserted it.
620  *
621  * @param otp An OTP handle.
622  * @param irq An interrupt type.
623  * @return The result of the operation.
624  */
627  dif_otp_ctrl_irq_t irq);
628 
629 /**
630  * Disables all interrupts, optionally snapshotting all toggle state for later
631  * restoration.
632  *
633  * @param otp An OTP handle.
634  * @param[out] snapshot Out-param for the snapshot; may be `NULL`.
635  * @return The result of the operation.
636  */
639  const dif_otp_ctrl_t *otp, dif_otp_ctrl_irq_snapshot_t *snapshot);
640 
641 /**
642  * Restores interrupts from the given snapshot.
643  *
644  * This function can be used with `dif_otp_ctrl_irq_disable_all()` to temporary
645  * interrupt save-and-restore.
646  *
647  * @param otp An OTP handle.
648  * @param snapshot A snapshot to restore from.
649  * @return The result of the operation.
650  */
653  const dif_otp_ctrl_t *otp, const dif_otp_ctrl_irq_snapshot_t *snapshot);
654 
655 /**
656  * Gets the current status of the OTP controller.
657  *
658  * @param otp An OTP handle.
659  * @param[out] status Out-param for the controller's status.
660  * @return The result of the operation.
661  */
664  dif_otp_ctrl_status_t *status);
665 
666 /**
667  * Schedules a read on the Direct Access Interface.
668  *
669  * Reads are performed relative to a partition; `address` should be given
670  * relative to the start of `partition`. An error is returned for out-of-bounds
671  * access.
672  *
673  * Furthermore, `address` must be well-aligned: it must be four-byte aligned for
674  * normal paritions and eight-byte-aligned for secret partitions. An error is
675  * returned for unaligned access.
676  *
677  * @param otp An OTP handle.
678  * @param partition The partition to read from.
679  * @param address A partition-relative address to read from.
680  * @return The result of the operation.
681  */
683 dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_read_start(
684  const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
685  uint32_t address);
686 
687 /**
688  * Gets the result of a completed 32-bit read operation on the Direct Access
689  * Interface.
690  *
691  * Whether this function or its 64-bit variant should be called is dependent on
692  * the most recent partition read from.
693  *
694  * @param otp An OTP handle.
695  * @param[out] value Out-param for the read value.
696  * @return The result of the operation.
697  */
699 dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_read32_end(const dif_otp_ctrl_t *otp,
700  uint32_t *value);
701 
702 /**
703  * Gets the result of a completed 64-bit read operation on the Direct Access
704  * Interface.
705  *
706  * Whether this function or its 32-bit variant should be called is dependent on
707  * the most recent partition read from.
708  *
709  * @param otp An OTP handle.
710  * @param[out] value Out-param for the read value.
711  * @return The result of the operation.
712  */
714 dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_read64_end(const dif_otp_ctrl_t *otp,
715  uint64_t *value);
716 
717 /**
718  * Schedules a 32-bit write on the Direct Access Interface.
719  *
720  * Writes are performed relative to a partition; `address` should be given
721  * relative to the start of `partition`. An error is returned for out-of-bounds
722  * access.
723  *
724  * Furthermore, `address` must be four-byte-aligned, and `partition` must not be
725  * a secret partition. An error is returned if neither condition is met.
726  *
727  * Note that this function cannot be used to program the digest at the end of a
728  * `SW` partition; `dif_otp_ctrl_dai_digest()` must be used instead.
729  *
730  * @param otp An OTP handle.
731  * @param partition The partition to program.
732  * @param address A partition-relative address to program.
733  * @param value The value to program into the OTP.
734  * @return The result of the operation.
735  */
737 dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_program32(
738  const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
739  uint32_t address, uint32_t value);
740 
741 /**
742  * Schedules a 64-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 eight-byte-aligned, and `partition` must be
749  * a secret partition. An error is returned if neither condition is met.
750  *
751  * @param otp An OTP handle.
752  * @param partition The partition to program.
753  * @param address A partition-relative address to program.
754  * @param value The value to program into the OTP.
755  * @return The result of the operation.
756  */
758 dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_program64(
759  const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
760  uint32_t address, uint64_t value);
761 
762 /**
763  * Schedules a hardware digest operation on the Direct Access Interface.
764  *
765  * **This operation will also lock writes for the given partition.**
766  *
767  * If `partition` is a SW partition, `digest` must be non-zero; if it is a
768  * partition with a hardware-managed digest, `digest` *must* be zero (since the
769  * digest will be generated by the hardware). An error is returned if either
770  * precondition is not met.
771  *
772  * This function does not work with the lifecycle state partition, and will
773  * return an error in that case.
774  *
775  * @param otp An OTP handle.
776  * @param partition The partition to digest and lock.
777  * @param digest The digest to program (for SW partitions).
778  * @return The result of the operation.
779  */
781 dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_digest(
782  const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
783  uint64_t digest);
784 
785 /**
786  * Gets the buffered digest value for the given partition.
787  *
788  * Note that this value is only updated when the device is reset; if the digest
789  * has not been computed yet, or has been computed but not since device reset,
790  * this function will return an error.
791  *
792  * The lifecycle partition does not have a digest and will result in an error
793  * being returned.
794  *
795  * @param otp An OTP handle.
796  * @param partition The partition to get a digest for.
797  * @param[out] digest Out-param for the digest.
798  * @return The result of the operation.
799  */
801 dif_otp_ctrl_digest_result_t dif_otp_ctrl_get_digest(
802  const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
803  uint64_t *digest);
804 
805 /**
806  * Performs a memory-mapped read of the given partition, if it supports them.
807  *
808  * In particular, this function will read `len` words, starting at `address`,
809  * relative to the start of `partition`.
810  *
811  * The same caveats for `dif_otp_ctrl_dai_read_start()` apply to `address`; in
812  * addition, `address + len` must also be in-range and must not overflow.
813  *
814  * This function will block until the read completes, unlike Direct Access
815  * Interface functions.
816  *
817  * @param otp An OTP handle.
818  * @param partition The partition to read from.
819  * @param address A partition-relative address to read from.
820  * @param[out] buf A buffer of words to write read values to.
821  * @param len The number of words to read.
822  * @return The result of the operation.
823  */
825 dif_otp_ctrl_dai_result_t dif_otp_ctrl_read_blocking(
826  const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
827  uint32_t address, uint32_t *buf, size_t len);
828 
829 /**
830  * Performs a memory-mapped read of the TEST region.
831  *
832  * In particular, this function will read `len` words, starting at `address`.
833  *
834  * The same caveats for `dif_otp_ctrl_dai_read_start()` apply to `address`; in
835  * addition, `address + len` must also be in-range and must not overflow.
836  *
837  * @param otp An OTP handle.
838  * @param address The address to read from.
839  * @param[out] buf A buffer of words to write read values to.
840  * @param len The number of words to read.
841  * @return The result of the operation.
842  */
845  uint32_t address, uint32_t *buf,
846  size_t len);
847 
848 /**
849  * Performs a memory-mapped write of the TEST region.
850  *
851  * In particular, this function will write `len` words, starting at `address`.
852  *
853  * The same caveats for `dif_otp_ctrl_dai_program32()` apply to `address`; in
854  * addition, `address + len` must also be in-range and must not overflow.
855  *
856  * @param otp An OTP handle.
857  * @param address An absolute address to write to.
858  * @param buf A buffer of words to write write values from.
859  * @param len The number of words to write.
860  * @return The result of the operation.
861  */
864  uint32_t address,
865  const uint32_t *buf, size_t len);
866 
867 #ifdef __cplusplus
868 } // extern "C"
869 #endif // __cplusplus
870 
871 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_