Programmer’s Guide

During provisioning and manufacturing, SW interacts with the OTP controller mostly through the Direct Access Interface (DAI), which is described below. Afterwards during production, SW is expected to perform only read accesses via the exposed CSRs and CSR windows, since all write access to the partitions has been locked down.

The following sections provide some general guidance, followed by an explanation of the DAI and a detailed OTP memory map. Typical programming sequences are explained at the end of the Programmer’s guide.

General Guidance

Initialization

The OTP controller initializes automatically upon power-up and is fully operational by the time the processor boots. The only initialization steps that SW should perform are:

  1. Check that the OTP controller has successfully initialized by reading STATUS. I.e., make sure that none of the ERROR bits are set, and that the DAI is idle (STATUS.DAI_IDLE).
  2. Set up the periodic background checks:

If needed, one-off integrity and consistency checks can be triggered via CHECK_TRIGGER. If this functionality is not needed, it is recommended to lock down the trigger register via CHECK_TRIGGER_REGWEN.

Later on during the boot process, SW may also choose to block read access to the SW managed partitions via the associated partition lock registers, e.g. CREATOR_SW_CFG_READ_LOCK or OWNER_SW_CFG_READ_LOCK.

Reset Considerations

It is important to note that values in OTP can be corrupted if a reset occurs during a programming operation. This should be of minor concern for SW, however, since all partitions except for the LIFE_CYCLE partition are being provisioned in secure and controlled environments, and not in the field. The LIFE_CYCLE partition is the only partition that is modified in the field - but that partition is entirely owned by the life cycle controller and not by SW.

Programming Already Programmed Regions

OTP words cannot be programmed twice, and doing so may damage the memory array. Hence the OTP controller performs a blank check and returns an error if a write operation is issued to an already programmed location.

Potential Side-Effects on Flash via Life Cycle

It should be noted that the locked status of the partition holding the creator root key (i.e., the value of the SECRET2_DIGEST_0) determines the ID_STATUS of the device, which in turn determines SW accessibility of creator seed material in flash and OTP. That means that creator-seed-related collateral needs to be provisioned to Flash before the OTP digest lockdown mechanism is triggered, since otherwise accessibility to the corresponding flash region is lost. See the life cycle controller documentation for more details.

Direct Access Interface

OTP has to be programmed via the Direct Access Interface, which is comprised of the following CSRs:

CSR NameDescription
DIRECT_ACCESS_WDATA_0Low 32bit word to be written.
DIRECT_ACCESS_WDATA_1High 32bit word to be written.
DIRECT_ACCESS_RDATA_0Low 32bit word that has been read.
DIRECT_ACCESS_RDATA_1High 32bit word that has been read.
DIRECT_ACCESS_ADDRESSbyte address for the access.
DIRECT_ACCESS_CMDCommand register to trigger a read or a write access.
DIRECT_ACCESS_REGWENWrite protection register for DAI.

See further below for a detailed Memory Map of the address space accessible via the DAI.

Readout Sequence

A typical readout sequence looks as follows:

  1. Check whether the DAI is idle by reading the STATUS register.
  2. Write the byte address for the access to DIRECT_ACCESS_ADDRESS. Note that the address is aligned with the granule, meaning that either 2 or 3 LSBs of the address are ignored, depending on whether the access granule is 32 or 64bit.
  3. Trigger a read command by writing 0x1 to DIRECT_ACCESS_CMD.
  4. Poll the STATUS until the DAI state goes back to idle. Alternatively, the otp_operation_done interrupt can be enabled up to notify the processor once an access has completed.
  5. If the status register flags a DAI error, additional handling is required (see Section on Error handling).
  6. If the region accessed has a 32bit access granule, the 32bit chunk of read data can be read from DIRECT_ACCESS_RDATA_0. If the region accessed has a 64bit access granule, the 64bit chunk of read data can be read from the DIRECT_ACCESS_RDATA_0 and DIRECT_ACCESS_RDATA_1 registers.
  7. Go back to 1. and repeat until all data has been read.

The hardware will set DIRECT_ACCESS_REGWEN to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers.

Programming Sequence

A typical programming sequence looks as follows:

  1. Check whether the DAI is idle by reading the STATUS register.
  2. If the region to be accessed has a 32bit access granule, place a 32bit chunk of data into DIRECT_ACCESS_WDATA_0. If the region to be accessed has a 64bit access granule, both the DIRECT_ACCESS_WDATA_0 and DIRECT_ACCESS_WDATA_1 registers have to be used.
  3. Write the byte address for the access to DIRECT_ACCESS_ADDRESS. Note that the address is aligned with the granule, meaning that either 2 or 3 LSBs of the address are ignored, depending on whether the access granule is 32 or 64bit.
  4. Trigger a write command by writing 0x2 to DIRECT_ACCESS_CMD.
  5. Poll the STATUS until the DAI state goes back to idle. Alternatively, the otp_operation_done interrupt can be enabled up to notify the processor once an access has completed.
  6. If the status register flags a DAI error, additional handling is required (see Section on Error handling).
  7. Go back to 1. and repeat until all data has been written.

The hardware will set DIRECT_ACCESS_REGWEN to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers.

Note that SW is responsible for keeping track of already programmed OTP word locations during the provisioning phase. It is imperative that SW does not write the same word location twice, since this can lead to ECC inconsistencies, thereby potentially rendering the device useless.

