| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| { name: "otp_ctrl", |
| clock_primary: "clk_i", |
| bus_device: "tlul", |
| bus_host: "none", |
| |
| /////////////////////////// |
| // Interrupts and Alerts // |
| /////////////////////////// |
| |
| interrupt_list: [ |
| { name: "otp_operation_done", |
| desc: "A direct access command or digest calculation operation has completed." |
| } |
| { name: "otp_error", |
| desc: "An error has occurred in the OTP controller. Check the ERR_CODE register to get more information." |
| } |
| ], |
| |
| alert_list: [ |
| { name: "otp_fatal_error", |
| desc: "This alert triggers if hardware detects a parity bit or digest error in the buffered partitions.", |
| } |
| { name: "otp_check_failed", |
| desc: "This alert triggers if the digest over the buffered registers does not match with the digest stored in OTP.", |
| } |
| ], |
| |
| //////////////// |
| // Parameters // |
| //////////////// |
| param_list: [ |
| { name: "OtpByteAddrWidth", |
| desc: "Width of the OTP Byte address.", |
| type: "int", |
| default: "11", |
| local: "true" |
| }, |
| { name: "NumErrorEntries", |
| desc: "Number of error register entries.", |
| type: "int", |
| default: "9", // 7 partitions + DAI/LCI |
| local: "true" |
| }, |
| { name: "NumDaiWords", |
| desc: "Number of 32bit words in the DAI.", |
| type: "int", |
| default: "2", |
| local: "true" |
| }, |
| { name: "NumDigestWords", |
| desc: "Size of the digest fields in 32bit words.", |
| type: "int", |
| default: "2", |
| local: "true" |
| }, |
| { name: "NumLcHalfwords", |
| desc: "Number of 16bit life cycle fields.", |
| type: "int", |
| default: "12", |
| local: "true" |
| }, |
| { name: "NumCreatorSwCfgWindowWords", |
| desc: "Size of the TL-UL window in 32bit words. Note that the effective partition size is smaller than that.", |
| type: "int", |
| default: "256", |
| local: "true" |
| }, |
| { name: "NumOwnerSwCfgWindowWords", |
| desc: "Size of the TL-UL window in 32bit words. Note that the effective partition size is smaller than that.", |
| type: "int", |
| default: "256", |
| local: "true" |
| }, |
| { name: "NumDebugWindowWords", |
| desc: "Size of the TL-UL window in 32bit words.", |
| type: "int", |
| default: "512", |
| local: "true" |
| }, |
| ] |
| |
| ///////////////////////////// |
| // Intermodule Connections // |
| ///////////////////////////// |
| // TODO: these need to be refined during implementation and integration |
| inter_signal_list: [ |
| // CSRNG interface |
| { struct: "otp_csrng" |
| type: "req_rsp" |
| name: "otp_csrng" |
| act: "req" |
| package: "otp_ctrl_pkg" |
| } |
| // Power manager init command |
| { struct: "pwr_otp" |
| type: "req_rsp" |
| name: "pwr_otp_init" |
| act: "rsp" |
| package: "pwrmgr_pkg" |
| } |
| // Status output to power manager |
| { struct: "otp_pwr_state" |
| type: "uni" |
| name: "otp_pwr_state" |
| act: "req" |
| package: "otp_ctrl_pkg" |
| } |
| // LC transition command |
| { struct: "lc_otp_program" |
| type: "req_rsp" |
| name: "lc_otp_program" |
| act: "rsp" |
| package: "otp_ctrl_pkg" |
| } |
| // Broadcast to LC |
| { struct: "otp_lc_data" |
| type: "uni" |
| name: "otp_lc_data" |
| act: "req" |
| package: "otp_ctrl_pkg" |
| } |
| // Broadcast from LC |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_escalate_en" |
| act: "rcv" |
| package: "lifecycle_pkg" // TODO: move to LC package? |
| } |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_provision_en" |
| act: "rcv" |
| package: "lifecycle_pkg" // TODO: move to LC package? |
| } |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_test_en" |
| act: "rcv" |
| package: "lifecycle_pkg" // TODO: move to LC package? |
| } |
| // Broadcast to Key Manager |
| { struct: "keymgr_key" |
| type: "uni" |
| name: "otp_keymgr_key" |
| act: "req" |
| package: "otp_ctrl_pkg" // TODO: move this to keymgr package? |
| } |
| // Broadcast to Flash Controller |
| { struct: "flash_key" |
| type: "uni" |
| name: "otp_flash_key" |
| act: "req" |
| package: "otp_ctrl_pkg" |
| } |
| // Key request from Main RAM Scrambler |
| { struct: "ram_main_key" |
| type: "req_rsp" |
| name: "otp_ram_main_key" |
| act: "rsp" |
| package: "otp_ctrl_pkg" |
| } |
| // Key request from Retention RAM Scrambler |
| { struct: "ram_ret_aon_key" |
| type: "req_rsp" |
| name: "otp_ram_ret_aon_key" |
| act: "rsp" |
| package: "otp_ctrl_pkg" |
| } |
| // Key request from OTBN RAM Scrambler |
| { struct: "otbn_ram_key" |
| type: "req_rsp" |
| name: "otp_otbn_ram_key" |
| act: "rsp" |
| package: "otp_ctrl_pkg" |
| } |
| ] // inter_signal_list |
| |
| regwidth: "32", |
| registers: [ |
| |
| //////////////////////// |
| // Ctrl / Status CSRs // |
| //////////////////////// |
| |
| { name: "STATUS", |
| desc: "OTP status register.", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| fields: [ |
| { bits: "0" |
| name: "CREATOR_SW_CFG_ERROR" |
| desc: ''' |
| Set to 1 if an error occurred in this partition. |
| If set to 1, SW should check the !!ERR_CODE register at the corresponding index. |
| ''' |
| } |
| { bits: "1" |
| name: "OWNER_SW_CFG_ERROR" |
| desc: ''' |
| Set to 1 if an error occurred in this partition. |
| If set to 1, SW should check the !!ERR_CODE register at the corresponding index. |
| ''' |
| } |
| { bits: "2" |
| name: "HW_CFG_ERROR" |
| desc: ''' |
| Set to 1 if an error occurred in this partition. |
| If set to 1, SW should check the !!ERR_CODE register at the corresponding index. |
| ''' |
| } |
| { bits: "3" |
| name: "SECRET0_ERROR" |
| desc: ''' |
| Set to 1 if an error occurred in this partition. |
| If set to 1, SW should check the !!ERR_CODE register at the corresponding index. |
| ''' |
| } |
| { bits: "4" |
| name: "SECRET1_ERROR" |
| desc: ''' |
| Set to 1 if an error occurred in this partition. |
| If set to 1, SW should check the !!ERR_CODE register at the corresponding index. |
| ''' |
| } |
| { bits: "5" |
| name: "SECRET2_ERROR" |
| desc: ''' |
| Set to 1 if an error occurred in this partition. |
| If set to 1, SW should check the !!ERR_CODE register at the corresponding index. |
| ''' |
| } |
| { bits: "6" |
| name: "LIFE_CYCLE_ERROR" |
| desc: ''' |
| Set to 1 if an error occurred in this partition. |
| If set to 1, SW should check the !!ERR_CODE register at the corresponding index. |
| ''' |
| } |
| { bits: "7" |
| name: "DAI_ERROR" |
| desc: ''' |
| Set to 1 if an error occurred in the DAI. |
| If set to 1, SW should check the !!ERR_CODE register at the corresponding index. |
| ''' |
| } |
| { bits: "8" |
| name: "LCI_ERROR" |
| desc: ''' |
| Set to 1 if an error occurred in the LCI. |
| If set to 1, SW should check the !!ERR_CODE register at the corresponding index. |
| ''' |
| } |
| { bits: "9" |
| name: "TIMEOUT_ERROR" |
| desc: ''' |
| Set to 1 if an integrity or consistency check times out. |
| This raises an otp_check_failed alert and is an unrecoverable error condition. |
| ''' |
| } |
| { bits: "10" |
| name: "LFSR_FSM_ERROR" |
| desc: ''' |
| Set to 1 if the LFSR timer FSM has reached an invalid state. |
| This raises an otp_check_failed alert and is an unrecoverable error condition. |
| ''' |
| } |
| { bits: "11" |
| name: "SCRAMBLING_FSM_ERROR" |
| desc: ''' |
| Set to 1 if the scrambling datapath FSM has reached an invalid state. |
| This raises an otp_check_failed alert and is an unrecoverable error condition. |
| ''' |
| } |
| { bits: "12" |
| name: "KEY_DERIV_FSM_ERROR" |
| desc: ''' |
| Set to 1 if the key derivation FSM has reached an invalid state. |
| This raises an otp_check_failed alert and is an unrecoverable error condition. |
| ''' |
| } |
| { bits: "13" |
| name: "DAI_IDLE" |
| desc: "Set to 1 if the DAI is idle and ready to accept commands." |
| } |
| { bits: "14" |
| name: "CHECK_PENDING" |
| desc: "Set to 1 if an integrity or consistency check triggered by the LFSR timer or via !!CHECK_TRIGGER is pending." |
| } |
| ] |
| } |
| { multireg: { |
| name: "ERR_CODE", |
| desc: ''' |
| This register holds information on error conditions and should be |
| checked when any of the partitions or the DAI flags an error in the |
| !!STATUS registers, or when an !!INTR_STATE.otp_error has been triggered. |
| Note that all errors trigger an otp_error interrupt, and in addition some |
| errors may trigger either an otp_fatal_error or an otp_check_failed alert. |
| ''', |
| count: "NumErrorEntries", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| cname: "MODULE", |
| fields: [ |
| { |
| bits: "3:0" |
| enum: [ |
| { value: "0", |
| name: "NO_ERR", |
| desc: ''' |
| No error condition has occurred. |
| ''' |
| }, |
| { value: "1", |
| name: "OTP_CMD_INV_ERR", |
| desc: ''' |
| An invalid command has been written to the OTP macro. |
| This error should never occur during normal operation and is not recoverable. |
| If this error is present this may be a sign that the device is malfunctioning. |
| This error triggers an otp_fatal_error alert. |
| ''' |
| }, |
| { value: "2", |
| name: "OTP_INIT_ERR", |
| desc: ''' |
| The OTP macro initialization sequence has failed. |
| This error should never occur during normal operation and is not recoverable. |
| If this error is present this may be a sign that the device is malfunctioning. |
| This error triggers an otp_fatal_error alert. |
| ''' |
| }, |
| { value: "3", |
| name: "OTP_READ_CORR_ERR", |
| desc: ''' |
| A correctable error has occured during an OTP read operation. |
| The corresponding controller automatically recover from this error when |
| issuing a new command. |
| ''' |
| }, |
| { value: "4", |
| name: "OTP_READ_UNCORR_ERR", |
| desc: ''' |
| An uncorrectable error has occurred during an OTP read operation. |
| This error should never occur during normal operation and is not recoverable. |
| If this error is present this may be a sign that the device is malfunctioning. |
| This error triggers an otp_fatal_error alert. |
| ''' |
| }, |
| { value: "5", |
| name: "OTP_READ_ERR", |
| desc: ''' |
| A unspecified error has occurred during an OTP read operation. |
| This error should never occur during normal operation and is not recoverable. |
| If this error is present this may be a sign that the device is malfunctioning. |
| This error triggers an otp_fatal_error alert. |
| ''' |
| }, |
| { value: "6", |
| name: "OTP_WRITE_BLANK_ERR", |
| desc: ''' |
| A blank write check has failed during an OTP write operation. |
| This effectively aborts the write operation such that no harm is done to the OTP. |
| The corresponding controller automatically recovers from this error when issuing |
| a new command. |
| ''' |
| }, |
| { value: "7", |
| name: "OTP_WRITE_ERR", |
| desc: ''' |
| A unspecified error has occurred during an OTP write operation. |
| This error should never occur during normal operation and is not recoverable. |
| If this error is present this may be a sign that the device is malfunctioning. |
| This error triggers an otp_fatal_error alert. |
| ''' |
| }, |
| { value: "8", |
| name: "CMD_INV_ERR", |
| desc: ''' |
| This error indicates that an invalid command has been written to the DAI. |
| The DAI controller automatically recovers from this error when issuing |
| a new command. |
| ''' |
| }, |
| { value: "9", |
| name: "ACCESS_ERR", |
| desc: ''' |
| This error indicates that a locked memory region has been accessed. |
| The corresponding controller automatically recovers from this error when |
| issuing a new command. |
| ''' |
| }, |
| { value: "10", |
| name: "PARITY_ERROR", |
| desc: ''' |
| A parity mismatch has been detected in the buffer registers. |
| This error should never occur during normal operation and is not recoverable. |
| This error triggers an otp_check_failed alert. |
| ''' |
| }, |
| { value: "11", |
| name: "INTEG_ERR", |
| desc: ''' |
| An integrity check mismatch has been detected in the buffer registers. |
| This error should never occur during normal operation and is not recoverable. |
| This error triggers an otp_check_failed alert. |
| ''' |
| }, |
| { value: "12", |
| name: "CNSTY_ERR", |
| desc: ''' |
| A consistency check mismatch has been detected in the buffer registers. |
| This error should never occur during normal operation and is not recoverable. |
| This error triggers an otp_check_failed alert. |
| ''' |
| }, |
| { value: "13", |
| name: "FSM_ERR", |
| desc: ''' |
| The FSM of the corresponding controller has reached a parasitic state. |
| This error should never occur during normal operation and is not recoverable. |
| If this error is present, this is a sign that the device has fallen victim to |
| a glitch attack. |
| This error triggers an otp_check_failed alert. |
| ''' |
| }, |
| { value: "14", |
| name: "ESC_ERR", |
| desc: ''' |
| This error is the result of an escalation action in the alert subsystem, and |
| indicates that the corresponding controller FSM has been moved into a terminal |
| state due to escalation via the alert subsystem. |
| ''' |
| }, |
| ] |
| } |
| ] |
| } |
| } |
| { name: "DIRECT_ACCESS_REGWEN", |
| desc: ''' |
| Register write enable for all direct access interface registers. |
| ''', |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| fields: [ |
| { |
| bits: "0", |
| desc: ''' This bit is hardware-managed and only readable by software. The DAI sets this bit temporarily to 0 during an OTP operation such that the corresponding address and data |
| registers cannot be modified while the operation is pending. |
| ''' |
| resval: 1, |
| }, |
| ] |
| }, |
| { name: "DIRECT_ACCESS_CMD", |
| desc: "Command register for direct accesses.", |
| swaccess: "r0w1c", |
| hwaccess: "hro", |
| hwqe: "true", |
| hwext: "true", |
| regwen: "DIRECT_ACCESS_REGWEN", |
| fields: [ |
| { bits: "0", |
| name: "READ", |
| desc: ''' |
| Initiates a readout sequence that reads the location specified |
| by !!DIRECT_ACCESS_ADDRESS. The command places the data read into |
| !!DIRECT_ACCESS_RDATA_0 and !!DIRECT_ACCESS_RDATA_1 (for 64bit partitions). |
| ''' |
| } |
| { bits: "1", |
| name: "WRITE", |
| desc: ''' |
| Initiates a programming sequence that writes the data in !!DIRECT_ACCESS_WDATA_0 |
| and !!DIRECT_ACCESS_WDATA_1 (for 64bit partitions) to the location specified by |
| !!DIRECT_ACCESS_ADDRESS. |
| ''' |
| } |
| { bits: "2", |
| name: "DIGEST", |
| desc: ''' |
| Initiates the digest calculation and locking sequence for the partition specified by |
| !!DIRECT_ACCESS_ADDRESS. |
| ''' |
| } |
| ] |
| } |
| { name: "DIRECT_ACCESS_ADDRESS", |
| desc: "Address register for direct accesses.", |
| swaccess: "rw", |
| hwaccess: "hro", |
| hwqe: "false", |
| regwen: "DIRECT_ACCESS_REGWEN", |
| fields: [ |
| { bits: "OtpByteAddrWidth-1:0", |
| desc: ''' |
| This is the address for the OTP word to be read or written through |
| the direct access interface. Note that the address is aligned to the access size |
| internally, hence bits 1:0 are ignored for 32bit accesses, and bits 2:0 are ignored |
| for 64bit accesses. |
| |
| For the digest calculation command, set this register to the appropriate partition index |
| (0x2: !!HW_CFG_DIGEST, 0x4: !!SECRET0_DIGEST, 0x5: !!SECRET1_DIGEST and 0x6: !!SECRET2_DIGEST). |
| ''' |
| } |
| ] |
| } |
| { multireg: { |
| name: "DIRECT_ACCESS_WDATA", |
| desc: '''Write data for direct accesses. |
| Hardware automatically determines the access granule (32bit or 64bit) based on which |
| partition is being written to. |
| ''', |
| count: "NumDaiWords", // 2 x 32bit = 64bit |
| swaccess: "rw", |
| hwaccess: "hro", |
| hwqe: "false", |
| regwen: "DIRECT_ACCESS_REGWEN", |
| cname: "WORD", |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| { multireg: { |
| name: "DIRECT_ACCESS_RDATA", |
| desc: '''Read data for direct accesses. |
| Hardware automatically determines the access granule (32bit or 64bit) based on which |
| partition is read from. |
| ''', |
| count: "NumDaiWords", // 2 x 32bit = 64bit |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| cname: "WORD", |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| |
| ////////////////////////////////////// |
| // Integrity and Consistency Checks // |
| ////////////////////////////////////// |
| { name: "CHECK_TRIGGER_REGWEN", |
| desc: ''' |
| Register write enable for !!CHECK_TRIGGER. |
| ''', |
| swaccess: "rw1c", |
| hwaccess: "none", |
| fields: [ |
| { bits: "0", |
| desc: ''' |
| When cleared to 0, the !!CHECK_TRIGGER register cannot be written anymore. |
| Write 1 to clear this bit. |
| ''' |
| resval: 1, |
| }, |
| ] |
| }, |
| { name: "CHECK_TRIGGER", |
| desc: "Command register for direct accesses.", |
| swaccess: "r0w1c", |
| hwaccess: "hro", |
| hwqe: "true", |
| hwext: "true", |
| regwen: "CHECK_TRIGGER_REGWEN", |
| fields: [ |
| { bits: "0", |
| name: "INTEGRITY", |
| desc: ''' |
| Writing 1 to this bit triggers an integrity check. SW should monitor !!STATUS.CHECK_PENDING |
| and wait until the check has been completed. If there are any errors, those will be flagged |
| in the !!STATUS and !!ERR_CODE registers, and via the interrupts and alerts. |
| ''' |
| } |
| { bits: "1", |
| name: "CONSISTENCY", |
| desc: ''' |
| Writing 1 to this bit triggers a consistency check. SW should monitor !!STATUS.CHECK_PENDING |
| and wait until the check has been completed. If there are any errors, those will be flagged |
| in the !!STATUS and !!ERR_CODE registers, and via interrupts and alerts. |
| ''' |
| } |
| ] |
| }, |
| { name: "CHECK_REGWEN", |
| desc: ''' |
| Register write enable for !!INTEGRITY_CHECK_PERIOD and !!CONSISTENCY_CHECK_PERIOD. |
| ''', |
| swaccess: "rw1c", |
| hwaccess: "none", |
| fields: [ |
| { bits: "0", |
| desc: ''' |
| When cleared to 0, !!INTEGRITY_CHECK_PERIOD and !!CONSISTENCY_CHECK_PERIOD registers cannot be written anymore. |
| Write 1 to clear this bit. |
| ''' |
| resval: 1, |
| }, |
| ] |
| }, |
| { name: "CHECK_TIMEOUT", |
| desc: ''' |
| Timeout value for the integrity and consistency checks. |
| ''', |
| swaccess: "rw", |
| hwaccess: "hro", |
| regwen: "CHECK_REGWEN", |
| fields: [ |
| { bits: "31:0", |
| desc: ''' |
| Timeout value in cycles for the for the integrity and consistency checks. If an integrity or consistency |
| check does not complete within the timeout window, an error will be flagged in the !!STATUS register, |
| an otp_error interrupt will be raised, and an otp_check_failed alert will be sent out. The timeout should |
| be set to a large value to stay on the safe side. The maximum check time can be upper bounded by the |
| number of cycles it takes to readout, scramble and digest the entire OTP array. Since this amounts to |
| roughly 25k cycles, it is recommended to set this value to at least 100'000 cycles in order to stay on the |
| safe side. A value of zero disables the timeout mechanism (default). |
| ''' |
| resval: 0, |
| }, |
| ] |
| }, |
| { name: "INTEGRITY_CHECK_PERIOD", |
| desc: ''' |
| This value specifies the maximum period that can be generated pseudo-randomly. |
| Only applies to the HW_CFG and SECRET* partitions, once they are locked. |
| ''' |
| swaccess: "rw", |
| hwaccess: "hro", |
| regwen: "CHECK_REGWEN", |
| fields: [ |
| { bits: "31:0", |
| desc: ''' |
| The pseudo-random period is generated using a 40bit LFSR internally, and this register defines |
| the bit mask to be applied to the LFSR output in order to limit its range. The value of this |
| register is left shifted by 8bits and the lower bits are set to 8'hFF in order to form the 40bit mask. |
| A recommended value is 0x3_FFFF, corresponding to a maximum period of ~2.8s at 24MHz. |
| A value of zero disables the timer (default). Note that a one-off check can always be triggered via |
| !!CHECK_TRIGGER.INTEGRITY. |
| ''' |
| resval: "0" |
| } |
| ] |
| } |
| { name: "CONSISTENCY_CHECK_PERIOD", |
| desc: ''' |
| This value specifies the maximum period that can be generated pseudo-randomly. |
| This applies to the LIFE_CYCLE partition and the HW_CFG and SECRET* partitions, once they are locked. |
| ''' |
| swaccess: "rw", |
| hwaccess: "hro", |
| regwen: "CHECK_REGWEN", |
| fields: [ |
| { bits: "31:0", |
| desc: ''' |
| The pseudo-random period is generated using a 40bit LFSR internally, and this register defines |
| the bit mask to be applied to the LFSR output in order to limit its range. The value of this |
| register is left shifted by 8bits and the lower bits are set to 8'hFF in order to form the 40bit mask. |
| A recommended value is 0x3FF_FFFF, corresponding to a maximum period of ~716s at 24MHz. |
| A value of zero disables the timer (default). Note that a one-off check can always be triggered via |
| !!CHECK_TRIGGER.CONSISTENCY. |
| ''' |
| resval: "0" |
| } |
| ] |
| } |
| |
| //////////////////////////////////// |
| // Dynamic Locks of SW Parititons // |
| //////////////////////////////////// |
| { name: "CREATOR_SW_CFG_READ_LOCK", |
| desc: ''' |
| Runtime read lock for the creator software partition. |
| ''', |
| swaccess: "rw1c", |
| hwaccess: "hro", |
| fields: [ |
| { bits: "0", |
| desc: ''' |
| When cleared to 0, read access to the !!CREATOR_SW_CFG partition is locked. |
| Write 1 to clear this bit. |
| ''' |
| resval: 1, |
| }, |
| ] |
| }, |
| { name: "OWNER_SW_CFG_READ_LOCK", |
| desc: ''' |
| Runtime read lock for the owner software partition. |
| ''', |
| swaccess: "rw1c", |
| hwaccess: "hro", |
| fields: [ |
| { bits: "0", |
| desc: ''' |
| When cleared to 0, read access to the !!OWNER_SW_CFG partition is locked. |
| Write 1 to clear this bit. |
| ''' |
| resval: 1, |
| }, |
| ] |
| }, |
| |
| /////////////////////// |
| // Integrity Digests // |
| /////////////////////// |
| { multireg: { |
| name: "CREATOR_SW_CFG_DIGEST", |
| desc: ''' |
| Integrity digest for the creator software config partition. |
| The integrity digest is 0 by default. Software must write this |
| digest value via the direct access interface in order to lock the partition. |
| After a reset, write access to the !!OWNER_SW_CFG partition is locked and |
| the digest becomes visible in this CSR. |
| ''', |
| count: "NumDigestWords", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| cname: "WORD", |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| { multireg: { |
| name: "OWNER_SW_CFG_DIGEST", |
| desc: ''' |
| Integrity digest for the owner software config partition. |
| The integrity digest is 0 by default. Software must write this |
| digest value via the direct access interface in order to lock the partition. |
| After a reset, write access to the !!OWNER_SW_CFG partition is locked and |
| the digest becomes visible in this CSR. |
| ''', |
| count: "NumDigestWords", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| cname: "WORD", |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| { multireg: { |
| name: "HW_CFG_DIGEST", |
| desc: ''' |
| Hardware config partition integrity digest. |
| The integrity digest is 0 by default. The digest calculation can be triggered via the !!DIRECT_ACCESS_CMD. |
| After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. |
| ''', |
| count: "NumDigestWords", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| cname: "WORD", |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| { multireg: { |
| name: "SECRET0_DIGEST", |
| desc: ''' |
| Integrity digest for the SECRET0 partition. |
| The integrity digest is 0 by default. The digest calculation can be triggered via the !!DIRECT_ACCESS_CMD. |
| After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. |
| ''', |
| count: "NumDigestWords", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| cname: "WORD", |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| { multireg: { |
| name: "SECRET1_DIGEST", |
| desc: ''' |
| Integrity digest for the SECRET1 partition. |
| The integrity digest is 0 by default. The digest calculation can be triggered via the !!DIRECT_ACCESS_CMD. |
| After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. |
| ''', |
| count: "NumDigestWords", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| cname: "WORD", |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| { multireg: { |
| name: "SECRET2_DIGEST", |
| desc: ''' |
| Integrity digest for the SECRET2 partition. |
| The integrity digest is 0 by default. The digest calculation can be triggered via the !!DIRECT_ACCESS_CMD. |
| After a reset, the digest then becomes visible in this CSR, and the corresponding partition becomes write-locked. |
| ''', |
| count: "NumDigestWords", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| cname: "WORD", |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| |
| ////////////////////// |
| // Life Cycle State // |
| ////////////////////// |
| { multireg: { |
| name: "LC_STATE", |
| desc: ''' |
| Life cycle state, comprised of 12 16bit words. |
| TODO: add link to LC controller spec. |
| Other values than specified below are invalid. |
| ''', |
| count: "NumLcHalfwords", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| cname: "HALFWORD", |
| fields: [ |
| { bits: "15:0" |
| enum: [ |
| { value: "0", |
| name: "BLANK", |
| desc: ''' |
| 0x0000 |
| ''' |
| }, |
| { value: "62970", |
| name: "SET", |
| desc: ''' |
| 0xF5FA |
| ''' |
| }, |
| ] |
| } |
| ] |
| } |
| }, |
| { name: "LC_TRANSITION_CNT", |
| desc: "Counter for total amount of state transition attempts.", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| fields: [ |
| { bits: "31:0", |
| desc: ''' |
| This counter will be incremented upon each state transition attempt, |
| or when the transition command coming from the life cycle controller is invalid. |
| ''' |
| } |
| ] |
| } |
| |
| //////////////////////////////// |
| // Software Config Partitions // |
| //////////////////////////////// |
| { skipto: "0x400" } |
| |
| { window: { |
| name: "CREATOR_SW_CFG" |
| items: "NumCreatorSwCfgWindowWords" |
| swaccess: "ro", |
| desc: ''' |
| Any read to this window directly maps to the corresponding offset in the creator software |
| config partition, and triggers an OTP readout of the Bytes requested. Note that the transaction |
| will block until OTP readout has completed. |
| ''' |
| } |
| } |
| |
| { skipto: "0x800" } |
| |
| { window: { |
| name: "OWNER_SW_CFG" |
| items: "NumOwnerSwCfgWindowWords" |
| swaccess: "ro", |
| desc: ''' |
| Any read to this window directly maps to the corresponding offset in the owner software |
| config partition, and triggers an OTP readout of the Bytes requested. Note that the transaction |
| will block until OTP readout has completed. |
| ''' |
| } |
| } |
| |
| ////////////////////// |
| // Test Access Port // |
| ////////////////////// |
| { skipto: "0xC00" } |
| |
| // TODO: may have to update description, once it is known how RAW unlock is handled. |
| { window: { |
| name: "TEST_ACCESS" |
| items: "NumDebugWindowWords" |
| swaccess: "rw", |
| desc: ''' |
| This maps to the register file of the proprietary OTP macro. Note that this is only |
| accessible during the TEST life cycle state. |
| ''' |
| } |
| } |
| ], |
| } |