blob: 2f17e1602f50204f66da300c883ab02a8636e55b [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_
/**
* @file
* @brief <a href="/hw/ip/otp_ctrl/doc/">OTP</a> Device Interface Functions
*/
#include <stdint.h>
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_warn_unused_result.h"
// Header Extern Guard (so header can be used from C and C++)
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/**
* A toggle state: enabled, or disabled.
*
* This enum may be used instead of a `bool` when describing an enabled/disabled
* state.
*/
typedef enum dif_otp_ctrl_toggle {
/*
* The "enabled" state.
*/
kDifOtpCtrlToggleEnabled,
/**
* The "disabled" state.
*/
kDifOtpCtrlToggleDisabled,
} dif_otp_ctrl_toggle_t;
/**
* A partition within OTP memory.
*/
typedef enum dif_otp_ctrl_partition {
/**
* The creator software configuration area.
*
* This partition contains device-specific calibration data.
*/
kDifOtpCtrlPartitionCreatorSwCfg,
/**
* The owner software configuration area.
*
* This partition contains data to e.g. enable ROM hardening features.
*/
kDifOtpCtrlPartitionOwnerSwCfg,
/**
* The hardware configuration area.
*/
kDifOtpCtrlPartitionHwCfg,
/**
* The device lifecycle area.
*/
kDifOtpCtrlPartitionLifeCycle,
/**
* Scrambled partition 0.
*
* This paritition contains TEST lifecycle state unlock tokens.
*/
kDifOtpCtrlPartitionSecret0,
/**
* Scrambled partition 1.
*
* This partition contains SRAM and flash scrambling keys.
*/
kDifOtpCtrlPartitionSecret1,
/**
* Scrambled partition 2.
*
* This partition contains the RMA unlock token and the CreatorRootKey.
*/
kDifOtpCtrlPartitionSecret2,
} dif_otp_ctrl_partition_t;
/**
* Hardware instantiation parameters for OTP.
*
* This struct describes information about the underlying hardware that is
* not determined until the hardware design is used as part of a top-level
* design.
*/
typedef struct dif_otp_ctrl_params {
/**
* The base address for the OTP hardware registers.
*/
mmio_region_t base_addr;
} dif_otp_ctrl_params_t;
/**
* Runtime configuration for OTP.
*
* This struct describes runtime information for one-time configuration of the
* hardware.
*/
typedef struct dif_otp_ctrl_config {
/**
* The timeout for an integrity or consistency check to succeed, in cycles.
*
* 100'000 is recommended as a minimum safe value.
*/
uint32_t check_timeout;
/**
* A mask for the pseudo-random integrity check period.
*
* The value of this mask limits the period of the integrity check; when the
* pseudo-random period is computed, this mask is applied to limit it. For
* example, a value of 0x3'ffff would correspond to a maximum period of about
* 2.8s at 24MHz.
*
* A value of zero disables the check.
*/
uint32_t integrity_period_mask;
/**
* A mask for the pseudo-random consistency check period.
*
* The value of this mask limits the period of the consistency check; when the
* pseudo-random period is computed, this mask is applied to limit it. For
* example, a value of 0x3ff'ffff would correspond to a maximum period of
* about 716s at 24MHz.
*
* A value of zero disables the check.
*/
uint32_t consistency_period_mask;
} dif_otp_ctrl_config_t;
/**
* A handle to OTP.
*
* This type should be treated as opaque by users.
*/
typedef struct dif_otp_ctrl {
dif_otp_ctrl_params_t params;
} dif_otp_ctrl_t;
/**
* The result of an OTP operation.
*/
typedef enum dif_otp_ctrl_result {
/**
* Indicates that the operation succeeded.
*/
kDifOtpCtrlOk = 0,
/**
* Indicates some unspecified failure.
*/
kDifOtpCtrlError = 1,
/**
* Indicates that some parameter passed into a function failed a
* precondition.
*
* When this value is returned, no hardware operations occurred.
*/
kDifOtpCtrlBadArg = 2,
} dif_otp_ctrl_result_t;
/**
* The result of a lockable operation.
*/
typedef enum dif_otp_ctrl_lockable_result {
/**
* Indicates that the operation succeeded.
*/
kDifOtpCtrlLockableOk = kDifOtpCtrlOk,
/**
* Indicates some unspecified failure.
*/
kDifOtpCtrlLockableError = kDifOtpCtrlError,
/**
* Indicates that some parameter passed into a function failed a
* precondition.
*
* When this value is returned, no hardware operations occurred.
*/
kDifOtpCtrlLockableBadArg = kDifOtpCtrlBadArg,
/**
* Indicates that this operation has been locked out, and can never
* succeed until hardware reset.
*/
kDifOtpCtrlLockableLocked,
} dif_otp_ctrl_lockable_result_t;
/**
* The result of a Direct Access Interface (DAI) operation.
*/
typedef enum dif_otp_ctrl_dai_result {
/**
* Indicates that the operation succeeded.
*/
kDifOtpCtrlDaiOk = kDifOtpCtrlOk,
/**
* Indicates some unspecified failure.
*/
kDifOtpCtrlDaiError = kDifOtpCtrlError,
/**
* Indicates that some parameter passed into a function failed a
* precondition.
*
* When this value is returned, no hardware operations occurred.
*/
kDifOtpCtrlDaiBadArg = kDifOtpCtrlBadArg,
/**
* Indicates that the DAI is busy and can't accept another incomming command.
*/
kDifOtpCtrlDaiBusy,
/**
* Indicates that the given partition does not support this operation.
*/
kDifOtpCtrlDaiBadPartition,
/**
* Indicates that the attempted DAI operation would go out of range of the
* requested partition.
*/
kDifOtpCtrlDaiOutOfRange,
/**
* Indicates that the given address was not correctly aligned.
*/
kDifOtpCtrlDaiUnaligned,
} dif_otp_ctrl_dai_result_t;
/**
* The result of a digest operation.
*/
typedef enum dif_otp_ctrl_digest_result {
/**
* Indicates that the operation succeeded.
*/
kDifOtpCtrlDigestOk = kDifOtpCtrlOk,
/**
* Indicates some unspecified failure.
*/
kDifOtpCtrlDigestError = kDifOtpCtrlError,
/**
* Indicates that some parameter passed into a function failed a
* precondition.
*
* When this value is returned, no hardware operations occurred.
*/
kDifOtpCtrlDigestBadArg = kDifOtpCtrlBadArg,
/**
* Indicates that a digest lookup failed because the digest had not been
* programmed yet.
*/
kDifOtpCtrlDigestMissing,
} dif_otp_ctrl_digest_result_t;
/**
* An OTP interrupt request type.
*/
typedef enum dif_otp_ctrl_irq {
/**
* Indicates that an asynchronous transaction completed.
*/
kDifOtpCtrlIrqDone,
/**
* Indicates that an error has occurred in the OTP controller.
*/
kDifOtpCtrlIrqError,
} dif_otp_ctrl_irq_t;
/**
* A snapshot of the enablement state of the interrupts for OTP.
*
* This is an opaque type, to be used with the `dif_otp_ctrl_irq_disable_all()`
* and
* `dif_otp_ctrl_irq_restore_all()` functions.
*/
typedef uint32_t dif_otp_ctrl_irq_snapshot_t;
/**
* A hardware-level status code.
*/
typedef enum dif_otp_ctrl_status_code {
// NOTE: This enum's API *requires* that all "error"-like codes (that is,
// those which have associated cause registers) be a prefix of the enum
// values.
//
// Note furthermore that these enum variants are intended as bit indices, so
// their values should not be randomized.
/**
* Indicates an error occurred in the `CreatorSwCfg` partition.
*/
kDifOtpCtrlStatusCodeCreatorSwCfgError = 0,
/**
* Indicates an error occurred in the `OwnerSwCfg` partition.
*/
kDifOtpCtrlStatusCodeOwnerSwCfgError,
/**
* Indicates an error occurred in the `HwCfg` partition.
*/
kDifOtpCtrlStatusCodeHwCfgError,
/**
* Indicates an error occurred in the `LifeCycle` partition.
*/
kDifOtpCtrlStatusCodeLifeCycleError,
/**
* Indicates an error occurred in the `Secret0` partition.
*/
kDifOtpCtrlStatusCodeSecret0Error,
/**
* Indicates an error occurred in the `Secret1` partition.
*/
kDifOtpCtrlStatusCodeSecret1Error,
/**
* Indicates an error occurred in the `Secret2` partition.
*/
kDifOtpCtrlStatusCodeSecret2Error,
/**
* Indicates an error occurred in the direct access interface.
*/
kDifOtpCtrlStatusCodeDaiError,
/**
* Indicates an error occurred in the lifecycle interface.
*/
kDifOtpCtrlStatusCodeLciError,
/**
* This is not a status code; rather, it represents the last error code which
* has a corresponding "cause" register.
*
* See `dif_otp_ctrl_status_t` for information on how to use this.
*/
kDifOtpCtrlStatusCodeHasCauseLast = kDifOtpCtrlStatusCodeLciError,
/**
* Indicates that an integrity or consistency check has timed out.
*
* This error is unrecoverable.
*/
kDifOtpCtrlStatusCodeTimeoutError,
/**
* Indicates that the LFSR that generates pseudo-random integrity and
* consistency checks is in a bad state.
*
* This error is unrecoverable.
*/
kDifOtpCtrlStatusCodeLfsrError,
/**
* Indicates that the scrambling hardware is in a bad state.
*
* This error is unrecoverable.
*/
kDifOtpCtrlStatusCodeScramblingError,
/**
* Indicates that the key derivation hardware is in a bad state.
*
* This error is unrecoverable.
*/
kDifOtpCtrlStatusCodeKdfError,
/**
* Indicates a bus integrity error.
*
* This error will raise an alert.
*/
kDifOtpCtrlStatusCodeBusIntegError,
/**
* Indicates that the direct access interface is idle.
*/
kDifOtpCtrlStatusCodeDaiIdle,
/**
* Indicates that an integrity or consistency check is currently pending.
*/
kDifOtpCtrlStatusCodeCheckPending,
} dif_otp_ctrl_status_code_t;
/**
* A hardware-level error code, associated with a particular error defined in
* `dif_otp_ctrl_status_t`.
*/
typedef enum dif_otp_ctrl_error {
/**
* Indicates no error.
*/
kDifOtpCtrlErrorOk,
/**
* Indicates that an OTP macro command was invalid or did not
* complete successfully.
*
* This error indicates non-recoverable hardware malfunction.
*/
kDifOtpCtrlErrorMacroUnspecified,
/**
* Indicates a recoverable error during a read operation.
*
* A followup read should work as expected.
*/
kDifOtpCtrlErrorMacroRecoverableRead,
/**
* Indicates an unrecoverable error during a read operation.
*
* This error indicates non-recoverable hardware malfunction.
*/
kDifOtpCtrlErrorMacroUnrecoverableRead,
/**
* Indicates that the blank write check failed during a write operation.
*/
kDifOtpCtrlErrorMacroBlankCheckFailed,
/**
* Indicates a locked memory region was accessed.
*/
kDifOtpCtrlErrorLockedAccess,
/**
* Indicates a parity, integrity or consistency check failed in the buffer
* registers.
*
* This error indicates non-recoverable hardware malfunction.
*/
kDifOtpCtrlErrorBackgroundCheckFailed,
/**
* Indicates that the FSM of the controller is in a bad state or that the
* controller's FSM has been moved into its terminal state due to escalation
* via the alert subsystem.
*
* This error indicates that the device has been glitched by an attacker.
*/
kDifOtpCtrlErrorFsmBadState,
} dif_otp_ctrl_error_t;
/**
* The overall status of the OTP controller.
*
* See `dif_otp_ctrl_get_status()`.
*/
typedef struct dif_otp_ctrl_status {
/**
* Currently active statuses, given as a bit vector. To check whether a
* particular status code was returned, write
*
* bool has_code = (status.codes >> kMyStatusCode) & 1;
*
* Note that it is possible to quickly check that the controller is idle and
* error-free by writing
*
* bool is_ok = status.codes == (1 << kDifOtpStatusCodeDaiIdle);
*/
uint32_t codes;
/**
* A list of root causes for each error status code.
*
* If the error status code `error` is present in `codes`, and
* `error <= kDifOtpCtrlStatusHasCauseLast`, then `causes[error]`
* will contain its root cause.
*/
dif_otp_ctrl_error_t causes[kDifOtpCtrlStatusCodeHasCauseLast + 1];
} dif_otp_ctrl_status_t;
/**
* Creates a new handle for OTP.
*
* This function does not actuate the hardware.
*
* @param params Hardware instantiation parameters.
* @param[out] otp Out param for the initialized handle.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_init(dif_otp_ctrl_params_t params,
dif_otp_ctrl_t *otp);
/**
* Configures OTP with runtime information.
*
* This function should need to be called at most once for the lifetime of
* `otp`.
*
* @param otp An OTP handle.
* @param config Runtime configuration parameters.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_lockable_result_t dif_otp_ctrl_configure(
const dif_otp_ctrl_t *otp, dif_otp_ctrl_config_t config);
/**
* Runs an integrity check on the OTP hardware.
*
* This function can be used to trigger an integrity check independent of the
* pseudo-random hardware-generated checks.
*
* @param otp An OTP handle.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_lockable_result_t dif_otp_ctrl_check_integrity(
const dif_otp_ctrl_t *otp);
/**
* Runs a consistency check on the OTP hardware.
*
* This function can be used to trigger a consistency check independent of the
* pseudo-random hardware-generated checks.
*
* @param otp An OTP handle.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_lockable_result_t dif_otp_ctrl_check_consistency(
const dif_otp_ctrl_t *otp);
/**
* Locks out `dif_otp_ctrl_configure()` and the
* `dif_otp_ctrl_check_*()` functions.
*
* This function is reentrant: calling it while functionality is locked will
* have no effect and return `kDifOtpCtrlOk`.
*
* @param otp An OTP handle.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_lock_config(const dif_otp_ctrl_t *otp);
/**
* Checks whether `dif_otp_ctrl_configure()` and the `dif_otp_ctrl_check_*()`
* functions are locked-out.
*
* @param otp An OTP handle.
* @param[out] is_locked Out-param for the locked state.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_config_is_locked(const dif_otp_ctrl_t *otp,
bool *is_locked);
/**
* Locks out reads to a SW partition.
*
* This function should only be called on SW partitions; doing otherwise will
* return an error.
*
* Note that this is distinct from the write-locking performed by calling
* `dif_otp_ctrl_dai_digest()`. In particular, the effects of this function will
* not persist past a system reset.
*
* This function is reentrant: calling it while functionality is locked will
* have no effect and return `kDifOtpCtrlOk`.
*
* @param otp An OTP handle.
* @param partition The SW partition to lock.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_lock_reading(
const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition);
/**
* Checks whether reads to a SW partition are locked out.
*
* This function should only be called on SW partitions; doing otherwise will
* return an error.
*
* @param otp An OTP handle.
* @param partition the SW partition to check for locking.
* @param[out] is_locked Out-param for the locked state.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_reading_is_locked(
const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
bool *is_locked);
/**
* Returns whether a particular interrupt is currently pending.
*
* @param otp An OTP handle.
* @param irq An interrupt type.
* @param[out] is_pending Out-param for whether the interrupt is pending.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_irq_is_pending(const dif_otp_ctrl_t *otp,
dif_otp_ctrl_irq_t irq,
bool *is_pending);
/**
* Acknowledges a particular interrupt, indicating to the hardware that it has
* been successfully serviced.
*
* @param otp An OTP handle.
* @param irq An interrupt type.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_irq_acknowledge(const dif_otp_ctrl_t *otp,
dif_otp_ctrl_irq_t irq);
/**
* Checks whether a particular interrupt is currently enabled or disabled.
*
* @param otp An OTP handle.
* @param irq An interrupt type.
* @param[out] state Out-param toggle state of the interrupt.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_irq_get_enabled(
const dif_otp_ctrl_t *otp, dif_otp_ctrl_irq_t irq,
dif_otp_ctrl_toggle_t *state);
/**
* Sets whether a particular interrupt is currently enabled or disabled.
*
* @param otp An OTP handle.
* @param irq An interrupt type.
* @param state The new toggle state for the interrupt.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_irq_set_enabled(const dif_otp_ctrl_t *otp,
dif_otp_ctrl_irq_t irq,
dif_otp_ctrl_toggle_t state);
/**
* Forces a particular interrupt, causing it to be serviced as if hardware had
* asserted it.
*
* @param otp An OTP handle.
* @param irq An interrupt type.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_irq_force(const dif_otp_ctrl_t *otp,
dif_otp_ctrl_irq_t irq);
/**
* Disables all interrupts, optionally snapshotting all toggle state for later
* restoration.
*
* @param otp An OTP handle.
* @param[out] snapshot Out-param for the snapshot; may be `NULL`.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_irq_disable_all(
const dif_otp_ctrl_t *otp, dif_otp_ctrl_irq_snapshot_t *snapshot);
/**
* Restores interrupts from the given snapshot.
*
* This function can be used with `dif_otp_ctrl_irq_disable_all()` to temporary
* interrupt save-and-restore.
*
* @param otp An OTP handle.
* @param snapshot A snapshot to restore from.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_irq_restore_all(
const dif_otp_ctrl_t *otp, const dif_otp_ctrl_irq_snapshot_t *snapshot);
/**
* Gets the current status of the OTP controller.
*
* @param otp An OTP handle.
* @param[out] status Out-param for the controller's status.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_get_status(const dif_otp_ctrl_t *otp,
dif_otp_ctrl_status_t *status);
/**
* Schedules a read on the Direct Access Interface.
*
* Reads are performed relative to a partition; `address` should be given
* relative to the start of `partition`. An error is returned for out-of-bounds
* access.
*
* Furthermore, `address` must be well-aligned: it must be four-byte aligned for
* normal paritions and eight-byte-aligned for secret partitions. An error is
* returned for unaligned access.
*
* @param otp An OTP handle.
* @param partition The partition to read from.
* @param address A partition-relative address to read from.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_read_start(
const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
uint32_t address);
/**
* Gets the result of a completed 32-bit read operation on the Direct Access
* Interface.
*
* Whether this function or its 64-bit variant should be called is dependent on
* the most recent partition read from.
*
* @param otp An OTP handle.
* @param[out] value Out-param for the read value.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_read32_end(const dif_otp_ctrl_t *otp,
uint32_t *value);
/**
* Gets the result of a completed 64-bit read operation on the Direct Access
* Interface.
*
* Whether this function or its 32-bit variant should be called is dependent on
* the most recent partition read from.
*
* @param otp An OTP handle.
* @param[out] value Out-param for the read value.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_read64_end(const dif_otp_ctrl_t *otp,
uint64_t *value);
/**
* Schedules a 32-bit write on the Direct Access Interface.
*
* Writes are performed relative to a partition; `address` should be given
* relative to the start of `partition`. An error is returned for out-of-bounds
* access.
*
* Furthermore, `address` must be four-byte-aligned, and `partition` must not be
* a secret partition. An error is returned if neither condition is met.
*
* Note that this function cannot be used to program the digest at the end of a
* `SW` partition; `dif_otp_ctrl_dai_digest()` must be used instead.
*
* @param otp An OTP handle.
* @param partition The partition to program.
* @param address A partition-relative address to program.
* @param value The value to program into the OTP.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_program32(
const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
uint32_t address, uint32_t value);
/**
* Schedules a 64-bit write on the Direct Access Interface.
*
* Writes are performed relative to a partition; `address` should be given
* relative to the start of `partition`. An error is returned for out-of-bounds
* access.
*
* Furthermore, `address` must be eight-byte-aligned, and `partition` must be
* a secret partition. An error is returned if neither condition is met.
*
* @param otp An OTP handle.
* @param partition The partition to program.
* @param address A partition-relative address to program.
* @param value The value to program into the OTP.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_program64(
const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
uint32_t address, uint64_t value);
/**
* Schedules a hardware digest operation on the Direct Access Interface.
*
* **This operation will also lock writes for the given partition.**
*
* If `partition` is a SW partition, `digest` must be non-zero; if it is a
* partition with a hardware-managed digest, `digest` *must* be zero (since the
* digest will be generated by the hardware). An error is returned if either
* precondition is not met.
*
* This function does not work with the lifecycle state partition, and will
* return an error in that case.
*
* @param otp An OTP handle.
* @param partition The partition to digest and lock.
* @param digest The digest to program (for SW partitions).
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_dai_result_t dif_otp_ctrl_dai_digest(
const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
uint64_t digest);
/**
* Gets the buffered digest value for the given partition.
*
* Note that this value is only updated when the device is reset; if the digest
* has not been computed yet, or has been computed but not since device reset,
* this function will return an error.
*
* The lifecycle partition does not have a digest and will result in an error
* being returned.
*
* @param otp An OTP handle.
* @param partition The partition to get a digest for.
* @param[out] digest Out-param for the digest.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_digest_result_t dif_otp_ctrl_get_digest(
const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
uint64_t *digest);
/**
* Performs a memory-mapped read of the given partition, if it supports them.
*
* In particular, this function will read `len` words, starting at `address`,
* relative to the start of `partition`.
*
* The same caveats for `dif_otp_ctrl_dai_read_start()` apply to `address`; in
* addition, `address + len` must also be in-range and must not overflow.
*
* This function will block until the read completes, unlike Direct Access
* Interface functions.
*
* @param otp An OTP handle.
* @param partition The partition to read from.
* @param address A partition-relative address to read from.
* @param[out] buf A buffer of words to write read values to.
* @param len The number of words to read.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_dai_result_t dif_otp_ctrl_read_blocking(
const dif_otp_ctrl_t *otp, dif_otp_ctrl_partition_t partition,
uint32_t address, uint32_t *buf, size_t len);
/**
* Performs a memory-mapped read of the TEST region.
*
* In particular, this function will read `len` words, starting at `address`.
*
* The same caveats for `dif_otp_ctrl_dai_read_start()` apply to `address`; in
* addition, `address + len` must also be in-range and must not overflow.
*
* @param otp An OTP handle.
* @param address The address to read from.
* @param[out] buf A buffer of words to write read values to.
* @param len The number of words to read.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_read_test(const dif_otp_ctrl_t *otp,
uint32_t address, uint32_t *buf,
size_t len);
/**
* Performs a memory-mapped write of the TEST region.
*
* In particular, this function will write `len` words, starting at `address`.
*
* The same caveats for `dif_otp_ctrl_dai_program32()` apply to `address`; in
* addition, `address + len` must also be in-range and must not overflow.
*
* @param otp An OTP handle.
* @param address An absolute address to write to.
* @param buf A buffer of words to write write values from.
* @param len The number of words to write.
* @return The result of the operation.
*/
DIF_WARN_UNUSED_RESULT
dif_otp_ctrl_result_t dif_otp_ctrl_write_test(const dif_otp_ctrl_t *otp,
uint32_t address,
const uint32_t *buf, size_t len);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_OTP_CTRL_H_