Digest Calculation Sequence

The hardware digest computation for the hardware and secret partitions can be triggered as follows:

  1. Check whether the DAI is idle by reading the STATUS register.
  2. Write the partition base address to DIRECT_ACCESS_ADDRESS.
  3. Trigger a digest calculation command by writing 0x4 to DIRECT_ACCESS_CMD.
  4. Poll the STATUS until the DAI state goes back to idle. Alternatively, the otp_operation_done interrupt can be enabled up to notify the processor once an access has completed.
  5. If the status register flags a DAI error, additional handling is required (see Section on Error handling).

The hardware will set DIRECT_ACCESS_REGWEN to 0x0 while an operation is pending in order to temporarily lock write access to the CSRs registers.

It should also be noted that the effect of locking a partition via the digest only takes effect after the next system reset. To prevent integrity check failures SW must therefore ensure that no more programming operations are issued to the affected partition after initiating the digest calculation sequence.

Software Integrity Handling

As opposed to buffered partitions, the digest and integrity handling of unbuffered partitions is entirely up to software. The only hardware-assisted feature in unbuffered partitions is the digest lock, which locks write access to an unbuffered partition once a nonzero value has been programmed to the 64bit digest location.

In a similar vein, it should be noted that the system-wide bus-integrity metadata does not travel alongside the data end-to-end in the OTP controller (i.e., the bus-integrity metadata bits are not stored into the OTP memory array). This means that data written to and read from the OTP macro is not protected by the bus integrity feature at all stages. In case of buffered partitions this does not pose a concern since data integrity in these partitions is checked via the hardware assisted digest mechanism. In case of unbuffered partitions however, the data integrity checking is entirely up to software. I.e., if data is read from an unbuffered partition (either through the DAI or CSR windows), software should perform an integrity check on that data.

Error Handling

The agents that can access the OTP macro (DAI, LCI, buffered/unbuffered partitions) expose detailed error codes that can be used to root cause any failure. The error codes are defined in the table below, and the corresponding otp_err_e enum type can be found in the otp_ctrl_pkg. The table also lists which error codes are supported by which agent.

Errors that are not “recoverable” are severe errors that move the corresponding partition or DAI/LCI FSM into a terminal error state, where no more commands can be accepted (a system reset is required to restore functionality in that case). Errors that are “recoverable” are less severe and do not cause the FSM to jump into a terminal error state.

Note that error codes that originate in the physical OTP macro are prefixed with Macro*.

Error CodeEnum NameRecoverableDAILCIUnbufBufDescription
0x0NoError-xxxxNo error has occurred.
0x1MacroErrornoxxxxReturned if the OTP macro command did not complete successfully due to a macro malfunction.
0x2MacroEccCorrErroryesx-xxA correctable ECC error has occurred during a read operation in the OTP macro.
0x3MacroEccUncorrErrornox-x*xAn uncorrectable ECC error has occurred during a read operation in the OTP macro. Note (*): This error is collapsed into MacroEccCorrError if the partition is a vendor test partition. It then becomes a recoverable error.
0x4MacroWriteBlankErroryes / no*xx--This error is returned if a write operation attempted to clear an already programmed bit location. Note (*): This error is recoverable if encountered in the DAI, but unrecoverable if encountered in the LCI.
0x5AccessErroryesx-x-An access error has occurred (e.g. write to write-locked region, or read to a read-locked region).
0x6CheckFailErrorno--xxAn unrecoverable ECC, integrity or consistency error has been detected.
0x7FsmStateErrornoxxxxThe FSM has been glitched into an invalid state, or escalation has been triggered and the FSM has been moved into a terminal error state.

All non-zero error codes listed above trigger an otp_error interrupt. In addition, all unrecoverable OTP Macro* errors (codes 0x1, 0x3) trigger a fatal_macro_error alert, while all remaining unrecoverable errors trigger a fatal_check_error alert.

If software receives an otp_error interrupt, but all error codes read back as 0x0 (NoError), this should be treated as a fatal error condition, and the system should be shut down as soon as possible.

Note that the MacroWriteBlankError will only be generated if the write attempt over already written data fails within the OTP macro after applying any means supported within it to enable a write on existing data, e.g., a bit-reversal option. Also note that while this error is marked as a recoverable error, the affected OTP word may be in an inconsistent state after this error has been returned. This can cause several issues when the word is accessed again (either as part of a regular read operation, as part of the readout at boot, or as part of a background check). It is important that SW ensures that each word is only written once, since this can render the device useless.

Direct Access Memory Map

The table below provides a detailed overview of the items stored in the OTP partitions. Some of the items that are buffered in registers is readable via memory mapped CSRs, and these CSRs are linked in the table below. Items that are not linked can only be accessed via the direct programming interface (if the partition is not locked via the corresponding digest). It should be noted that CREATOR_SW_CFG and OWNER_SW_CFG are accessible through a memory mapped window, and content of these partitions is not buffered. Hence, a read access to those windows will take in the order of 10-20 cycles until the read returns.

Sizes below are specified in multiples of 32bit words.

