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