IndexPartitionSize [B]Access GranuleItemByte AddressSize [B]
0VENDOR_TEST6432bitSCRATCH0x00056
64bitVENDOR_TEST_DIGEST0x0388
1CREATOR_SW_CFG36832bitCREATOR_SW_CFG_AST_CFG0x040156
32bitCREATOR_SW_CFG_AST_INIT_EN0x0DC4
32bitCREATOR_SW_CFG_ROM_EXT_SKU0x0E04
32bitCREATOR_SW_CFG_SIGVERIFY_SPX_EN0x0E44
32bitCREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG0x0E84
32bitCREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG0x0EC4
32bitCREATOR_SW_CFG_FLASH_HW_INFO_CFG_OVERRIDE0x0F04
32bitCREATOR_SW_CFG_RNG_EN0x0F44
32bitCREATOR_SW_CFG_JITTER_EN0x0F84
32bitCREATOR_SW_CFG_RET_RAM_RESET_MASK0x0FC4
32bitCREATOR_SW_CFG_MANUF_STATE0x1004
32bitCREATOR_SW_CFG_ROM_EXEC_EN0x1044
32bitCREATOR_SW_CFG_CPUCTRL0x1084
32bitCREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT0x10C4
32bitCREATOR_SW_CFG_MIN_SEC_VER_BL00x1104
32bitCREATOR_SW_CFG_DEFAULT_BOOT_DATA_IN_PROD_EN0x1144
32bitCREATOR_SW_CFG_RMA_SPIN_EN0x1184
32bitCREATOR_SW_CFG_RMA_SPIN_CYCLES0x11C4
32bitCREATOR_SW_CFG_RNG_REPCNT_THRESHOLDS0x1204
32bitCREATOR_SW_CFG_RNG_REPCNTS_THRESHOLDS0x1244
32bitCREATOR_SW_CFG_RNG_ADAPTP_HI_THRESHOLDS0x1284
32bitCREATOR_SW_CFG_RNG_ADAPTP_LO_THRESHOLDS0x12C4
32bitCREATOR_SW_CFG_RNG_BUCKET_THRESHOLDS0x1304
32bitCREATOR_SW_CFG_RNG_MARKOV_HI_THRESHOLDS0x1344
32bitCREATOR_SW_CFG_RNG_MARKOV_LO_THRESHOLDS0x1384
32bitCREATOR_SW_CFG_RNG_EXTHT_HI_THRESHOLDS0x13C4
32bitCREATOR_SW_CFG_RNG_EXTHT_LO_THRESHOLDS0x1404
32bitCREATOR_SW_CFG_RNG_ALERT_THRESHOLD0x1444
32bitCREATOR_SW_CFG_RNG_HEALTH_CONFIG_DIGEST0x1484
32bitCREATOR_SW_CFG_SRAM_KEY_RENEW_EN0x14C4
32bitCREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN0x1504
32bitCREATOR_SW_CFG_IMMUTABLE_ROM_EXT_START_OFFSET0x1544
32bitCREATOR_SW_CFG_IMMUTABLE_ROM_EXT_LENGTH0x1584
32bitCREATOR_SW_CFG_IMMUTABLE_ROM_EXT_SHA256_HASH0x15C32
32bitCREATOR_SW_CFG_RESERVED0x17C32
64bitCREATOR_SW_CFG_DIGEST0x1A88
2OWNER_SW_CFG71232bitOWNER_SW_CFG_ROM_ERROR_REPORTING0x1B04
32bitOWNER_SW_CFG_ROM_BOOTSTRAP_DIS0x1B44
32bitOWNER_SW_CFG_ROM_ALERT_CLASS_EN0x1B84
32bitOWNER_SW_CFG_ROM_ALERT_ESCALATION0x1BC4
32bitOWNER_SW_CFG_ROM_ALERT_CLASSIFICATION0x1C0320
32bitOWNER_SW_CFG_ROM_LOCAL_ALERT_CLASSIFICATION0x30064
32bitOWNER_SW_CFG_ROM_ALERT_ACCUM_THRESH0x34016
32bitOWNER_SW_CFG_ROM_ALERT_TIMEOUT_CYCLES0x35016
32bitOWNER_SW_CFG_ROM_ALERT_PHASE_CYCLES0x36064
32bitOWNER_SW_CFG_ROM_ALERT_DIGEST_PROD0x3A04
32bitOWNER_SW_CFG_ROM_ALERT_DIGEST_PROD_END0x3A44
32bitOWNER_SW_CFG_ROM_ALERT_DIGEST_DEV0x3A84
32bitOWNER_SW_CFG_ROM_ALERT_DIGEST_RMA0x3AC4
32bitOWNER_SW_CFG_ROM_WATCHDOG_BITE_THRESHOLD_CYCLES0x3B04
32bitOWNER_SW_CFG_ROM_KEYMGR_OTP_MEAS_EN0x3B44
32bitOWNER_SW_CFG_MANUF_STATE0x3B84
32bitOWNER_SW_CFG_ROM_RSTMGR_INFO_EN0x3BC4
32bitOWNER_SW_CFG_ROM_EXT_BOOTSTRAP_EN0x3C04
32bitOWNER_SW_CFG_ROM_SENSOR_CTRL_ALERT_CFG0x3C412
32bitOWNER_SW_CFG_ROM_SRAM_READBACK_EN0x3D04
32bitOWNER_SW_CFG_ROM_PRESERVE_RESET_REASON_EN0x3D44
32bitOWNER_SW_CFG_ROM_RESET_REASON_CHECK_VALUE0x3D84
32bitOWNER_SW_CFG_ROM_BANNER_EN0x3DC4
32bitOWNER_SW_CFG_ROM_FLASH_ECC_EXC_HANDLER_EN0x3E04
32bitOWNER_SW_CFG_RESERVED0x3E4128
64bitOWNER_SW_CFG_DIGEST0x4708
3ROT_CREATOR_AUTH_CODESIGN47232bitROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE00x4784
32bitROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY00x47C64
32bitROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE10x4BC4
32bitROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY10x4C064
32bitROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE20x5004
32bitROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY20x50464
32bitROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE30x5444
32bitROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY30x54864
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE00x5884
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY00x58C32
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG00x5AC4
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE10x5B04
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY10x5B432
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG10x5D44
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE20x5D84
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY20x5DC32
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG20x5FC4
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE30x6004
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY30x60432
32bitROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG30x6244
32bitROT_CREATOR_AUTH_CODESIGN_BLOCK_SHA2_256_HASH0x62832
64bitROT_CREATOR_AUTH_CODESIGN_DIGEST0x6488
4ROT_CREATOR_AUTH_STATE4032bitROT_CREATOR_AUTH_STATE_ECDSA_KEY00x6504
32bitROT_CREATOR_AUTH_STATE_ECDSA_KEY10x6544
32bitROT_CREATOR_AUTH_STATE_ECDSA_KEY20x6584
32bitROT_CREATOR_AUTH_STATE_ECDSA_KEY30x65C4
32bitROT_CREATOR_AUTH_STATE_SPX_KEY00x6604
32bitROT_CREATOR_AUTH_STATE_SPX_KEY10x6644
32bitROT_CREATOR_AUTH_STATE_SPX_KEY20x6684
32bitROT_CREATOR_AUTH_STATE_SPX_KEY30x66C4
64bitROT_CREATOR_AUTH_STATE_DIGEST0x6708
5HW_CFG07232bitDEVICE_ID0x67832
32bitMANUF_STATE0x69832
64bitHW_CFG0_DIGEST0x6B88
6HW_CFG11632bitEN_SRAM_IFETCH0x6C01
32bitEN_CSRNG_SW_APP_READ0x6C11
32bitDIS_RV_DM_LATE_DEBUG0x6C21
64bitHW_CFG1_DIGEST0x6C88
7SECRET04064bitTEST_UNLOCK_TOKEN0x6D016
64bitTEST_EXIT_TOKEN0x6E016
64bitSECRET0_DIGEST0x6F08
8SECRET18864bitFLASH_ADDR_KEY_SEED0x6F832
64bitFLASH_DATA_KEY_SEED0x71832
64bitSRAM_DATA_KEY_SEED0x73816
64bitSECRET1_DIGEST0x7488
9SECRET28864bitRMA_TOKEN0x75016
64bitCREATOR_ROOT_KEY_SHARE00x76032
64bitCREATOR_ROOT_KEY_SHARE10x78032
64bitSECRET2_DIGEST0x7A08
10LIFE_CYCLE8832bitLC_TRANSITION_CNT0x7A848
32bitLC_STATE0x7D840

Note that since the content in the SECRET* partitions are scrambled using a 64bit PRESENT cipher, read and write access through the DAI needs to occur at a 64bit granularity. Also, all digests (no matter whether they are SW or HW digests) have an access granule of 64bit.

The table below lists digests locations, and the corresponding locked partitions.

Digest NameAffected PartitionCalculated by HW
VENDOR_TEST_DIGESTVENDOR_TESTno
CREATOR_SW_CFG_DIGESTCREATOR_SW_CFGno
OWNER_SW_CFG_DIGESTOWNER_SW_CFGno
ROT_CREATOR_AUTH_CODESIGN_DIGESTROT_CREATOR_AUTH_CODESIGNno
ROT_CREATOR_AUTH_STATE_DIGESTROT_CREATOR_AUTH_STATEno
HW_CFG0_DIGESTHW_CFG0yes
HW_CFG1_DIGESTHW_CFG1yes
SECRET0_DIGESTSECRET0yes
SECRET1_DIGESTSECRET1yes
SECRET2_DIGESTSECRET2yes

Write access to the affected partition will be locked if the digest has a nonzero value.

For the software partition digests, it is entirely up to software to decide on the digest algorithm to be used. Hardware will determine the lock condition only based on whether a non-zero value is present at that location or not.

For the hardware partitions, hardware calculates this digest and uses it for background verification. Digest calculation can be triggered via the DAI.

Finally, it should be noted that the RMA_TOKEN and CREATOR_ROOT_KEY_SHARE0 / CREATOR_ROOT_KEY_SHARE1 items can only be programmed when the device is in the DEV, PROD, PROD_END and RMA stages. Please consult the life cycle controller documentation documentation for more information.

OTP Field Descriptions

The table below describes what each field in the OTP partitions is used for.

PartitionItemSize [B]Description
CREATOR_SW_CFGCREATOR_SW_CFG_AST_CFG156AST configuration data. These values get blindly copied to the AST CSRs during ROM execution.
CREATOR_SW_CFG_AST_INIT_EN4Controls whether or not the CREATOR_SW_CFG_AST_CFG values get copied to the AST CSRs during ROM execution. A value of kMultiBitBool4True enables copying; all other values disable.
CREATOR_SW_CFG_ROM_EXT_SKU4SKU identifier metadata. Unused by SiliconCreator software.
CREATOR_SW_CFG_SIGVERIFY_SPX_EN4Controls whether or not SPHINCS+ signature verification will be executed when the ROM attempts to boot the ROM_EXT. A value of kSigverifySpxDisabledOtp disables SPHINCS+ signature verification, while all other values enable it. Note, SPHINCS+ signature verification is always disabled in TEST_UNLOCKED* LC states.
CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG4The default scrambling, ECC, and high endurance configuration settings for flash data pages set during ROM execution.
CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG4The scrambling, ECC, and high endurance configuration settings for the boot data flash info pages set during ROM execution.
CREATOR_SW_CFG_FLASH_HW_INFO_CFG_OVERRIDE4Scrambling and ECC configuration overrides (set by the ROM) for the Creator and OwnerSeed flash info pages (pages 1 and 2 in partition 0) that are hardwired to the keygmr. By default, scrambling and ECC on these flash info pages must be enabled in order to successfully crank the keygmr (in the ROM_EXT). However, values of kMultiBitBool4True for each subfield in this field will disable this requirement. See the HW_INFO_CFG_OVERRIDE flash_ctrl CSR for more details.
CREATOR_SW_CFG_RNG_EN4Whether or not to enable use of hardware generated entropy (from the entropy complex via EDN) in the rnd_uint32 function. A value of kHardenedBoolTrue enables the use of hardware generated entropy, while all other values disable.
CREATOR_SW_CFG_JITTER_EN4Whether or not to enable clock jitter. A value of kMultiBitBool4False disables, while all other values enable.
CREATOR_SW_CFG_RET_RAM_RESET_MASK4Reset reason mask used to initialize (by overwriting with random data) retention SRAM during ROM execution. A value of 0 only initializes retention SRAM on power-on-resets.See rstmgr RESET_INFO CSR documentation for more details.
CREATOR_SW_CFG_MANUF_STATE4Manufacturing state binding field. For use by SiliconCreators or SiliconOwners to bind ROM_EXT images to a specific device or set of devices.
CREATOR_SW_CFG_ROM_EXEC_EN4Whether or not to enable execution of ROM. A value of 0 disables, while all other values enable. This enables provisioning flows to attach JTAG connections and halt the CPU before the device has been fully provisioned. All SKUs should set this field to a non-zero value. Provisioning flows shall take care to program this field at the appropriate time during.
CREATOR_SW_CFG_CPUCTRL4Value to write to the Ibex CPUCTRL CSR during ROM execution. This field controls settings such as ICACHE enablement. See Ibex documentation for more information.
CREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT4Value of the min_security_version_rom_ext field of the default boot data.
CREATOR_SW_CFG_MIN_SEC_VER_BL04Value of the min_security_version_bl0 field of the default boot data.
CREATOR_SW_CFG_DEFAULT_BOOT_DATA_IN_PROD_EN4Whether or not to enable the default boot data in PROD and PROD_END life cycle states. A value of kHardenedBoolTrue enables, all other values disable. If left disabled, provisioning flows are required to setup boot data pages prior to enabling ROM execution.
CREATOR_SW_CFG_RMA_SPIN_EN4Whether or not to enable a busy-wait delay loop in the ROM, when a specific SW strapping configuration is applied during boot, to provide time to trigger an RMA lifecycle transition over JTAG. A value of kHardenedBoolTrue enables, all other values disable.
CREATOR_SW_CFG_RMA_SPIN_CYCLES4The number of Ibex clock cycles to spin for when waiting for an RMA transition. Used in combination with the CREATOR_SW_CFG_RMA_SPIN_EN field.
CREATOR_SW_CFG_RNG_REPCNT_THRESHOLDS4The repetition count health test thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details.
CREATOR_SW_CFG_RNG_REPCNTS_THRESHOLDS4The repetition count symbol health test thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details.
CREATOR_SW_CFG_RNG_ADAPTP_HI_THRESHOLDS4The adaptive proportion health test high thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details.
CREATOR_SW_CFG_RNG_ADAPTP_LO_THRESHOLDS4The adaptive proportion health test low thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details.
CREATOR_SW_CFG_RNG_BUCKET_THRESHOLDS4The bucket health test thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details.
CREATOR_SW_CFG_RNG_MARKOV_HI_THRESHOLDS4The Markov health test high thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details.
CREATOR_SW_CFG_RNG_MARKOV_LO_THRESHOLDS4The Markov health test low thresholds to enable entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details.
CREATOR_SW_CFG_RNG_EXTHT_HI_THRESHOLDS4The external health test high thresholds to enable the entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details.
CREATOR_SW_CFG_RNG_EXTHT_LO_THRESHOLDS4The external health test low thresholds to enable the entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details.
CREATOR_SW_CFG_RNG_ALERT_THRESHOLD4The alert threshold to configure the entropy_src with during ROM execution. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details.
CREATOR_SW_CFG_RNG_HEALTH_CONFIG_DIGEST4A CRC32 digest of all entropy_src health test threshold configuration fields above. This must be configured if CREATOR_SW_CFG_RNG_EN is true. See entropy_src documentation for more details.
CREATOR_SW_CFG_SRAM_KEY_RENEW_EN4Whether or not the ROM should request SRAM to be rescrambled with a new key on every boot. kHardenedBoolFalse disables, while all other values enable.
CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN4Enablement of the ROM_EXT immutable code section. A value of kHardenedBoolTrue enables the feature. All other values disable it.
CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_START_OFFSET4Relative offset from the start of the ROM_EXT slot to find the immutable code section at.
CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_LENGTH4Length (in bytes) of the immutable code section.
CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_SHA256_HASH32SHA256 hash of the immutable ROM_EXT section.
CREATOR_SW_CFG_RESERVED32Unused bits in the CREATOR_SW_CFG OTP partition. These can be claimed by software as needed.
OWNER_SW_CFGOWNER_SW_CFG_ROM_ERROR_REPORTING4The shutdown error reporting verbosity used by the ROM. Should be configured to one of several shutdown_error_redact_t values. See sw/device/silicon_creator/lib/shutdown.h for more details.
OWNER_SW_CFG_ROM_BOOTSTRAP_DIS4Whether or not to disable ROM bootstrap mechanism. A value of kHardenedBoolTrue disable bootstrap mechanism in the ROM, while all other values enable it. Note, the provisioning flow should take care when to program this field if it is used by a SKU, as there is no way to get firmware into flash in a PROD LC state if a valid ROM_EXT does not already exist in flash once this value is configured to true.
OWNER_SW_CFG_ROM_ALERT_CLASS_EN4A four byte packed field, where each byte controls whether or not the ROM enables each alert class (A through D) of the alert_handler. The byte-sized subfields are arranged from D to A, MSB to LSB. Each byte should be set to an alert_enable_t value accordingly. See the alert_handler documentation for more details.
OWNER_SW_CFG_ROM_ALERT_ESCALATION4A four byte packed field, where each byte controls the escalation configuration for each alert class (A through D) of the alert_handler configured by the ROM. The byte-sized subfields are arranged from D to A, MSB to LSB. Each byte should be set to an alert_escalate_t value accordingly. See the alert_handler documentation for more details.
OWNER_SW_CFG_ROM_ALERT_CLASSIFICATION320The alert classifications (A through D) for each alert source of the alert_handler to be configured by the ROM. The field consists of a contiguous 320-byte block, or 80 32-bit words. The four bytes in each word encode the configuration of a single alert source across four lifecycle states, in order from LSB to MSB: PROD, PROD_END, DEV, and RMA. Each byte should be set to an alert_class_t value accordingly. The order of the 80 32-bit words, from LSB to MSB can be found in the EARLGREY_ALERTS list in rules/const.bzl. See the alert_handler documentation for more details.
OWNER_SW_CFG_ROM_LOCAL_ALERT_CLASSIFICATION64Same as the OWNER_SW_CFG_ROM_ALERT_CLASSIFICATION field, except these configuration correspond to the local alert sources found in the EARLGREY_LOC_ALERTS list in rules/const.bzl`.
OWNER_SW_CFG_ROM_ALERT_ACCUM_THRESH16The alert accumulation threshold values for each alert class (A through D) of the alert_handler to be configured by the ROM. This field consists of four 32-bit words encoding the accumulation thresholds for each alert class A through D arranged LSW to MSW. See the alert_handler documentation for more details.
OWNER_SW_CFG_ROM_ALERT_TIMEOUT_CYCLES16Same as the OWNER_SW_CFG_ROM_ALERT_ACCUM_THRESH field, except each value corresponds to the interrupt timeout configuration of an alert class.
OWNER_SW_CFG_ROM_ALERT_PHASE_CYCLES64The alert escalation phase durations, measured in clock cycles, the ROM will configure the four alert phases for each alert class of the alert_handler. This field consists of a contiguous 64-byte block, or an array of four 128-bit fields. Each 128-bit subfield encodes four 32-bit words that contain the alert phase cycle count configurations for alert escalation phases 0 to 3, from LSW to MSW. Each 128-bit subfield is contains all cofigurations for a single alert class, arranged from class A to D, from LS to MS. For example, the cycle durations of each escalation phase in this field should be configured as such, from LSB to MSB: <classA,phase0>…<classA,phase3>…<classD,phase0>… <classD,phase3>. See the alert_handler documentation for more details.
OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD4The expected CRC32 digest over all of the alert_handler configurations set up by the ROM for a device operating in the PROD LC state. The ROM reads this field and checks it against a digest it computes over the alert_handler configuration it programmed. This field is expected to be automatically computed by the otp_alert_digest() Bazel rule. See the alert_config_crc32() function in the SiliconCreator alert_handler driver for more details on what configurations are included in this digest.
OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD_END4Same as the OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD field, except the expected digest is for chips operating in the PROD_END LC state.
OWNER_SW_CFG_ROM_ALERT_DIGEST_DEV4Same as the OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD field, except the expected digest is for chips operating in the DEV LC state.
OWNER_SW_CFG_ROM_ALERT_DIGEST_RMA4Same as the OWNER_SW_CFG_ROM_ALERT_DIGEST_PROD field, except the expected digest is for chips operating in the RMA LC state.
OWNER_SW_CFG_ROM_WATCHDOG_BITE_THRESHOLD_CYCLES4Watchdog timer bite threshold (in cycles) configured by the ROM.
OWNER_SW_CFG_ROM_KEYMGR_OTP_MEAS_EN4Whether or not to configure the attestation SW binding CSRs of the keymgr with the value in ROM_EXT manifest or the measurement of the OTP CreatorSwCfg, OwnerSwCfg, and secure boot key integrity digest. A value of kHardenedBoolTrue uses the ROM computed OTP measurements, while all other values trigger the use of the binding values included in the ROM_EXT manifest.
OWNER_SW_CFG_MANUF_STATE4Manufacturing state binding field. For use by SiliconCreators or SiliconOwners to bind BL0 images to a specific device or set of devices.
OWNER_SW_CFG_ROM_RSTMGR_INFO_EN4A two byte packed word that indicates the expected rstmgr alert and CPU info dump enable states, configured in the rstmgr’s ALERT_INFO_CTRL and CPU_INFO_CTRL CSRs respectively. The expected format of this fields is {0,0,kHardenedBool*,kHardenedBool*}, read MSB to LSB, where the left most kHardenedBool* entry indicates the expected enablement state of the ALERT_INFO_CTRL, and the right most indicates the enablement state of the CPU_INFO_CTRL. Since the ROM expects both to be disabled upon handing over execution control to the ROM_EXT, this entire OTP field should be left unprovisioned, or set to all 0.
OWNER_SW_CFG_ROM_EXT_BOOTSTRAP_EN4Unused. Set to 0.
OWNER_SW_CFG_ROM_SENSOR_CTRL_ALERT_CFG12Alert configuration values for the sensor_ctrl block that will be configured by the ROM. This field is 12 bytes long, where each byte contains two 4-bit packed subfields, encoding two four bit boolean values (kMultiBitBool4False or kMultiBitBool4True), as follows (read MSB to LSB): {fatality, enablement}. For example, the byte 0x69 would encode the alert is: 1) recoverable, and 2) disabled. Currently, there are only 11 alerts in sensor_ctrl to configure, thus only the least significant bytes in this field are used.
OWNER_SW_CFG_ROM_SRAM_READBACK_EN4This field encodes the enablements of the readback security features for the main and retention SRAMs to be configured by the ROM. This field is four bytes, but the LSB contains two 4-bit packed kMultiBitBool4* values that indicate the enablement of the feature for the retention SRAM and main SRAM, from MSB to LSB respectively. See the READBACK CSR of the sram_ctrl for more details on this feature.
OWNER_SW_CFG_ROM_PRESERVE_RESET_REASON_EN4Whether or not the ROM should preserve the reset reasons CSR state in the rstmgr, or clear it. A value of kHardenedBoolTrue preserves the CSR, while other values trigger the ROM to clear the CSR after copying the reason to the retention SRAM.
OWNER_SW_CFG_ROM_RESET_REASON_CHECK_VALUE4Two packed 16-bit values that indicate whether the ROM should perform a validation check on the the reset reasons during boot. The validation check is a hardening mechanism that checks the reset reasons for consistency at two different points in time. Both packed values should be the same. Values of kHardenedBoolFalse will instruct the ROM to skip the reset reasons validation check, while all other values will instruct the ROM to perform the check.
OWNER_SW_CFG_ROM_BANNER_EN4Whether or not the ROM should print a banner message to the console UART during boot. A value of kHardenedBoolFalse disables the message printing, while all other values enable it.
OWNER_SW_CFG_ROM_FLASH_ECC_EXC_HANDLER_EN4Whether or not the ROM should use the flash ECC exception handler during execution. A value of kHardenedBoolTrue allows the ROM to use an the exception handler that recovers gracefully and continues the boot process if a flash ECC error is encountered during verification of a specific ROM_EXT slot. This enables the ROM to attempt booting the next ROM_EXT slot if the first slot attempted has been corrupted. All other values trigger default ROM exception handling, which is all exceptions trigger a chip shutdown and reset.
OWNER_SW_CFG_RESERVED128Unused bits in the OWNER_SW_CFG OTP partition. These can be claimed by software as needed.
ROT_CREATOR_AUTH_CODESIGNROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE04
ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY064
ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE14
ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY164
ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE24
ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY264
ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY_TYPE34
ROT_CREATOR_AUTH_CODESIGN_ECDSA_KEY364
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE04
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY032
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG04
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE14
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY132
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG14
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE24
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY232
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG24
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_TYPE34
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY332
ROT_CREATOR_AUTH_CODESIGN_SPX_KEY_CONFIG34
ROT_CREATOR_AUTH_CODESIGN_BLOCK_SHA2_256_HASH32
ROT_CREATOR_AUTH_STATEROT_CREATOR_AUTH_STATE_ECDSA_KEY04
ROT_CREATOR_AUTH_STATE_ECDSA_KEY14
ROT_CREATOR_AUTH_STATE_ECDSA_KEY24
ROT_CREATOR_AUTH_STATE_ECDSA_KEY34
ROT_CREATOR_AUTH_STATE_SPX_KEY04
ROT_CREATOR_AUTH_STATE_SPX_KEY14
ROT_CREATOR_AUTH_STATE_SPX_KEY24
ROT_CREATOR_AUTH_STATE_SPX_KEY34
HW_CFG0DEVICE_ID32Unique device identifier that is always exposed through the lifecycle JTAG tap. See OpenTitan documentation on Device Identifiers.
MANUF_STATE32Field to capture manufacturing status. Currently unused. Set to 0.
HW_CFG1EN_SRAM_IFETCH1Enablement of execute from SRAM switch in the sram_ctrl (see EXEC CSR). A kMultiBitBool8True value enables, while all other values disable.
EN_CSRNG_SW_APP_READ1Enablement of CSRNG software application interface. A kMultiBitBool8True value enables, while all other values disable. Enablement is required to extract output from CSRNG via software.
DIS_RV_DM_LATE_DEBUG1Disablement of RV_DM late debug feature (see rv_dm documentation). A kMultiBitBool8True disables the late debug feature and renders the rv_dm fully ungated in DEV lifecycle states. All other values gate rv_dm reachability based on the value of LATE_DEBUG_ENABLE CSR in the rv_dm block.

Examples

Provisioning Items

The following represents a typical provisioning sequence for items in all partitions (except for the LIFE_CYCLE partition, which is not software-programmable):

  1. Program the item in 32bit or 64bit chunks via the DAI.
  2. Read back and verify the item via the DAI.
  3. If the item is exposed via CSRs or a CSR window, perform a full-system reset and verify whether those fields are correctly populated.

Note that any unrecoverable errors during the programming steps, or mismatches during the readback and verification steps indicate that the device might be malfunctioning (possibly due to fabrication defects) and hence the device may have to be scrapped. This is however rare and should not happen after fabrication testing.

Locking Partitions

Once a partition has been fully populated, write access to that partition has to be permanently locked. For the HW_CFG* and SECRET* partitions, this can be achieved as follows:

  1. Trigger a digest calculation via the DAI.
  2. Read back and verify the digest location via the DAI.
  3. Perform a full-system reset and verify that the corresponding CSRs exposing the 64bit digest have been populated (HW_CFG_DIGEST_0, SECRET0_DIGEST_0, SECRET1_DIGEST_0 or SECRET2_DIGEST_0).

It should be noted that locking only takes effect after a system reset since the affected partitions first have to re-sense the digest values. Hence, it is critical that SW ensures that no more data is written to the partition to be locked after triggering the hardware digest calculation. Otherwise, the device will likely be rendered inoperable as this can lead to permanent digest mismatch errors after system reboot.

For the CREATOR_SW_CFG and OWNER_SW_CFG partitions, the process is similar, but computation and programming of the digest is entirely up to software:

  1. Compute a 64bit digest over the relevant parts of the partition, and program that value to CREATOR_SW_CFG_DIGEST_0 or OWNER_SW_CFG_DIGEST_0 via the DAI. Note that digest accesses through the DAI have an access granule of 64bit.
  2. Read back and verify the digest location via the DAI.
  3. Perform a full-system reset and verify that the corresponding digest CSRs CREATOR_SW_CFG_DIGEST_0 or OWNER_SW_CFG_DIGEST_0 have been populated with the correct 64bit value.

Note that any unrecoverable errors during the programming steps, or mismatches during the read-back and verification steps indicate that the device might be malfunctioning (possibly due to fabrication defects) and hence the device may have to be scrapped. This is however rare and should not happen after fabrication testing.

Device Interface Functions (DIFs)

Additional Notes

OTP IP Assumptions

It is assumed the OTP IP employed in production has reasonable physical defense characteristics. Specifically which defensive features will likely be use case dependent, but at a minimum they should have the properties below. Note some properties are worded with “SHALL” and others with “SHOULD”. “SHALL” refers to features that must be present, while “SHOULD” refers to features that are ideal, but optional.

  • The contents shall not be observable via optical microscopy (for example anti-fuse technology).
  • The IP lifetime shall not be limited by the amount of read cycles performed.
  • If the IP contains field programmability (internal charge pumps and LDOs), there shall be mechanisms in place to selectively disable this function based on device context.
  • If the IP contains redundant columns, rows, pages or banks for yield improvement, it shall provide a mechanism to lock down arbitrary manipulation of page / bank swapping during run-time.
  • The IP shall be clear on what bits must be manipulated by the user, what bits are automatically manipulated by hardware (for example ECC or redundancy) and what areas the user can influence.
  • The IP shall be compatible, through the use of a proprietary wrapper or shim, with an open-source friendly IO interface.
  • The IP should functionally support the programming of already programmed bits without information leakage.
  • The IP should offer SCA resistance:
    • For example, the content may be stored differentially.
    • For example, the sensing exhibits similar power signatures no matter if the stored bit is 0 or 1.
  • The IP interface shall be memory-like if beyond a certain size.
  • When a particular location is read, a fixed width output is returned; similar when a particular location is programmed, a fixed width input is supplied.
  • The IP does not output all stored bits in parallel.
  • The contents should be electrically hidden. For example, it should be difficult for an attacker to energize the fuse array and observe how the charge leaks.
  • The IP should route critical nets at lower metal levels to avoid probing.
  • The IP should contain native detectors for fault injection attacks.
  • The IP should contain mechanisms to guard against interrupted programming - either through malicious intent or unexpected power loss and glitched address lines.
  • The IP should contain mechanisms for error corrections (single bit errors).
    • For example ECC or redundant bits voting / or-ing.
    • As error correction mechanisms are technology dependent, that information should not be exposed to the open-source controller, instead the controller should simply receive information on whether a read / program was successful.
  • The IP should have self-test functionality to assess the health of the storage and analog structures.
  • The IP may contain native PUF-like functionality.