| // Copyright lowRISC contributors. |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| // |
| // HJSON with partition metadata. |
| // |
| // DO NOT EDIT THIS FILE DIRECTLY. |
| // It has been generated with ./util/design/gen-otp-mmap.py |
| |
| |
| { name: "otp_ctrl", |
| clocking: [ |
| {clock: "clk_i", reset: "rst_ni", primary: true}, |
| {clock: "clk_edn_i", reset: "rst_edn_ni"} |
| ] |
| scan: "true", // Enable `scanmode_i` port |
| scan_reset: "true", // Enable `scan_rst_ni` port |
| scan_en: "true", // Enable `scan_en_i` port |
| bus_interfaces: [ |
| { protocol: "tlul", direction: "device", name: "core" } |
| { protocol: "tlul", direction: "device", name: "prim" } |
| ], |
| |
| available_output_list: [ |
| { name: "test", |
| width: 8, |
| desc: "Test-related GPIOs. Only active in DFT-enabled life cycle states." |
| } |
| ], |
| |
| /////////////////////////// |
| // 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: "fatal_macro_error", |
| desc: "This alert triggers if hardware detects an ECC or digest error in the buffered partitions.", |
| } |
| { name: "fatal_check_error", |
| desc: "This alert triggers if the digest over the buffered registers does not match with the digest stored in OTP.", |
| } |
| { name: "fatal_bus_integ_error", |
| desc: "This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected." |
| } |
| ], |
| |
| //////////////// |
| // Parameters // |
| //////////////// |
| param_list: [ |
| // Init file |
| { name: "MemInitFile", |
| desc: "VMEM file to initialize the OTP macro.", |
| type: "", |
| default: '""', |
| expose: "true", |
| local: "false" |
| } |
| // Random netlist constants |
| { name: "RndCnstLfsrSeed", |
| desc: "Compile-time random bits for initial LFSR seed", |
| type: "otp_ctrl_pkg::lfsr_seed_t" |
| randcount: "40", |
| randtype: "data", // randomize randcount databits |
| } |
| { name: "RndCnstLfsrPerm", |
| desc: "Compile-time random permutation for LFSR output", |
| type: "otp_ctrl_pkg::lfsr_perm_t" |
| randcount: "40", |
| randtype: "perm", // random permutation for randcount elements |
| } |
| { name: "RndCnstScrmblKeyInit", |
| desc: "Compile-time random permutation for scrambling key/nonce register reset value", |
| type: "otp_ctrl_pkg::scrmbl_key_init_t" |
| randcount: "256", |
| randtype: "data", // random permutation for randcount elements |
| } |
| // Normal parameters |
| { name: "NumSramKeyReqSlots", |
| desc: "Number of key slots", |
| type: "int", |
| default: "3", |
| local: "true" |
| }, |
| { 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: "10", // 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: "NumSwCfgWindowWords", |
| desc: "Size of the TL-UL window in 32bit words. Note that the effective partition size is smaller than that.", |
| type: "int", |
| default: "512", |
| local: "true" |
| } |
| |
| // Memory map Info |
| { name: "NumPart", |
| desc: "Number of partitions", |
| type: "int", |
| default: "8", |
| local: "true" |
| }, |
| { name: "VendorTestOffset", |
| desc: "Offset of the VENDOR_TEST partition", |
| type: "int", |
| default: "0", |
| local: "true" |
| }, |
| { name: "VendorTestSize", |
| desc: "Size of the VENDOR_TEST partition", |
| type: "int", |
| default: "64", |
| local: "true" |
| }, |
| { name: "ScratchOffset", |
| desc: "Offset of SCRATCH", |
| type: "int", |
| default: "0", |
| local: "true" |
| }, |
| { name: "ScratchSize", |
| desc: "Size of SCRATCH", |
| type: "int", |
| default: "56", |
| local: "true" |
| }, |
| { name: "VendorTestDigestOffset", |
| desc: "Offset of VENDOR_TEST_DIGEST", |
| type: "int", |
| default: "56", |
| local: "true" |
| }, |
| { name: "VendorTestDigestSize", |
| desc: "Size of VENDOR_TEST_DIGEST", |
| type: "int", |
| default: "8", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgOffset", |
| desc: "Offset of the CREATOR_SW_CFG partition", |
| type: "int", |
| default: "64", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgSize", |
| desc: "Size of the CREATOR_SW_CFG partition", |
| type: "int", |
| default: "800", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgAstCfgOffset", |
| desc: "Offset of CREATOR_SW_CFG_AST_CFG", |
| type: "int", |
| default: "64", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgAstCfgSize", |
| desc: "Size of CREATOR_SW_CFG_AST_CFG", |
| type: "int", |
| default: "156", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgAstInitEnOffset", |
| desc: "Offset of CREATOR_SW_CFG_AST_INIT_EN", |
| type: "int", |
| default: "220", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgAstInitEnSize", |
| desc: "Size of CREATOR_SW_CFG_AST_INIT_EN", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgRomExtSkuOffset", |
| desc: "Offset of CREATOR_SW_CFG_ROM_EXT_SKU", |
| type: "int", |
| default: "224", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgRomExtSkuSize", |
| desc: "Size of CREATOR_SW_CFG_ROM_EXT_SKU", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgUseSwRsaVerifyOffset", |
| desc: "Offset of CREATOR_SW_CFG_USE_SW_RSA_VERIFY", |
| type: "int", |
| default: "228", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgUseSwRsaVerifySize", |
| desc: "Size of CREATOR_SW_CFG_USE_SW_RSA_VERIFY", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgKeyIsValidOffset", |
| desc: "Offset of CREATOR_SW_CFG_KEY_IS_VALID", |
| type: "int", |
| default: "232", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgKeyIsValidSize", |
| desc: "Size of CREATOR_SW_CFG_KEY_IS_VALID", |
| type: "int", |
| default: "8", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgFlashDataDefaultCfgOffset", |
| desc: "Offset of CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG", |
| type: "int", |
| default: "240", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgFlashDataDefaultCfgSize", |
| desc: "Size of CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgFlashInfoBootDataCfgOffset", |
| desc: "Offset of CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG", |
| type: "int", |
| default: "244", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgFlashInfoBootDataCfgSize", |
| desc: "Size of CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgRngEnOffset", |
| desc: "Offset of CREATOR_SW_CFG_RNG_EN", |
| type: "int", |
| default: "248", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgRngEnSize", |
| desc: "Size of CREATOR_SW_CFG_RNG_EN", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgJitterEnOffset", |
| desc: "Offset of CREATOR_SW_CFG_JITTER_EN", |
| type: "int", |
| default: "252", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgJitterEnSize", |
| desc: "Size of CREATOR_SW_CFG_JITTER_EN", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgRetRamResetMaskOffset", |
| desc: "Offset of CREATOR_SW_CFG_RET_RAM_RESET_MASK", |
| type: "int", |
| default: "256", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgRetRamResetMaskSize", |
| desc: "Size of CREATOR_SW_CFG_RET_RAM_RESET_MASK", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgManufStateOffset", |
| desc: "Offset of CREATOR_SW_CFG_MANUF_STATE", |
| type: "int", |
| default: "260", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgManufStateSize", |
| desc: "Size of CREATOR_SW_CFG_MANUF_STATE", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgRomExecEnOffset", |
| desc: "Offset of CREATOR_SW_CFG_ROM_EXEC_EN", |
| type: "int", |
| default: "264", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgRomExecEnSize", |
| desc: "Size of CREATOR_SW_CFG_ROM_EXEC_EN", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgCpuctrlOffset", |
| desc: "Offset of CREATOR_SW_CFG_CPUCTRL", |
| type: "int", |
| default: "268", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgCpuctrlSize", |
| desc: "Size of CREATOR_SW_CFG_CPUCTRL", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgMinSecVerRomExtOffset", |
| desc: "Offset of CREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT", |
| type: "int", |
| default: "272", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgMinSecVerRomExtSize", |
| desc: "Size of CREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgMinSecVerBl0Offset", |
| desc: "Offset of CREATOR_SW_CFG_MIN_SEC_VER_BL0", |
| type: "int", |
| default: "276", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgMinSecVerBl0Size", |
| desc: "Size of CREATOR_SW_CFG_MIN_SEC_VER_BL0", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgDefaultBootDataInProdEnOffset", |
| desc: "Offset of CREATOR_SW_CFG_DEFAULT_BOOT_DATA_IN_PROD_EN", |
| type: "int", |
| default: "280", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgDefaultBootDataInProdEnSize", |
| desc: "Size of CREATOR_SW_CFG_DEFAULT_BOOT_DATA_IN_PROD_EN", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgDigestOffset", |
| desc: "Offset of CREATOR_SW_CFG_DIGEST", |
| type: "int", |
| default: "856", |
| local: "true" |
| }, |
| { name: "CreatorSwCfgDigestSize", |
| desc: "Size of CREATOR_SW_CFG_DIGEST", |
| type: "int", |
| default: "8", |
| local: "true" |
| }, |
| { name: "OwnerSwCfgOffset", |
| desc: "Offset of the OWNER_SW_CFG partition", |
| type: "int", |
| default: "864", |
| local: "true" |
| }, |
| { name: "OwnerSwCfgSize", |
| desc: "Size of the OWNER_SW_CFG partition", |
| type: "int", |
| default: "800", |
| local: "true" |
| }, |
| { name: "RomErrorReportingOffset", |
| desc: "Offset of ROM_ERROR_REPORTING", |
| type: "int", |
| default: "864", |
| local: "true" |
| }, |
| { name: "RomErrorReportingSize", |
| desc: "Size of ROM_ERROR_REPORTING", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "RomBootstrapEnOffset", |
| desc: "Offset of ROM_BOOTSTRAP_EN", |
| type: "int", |
| default: "868", |
| local: "true" |
| }, |
| { name: "RomBootstrapEnSize", |
| desc: "Size of ROM_BOOTSTRAP_EN", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "RomFaultResponseOffset", |
| desc: "Offset of ROM_FAULT_RESPONSE", |
| type: "int", |
| default: "872", |
| local: "true" |
| }, |
| { name: "RomFaultResponseSize", |
| desc: "Size of ROM_FAULT_RESPONSE", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "RomAlertClassEnOffset", |
| desc: "Offset of ROM_ALERT_CLASS_EN", |
| type: "int", |
| default: "876", |
| local: "true" |
| }, |
| { name: "RomAlertClassEnSize", |
| desc: "Size of ROM_ALERT_CLASS_EN", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "RomAlertEscalationOffset", |
| desc: "Offset of ROM_ALERT_ESCALATION", |
| type: "int", |
| default: "880", |
| local: "true" |
| }, |
| { name: "RomAlertEscalationSize", |
| desc: "Size of ROM_ALERT_ESCALATION", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "RomAlertClassificationOffset", |
| desc: "Offset of ROM_ALERT_CLASSIFICATION", |
| type: "int", |
| default: "884", |
| local: "true" |
| }, |
| { name: "RomAlertClassificationSize", |
| desc: "Size of ROM_ALERT_CLASSIFICATION", |
| type: "int", |
| default: "320", |
| local: "true" |
| }, |
| { name: "RomLocalAlertClassificationOffset", |
| desc: "Offset of ROM_LOCAL_ALERT_CLASSIFICATION", |
| type: "int", |
| default: "1204", |
| local: "true" |
| }, |
| { name: "RomLocalAlertClassificationSize", |
| desc: "Size of ROM_LOCAL_ALERT_CLASSIFICATION", |
| type: "int", |
| default: "64", |
| local: "true" |
| }, |
| { name: "RomAlertAccumThreshOffset", |
| desc: "Offset of ROM_ALERT_ACCUM_THRESH", |
| type: "int", |
| default: "1268", |
| local: "true" |
| }, |
| { name: "RomAlertAccumThreshSize", |
| desc: "Size of ROM_ALERT_ACCUM_THRESH", |
| type: "int", |
| default: "16", |
| local: "true" |
| }, |
| { name: "RomAlertTimeoutCyclesOffset", |
| desc: "Offset of ROM_ALERT_TIMEOUT_CYCLES", |
| type: "int", |
| default: "1284", |
| local: "true" |
| }, |
| { name: "RomAlertTimeoutCyclesSize", |
| desc: "Size of ROM_ALERT_TIMEOUT_CYCLES", |
| type: "int", |
| default: "16", |
| local: "true" |
| }, |
| { name: "RomAlertPhaseCyclesOffset", |
| desc: "Offset of ROM_ALERT_PHASE_CYCLES", |
| type: "int", |
| default: "1300", |
| local: "true" |
| }, |
| { name: "RomAlertPhaseCyclesSize", |
| desc: "Size of ROM_ALERT_PHASE_CYCLES", |
| type: "int", |
| default: "64", |
| local: "true" |
| }, |
| { name: "RomWatchdogBiteThresholdCyclesOffset", |
| desc: "Offset of ROM_WATCHDOG_BITE_THRESHOLD_CYCLES", |
| type: "int", |
| default: "1364", |
| local: "true" |
| }, |
| { name: "RomWatchdogBiteThresholdCyclesSize", |
| desc: "Size of ROM_WATCHDOG_BITE_THRESHOLD_CYCLES", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "RomKeymgrRomExtMeasEnOffset", |
| desc: "Offset of ROM_KEYMGR_ROM_EXT_MEAS_EN", |
| type: "int", |
| default: "1368", |
| local: "true" |
| }, |
| { name: "RomKeymgrRomExtMeasEnSize", |
| desc: "Size of ROM_KEYMGR_ROM_EXT_MEAS_EN", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "OwnerSwCfgManufStateOffset", |
| desc: "Offset of OWNER_SW_CFG_MANUF_STATE", |
| type: "int", |
| default: "1372", |
| local: "true" |
| }, |
| { name: "OwnerSwCfgManufStateSize", |
| desc: "Size of OWNER_SW_CFG_MANUF_STATE", |
| type: "int", |
| default: "4", |
| local: "true" |
| }, |
| { name: "OwnerSwCfgDigestOffset", |
| desc: "Offset of OWNER_SW_CFG_DIGEST", |
| type: "int", |
| default: "1656", |
| local: "true" |
| }, |
| { name: "OwnerSwCfgDigestSize", |
| desc: "Size of OWNER_SW_CFG_DIGEST", |
| type: "int", |
| default: "8", |
| local: "true" |
| }, |
| { name: "HwCfgOffset", |
| desc: "Offset of the HW_CFG partition", |
| type: "int", |
| default: "1664", |
| local: "true" |
| }, |
| { name: "HwCfgSize", |
| desc: "Size of the HW_CFG partition", |
| type: "int", |
| default: "80", |
| local: "true" |
| }, |
| { name: "DeviceIdOffset", |
| desc: "Offset of DEVICE_ID", |
| type: "int", |
| default: "1664", |
| local: "true" |
| }, |
| { name: "DeviceIdSize", |
| desc: "Size of DEVICE_ID", |
| type: "int", |
| default: "32", |
| local: "true" |
| }, |
| { name: "ManufStateOffset", |
| desc: "Offset of MANUF_STATE", |
| type: "int", |
| default: "1696", |
| local: "true" |
| }, |
| { name: "ManufStateSize", |
| desc: "Size of MANUF_STATE", |
| type: "int", |
| default: "32", |
| local: "true" |
| }, |
| { name: "EnSramIfetchOffset", |
| desc: "Offset of EN_SRAM_IFETCH", |
| type: "int", |
| default: "1728", |
| local: "true" |
| }, |
| { name: "EnSramIfetchSize", |
| desc: "Size of EN_SRAM_IFETCH", |
| type: "int", |
| default: "1", |
| local: "true" |
| }, |
| { name: "EnCsrngSwAppReadOffset", |
| desc: "Offset of EN_CSRNG_SW_APP_READ", |
| type: "int", |
| default: "1729", |
| local: "true" |
| }, |
| { name: "EnCsrngSwAppReadSize", |
| desc: "Size of EN_CSRNG_SW_APP_READ", |
| type: "int", |
| default: "1", |
| local: "true" |
| }, |
| { name: "EnEntropySrcFwReadOffset", |
| desc: "Offset of EN_ENTROPY_SRC_FW_READ", |
| type: "int", |
| default: "1730", |
| local: "true" |
| }, |
| { name: "EnEntropySrcFwReadSize", |
| desc: "Size of EN_ENTROPY_SRC_FW_READ", |
| type: "int", |
| default: "1", |
| local: "true" |
| }, |
| { name: "EnEntropySrcFwOverOffset", |
| desc: "Offset of EN_ENTROPY_SRC_FW_OVER", |
| type: "int", |
| default: "1731", |
| local: "true" |
| }, |
| { name: "EnEntropySrcFwOverSize", |
| desc: "Size of EN_ENTROPY_SRC_FW_OVER", |
| type: "int", |
| default: "1", |
| local: "true" |
| }, |
| { name: "HwCfgDigestOffset", |
| desc: "Offset of HW_CFG_DIGEST", |
| type: "int", |
| default: "1736", |
| local: "true" |
| }, |
| { name: "HwCfgDigestSize", |
| desc: "Size of HW_CFG_DIGEST", |
| type: "int", |
| default: "8", |
| local: "true" |
| }, |
| { name: "Secret0Offset", |
| desc: "Offset of the SECRET0 partition", |
| type: "int", |
| default: "1744", |
| local: "true" |
| }, |
| { name: "Secret0Size", |
| desc: "Size of the SECRET0 partition", |
| type: "int", |
| default: "40", |
| local: "true" |
| }, |
| { name: "TestUnlockTokenOffset", |
| desc: "Offset of TEST_UNLOCK_TOKEN", |
| type: "int", |
| default: "1744", |
| local: "true" |
| }, |
| { name: "TestUnlockTokenSize", |
| desc: "Size of TEST_UNLOCK_TOKEN", |
| type: "int", |
| default: "16", |
| local: "true" |
| }, |
| { name: "TestExitTokenOffset", |
| desc: "Offset of TEST_EXIT_TOKEN", |
| type: "int", |
| default: "1760", |
| local: "true" |
| }, |
| { name: "TestExitTokenSize", |
| desc: "Size of TEST_EXIT_TOKEN", |
| type: "int", |
| default: "16", |
| local: "true" |
| }, |
| { name: "Secret0DigestOffset", |
| desc: "Offset of SECRET0_DIGEST", |
| type: "int", |
| default: "1776", |
| local: "true" |
| }, |
| { name: "Secret0DigestSize", |
| desc: "Size of SECRET0_DIGEST", |
| type: "int", |
| default: "8", |
| local: "true" |
| }, |
| { name: "Secret1Offset", |
| desc: "Offset of the SECRET1 partition", |
| type: "int", |
| default: "1784", |
| local: "true" |
| }, |
| { name: "Secret1Size", |
| desc: "Size of the SECRET1 partition", |
| type: "int", |
| default: "88", |
| local: "true" |
| }, |
| { name: "FlashAddrKeySeedOffset", |
| desc: "Offset of FLASH_ADDR_KEY_SEED", |
| type: "int", |
| default: "1784", |
| local: "true" |
| }, |
| { name: "FlashAddrKeySeedSize", |
| desc: "Size of FLASH_ADDR_KEY_SEED", |
| type: "int", |
| default: "32", |
| local: "true" |
| }, |
| { name: "FlashDataKeySeedOffset", |
| desc: "Offset of FLASH_DATA_KEY_SEED", |
| type: "int", |
| default: "1816", |
| local: "true" |
| }, |
| { name: "FlashDataKeySeedSize", |
| desc: "Size of FLASH_DATA_KEY_SEED", |
| type: "int", |
| default: "32", |
| local: "true" |
| }, |
| { name: "SramDataKeySeedOffset", |
| desc: "Offset of SRAM_DATA_KEY_SEED", |
| type: "int", |
| default: "1848", |
| local: "true" |
| }, |
| { name: "SramDataKeySeedSize", |
| desc: "Size of SRAM_DATA_KEY_SEED", |
| type: "int", |
| default: "16", |
| local: "true" |
| }, |
| { name: "Secret1DigestOffset", |
| desc: "Offset of SECRET1_DIGEST", |
| type: "int", |
| default: "1864", |
| local: "true" |
| }, |
| { name: "Secret1DigestSize", |
| desc: "Size of SECRET1_DIGEST", |
| type: "int", |
| default: "8", |
| local: "true" |
| }, |
| { name: "Secret2Offset", |
| desc: "Offset of the SECRET2 partition", |
| type: "int", |
| default: "1872", |
| local: "true" |
| }, |
| { name: "Secret2Size", |
| desc: "Size of the SECRET2 partition", |
| type: "int", |
| default: "88", |
| local: "true" |
| }, |
| { name: "RmaTokenOffset", |
| desc: "Offset of RMA_TOKEN", |
| type: "int", |
| default: "1872", |
| local: "true" |
| }, |
| { name: "RmaTokenSize", |
| desc: "Size of RMA_TOKEN", |
| type: "int", |
| default: "16", |
| local: "true" |
| }, |
| { name: "CreatorRootKeyShare0Offset", |
| desc: "Offset of CREATOR_ROOT_KEY_SHARE0", |
| type: "int", |
| default: "1888", |
| local: "true" |
| }, |
| { name: "CreatorRootKeyShare0Size", |
| desc: "Size of CREATOR_ROOT_KEY_SHARE0", |
| type: "int", |
| default: "32", |
| local: "true" |
| }, |
| { name: "CreatorRootKeyShare1Offset", |
| desc: "Offset of CREATOR_ROOT_KEY_SHARE1", |
| type: "int", |
| default: "1920", |
| local: "true" |
| }, |
| { name: "CreatorRootKeyShare1Size", |
| desc: "Size of CREATOR_ROOT_KEY_SHARE1", |
| type: "int", |
| default: "32", |
| local: "true" |
| }, |
| { name: "Secret2DigestOffset", |
| desc: "Offset of SECRET2_DIGEST", |
| type: "int", |
| default: "1952", |
| local: "true" |
| }, |
| { name: "Secret2DigestSize", |
| desc: "Size of SECRET2_DIGEST", |
| type: "int", |
| default: "8", |
| local: "true" |
| }, |
| { name: "LifeCycleOffset", |
| desc: "Offset of the LIFE_CYCLE partition", |
| type: "int", |
| default: "1960", |
| local: "true" |
| }, |
| { name: "LifeCycleSize", |
| desc: "Size of the LIFE_CYCLE partition", |
| type: "int", |
| default: "88", |
| local: "true" |
| }, |
| { name: "LcTransitionCntOffset", |
| desc: "Offset of LC_TRANSITION_CNT", |
| type: "int", |
| default: "1960", |
| local: "true" |
| }, |
| { name: "LcTransitionCntSize", |
| desc: "Size of LC_TRANSITION_CNT", |
| type: "int", |
| default: "48", |
| local: "true" |
| }, |
| { name: "LcStateOffset", |
| desc: "Offset of LC_STATE", |
| type: "int", |
| default: "2008", |
| local: "true" |
| }, |
| { name: "LcStateSize", |
| desc: "Size of LC_STATE", |
| type: "int", |
| default: "40", |
| local: "true" |
| }, |
| ] |
| |
| ///////////////////////////// |
| // Intermodule Connections // |
| ///////////////////////////// |
| |
| inter_signal_list: [ |
| // OTP dedicated power connection from AST |
| { struct: "" |
| type: "io" |
| name: "otp_ext_voltage_h" |
| act: "none" |
| default: "'0" |
| package: "", |
| } |
| // Power sequencing signals to AST |
| { struct: "otp_ast_req" |
| type: "uni" |
| name: "otp_ast_pwr_seq" |
| act: "req" |
| default: "'0" |
| package: "otp_ctrl_pkg" |
| } |
| // Power sequencing signals from AST |
| { struct: "otp_ast_rsp" |
| type: "uni" |
| name: "otp_ast_pwr_seq_h" |
| act: "rcv" |
| default: "'0" |
| package: "otp_ctrl_pkg" |
| } |
| // AST alert handling |
| { struct: "ast_dif" |
| type: "uni" |
| name: "otp_alert" |
| act: "req" |
| package: "ast_pkg" |
| } |
| // EDN interface |
| { struct: "edn" |
| type: "req_rsp" |
| name: "edn" |
| act: "req" |
| package: "edn_pkg" |
| } |
| // Power manager init command |
| { struct: "pwr_otp" |
| type: "req_rsp" |
| name: "pwr_otp" |
| act: "rsp" |
| default: "'0" |
| package: "pwrmgr_pkg" |
| } |
| // Macro-specific test signals to/from LC TAP |
| { struct: "lc_otp_vendor_test" |
| type: "req_rsp" |
| name: "lc_otp_vendor_test" |
| act: "rsp" |
| default: "'0" |
| package: "otp_ctrl_pkg" |
| } |
| // LC transition command |
| { struct: "lc_otp_program" |
| type: "req_rsp" |
| name: "lc_otp_program" |
| act: "rsp" |
| default: "'0" |
| package: "otp_ctrl_pkg" |
| } |
| // Broadcast to LC |
| { struct: "otp_lc_data" |
| type: "uni" |
| name: "otp_lc_data" |
| act: "req" |
| default: "'0" |
| package: "otp_ctrl_pkg" |
| } |
| // Broadcast from LC |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_escalate_en" |
| act: "rcv" |
| default: "lc_ctrl_pkg::Off" |
| package: "lc_ctrl_pkg" |
| } |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_creator_seed_sw_rw_en" |
| act: "rcv" |
| default: "lc_ctrl_pkg::Off" |
| package: "lc_ctrl_pkg" |
| } |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_seed_hw_rd_en" |
| act: "rcv" |
| default: "lc_ctrl_pkg::Off" |
| package: "lc_ctrl_pkg" |
| } |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_dft_en" |
| act: "rcv" |
| default: "lc_ctrl_pkg::Off" |
| package: "lc_ctrl_pkg" |
| } |
| { struct: "lc_tx" |
| type: "uni" |
| name: "lc_check_byp_en" |
| act: "rcv" |
| default: "lc_ctrl_pkg::Off" |
| package: "lc_ctrl_pkg" |
| } |
| // Broadcast to Key Manager |
| { struct: "otp_keymgr_key" |
| type: "uni" |
| name: "otp_keymgr_key" |
| act: "req" |
| default: "'0" |
| package: "otp_ctrl_pkg" |
| } |
| // Broadcast to Flash Controller |
| { struct: "flash_otp_key" |
| type: "req_rsp" |
| name: "flash_otp_key" |
| act: "rsp" |
| default: "'0" |
| package: "otp_ctrl_pkg" |
| } |
| // Key request from SRAM scramblers |
| { struct: "sram_otp_key" |
| // TODO: would be nice if this could accept parameters. |
| // Split this out into an issue. |
| width: "3" |
| type: "req_rsp" |
| name: "sram_otp_key" |
| act: "rsp" |
| default: "'0" |
| package: "otp_ctrl_pkg" |
| } |
| // Key request from OTBN RAM Scrambler |
| { struct: "otbn_otp_key" |
| type: "req_rsp" |
| name: "otbn_otp_key" |
| act: "rsp" |
| default: "'0" |
| package: "otp_ctrl_pkg" |
| } |
| // Hardware config partition |
| { struct: "otp_hw_cfg" |
| type: "uni" |
| name: "otp_hw_cfg" |
| act: "req" |
| default: "'0" |
| package: "otp_ctrl_part_pkg" |
| } |
| // AST observability control |
| { struct: "ast_obs_ctrl", |
| type: "uni", |
| name: "obs_ctrl", |
| act: "rcv", |
| package: "ast_pkg" |
| } |
| // prim otp observe bus |
| { struct: "logic", |
| type: "uni", |
| name: "otp_obs", |
| act: "req", |
| width: "8", |
| package: "" |
| } |
| ] // inter_signal_list |
| |
| ///////////////////// |
| // Countermeasures // |
| ///////////////////// |
| |
| countermeasures: [ |
| { name: "BUS.INTEGRITY", |
| desc: "End-to-end bus integrity scheme." |
| } |
| { name: "SECRET.MEM.SCRAMBLE", |
| desc: "Secret partitions are scrambled with a full-round PRESENT cipher." |
| } |
| { name: "PART.MEM.DIGEST", |
| desc: "Integrity of buffered partitions is ensured via a 64bit digest." |
| } |
| { name: "DAI.FSM.SPARSE", |
| desc: "The direct access interface FSM is sparsely encoded." |
| } |
| { name: "KDI.FSM.SPARSE", |
| desc: "The key derivation interface FSM is sparsely encoded." |
| } |
| { name: "LCI.FSM.SPARSE", |
| desc: "The life cycle interface FSM is sparsely encoded." |
| } |
| { name: "PART.FSM.SPARSE", |
| desc: "The partition FSMs are sparsely encoded." |
| } |
| { name: "SCRMBL.FSM.SPARSE", |
| desc: "The scramble datapath FSM is sparsely encoded." |
| } |
| { name: "TIMER.FSM.SPARSE", |
| desc: "The background check timer FSM is sparsely encoded." |
| } |
| { name: "DAI.CTR.REDUN", |
| desc: "The direct access interface address counter employs a cross-counter implementation." |
| } |
| { name: "KDI_SEED.CTR.REDUN", |
| desc: "The key derivation interface counter employs a cross-counter implementation." |
| } |
| { name: "KDI_ENTROPY.CTR.REDUN", |
| desc: "The key derivation entropy counter employs a cross-counter implementation." |
| } |
| { name: "LCI.CTR.REDUN", |
| desc: "The life cycle interface address counter employs a cross-counter implementation." |
| } |
| { name: "PART.CTR.REDUN", |
| desc: "The address counter of buffered partitions employs a cross-counter implementation." |
| } |
| { name: "SCRMBL.CTR.REDUN", |
| desc: "The srambling datapath counter employs a cross-counter implementation." |
| } |
| { name: "TIMER_INTEG.CTR.REDUN", |
| desc: "The background integrity check timer employs a duplicated counter implementation." |
| } |
| { name: "TIMER_CNSTY.CTR.REDUN", |
| desc: "The background consistency check timer employs a duplicated counter implementation." |
| } |
| { name: "TIMER.LFSR.REDUN", |
| desc: "The background check LFSR is duplicated." |
| } |
| { name: "DAI.FSM.LOCAL_ESC", |
| desc: "The direct access interface FSM is moved into an invalid state upon local escalation." |
| } |
| { name: "LCI.FSM.LOCAL_ESC", |
| desc: "The life cycle interface FSM is moved into an invalid state upon local escalation." |
| } |
| { name: "KDI.FSM.LOCAL_ESC", |
| desc: "The key derivation interface FSM is moved into an invalid state upon local escalation." |
| } |
| { name: "PART.FSM.LOCAL_ESC", |
| desc: "The partition FSMs are moved into an invalid state upon local escalation." |
| } |
| { name: "SCRMBL.FSM.LOCAL_ESC", |
| desc: "The scramble datapath FSM is moved into an invalid state upon local escalation." |
| } |
| { name: "TIMER.FSM.LOCAL_ESC", |
| desc: "The background check timer FSM is moved into an invalid state upon local escalation." |
| } |
| { name: "DAI.FSM.GLOBAL_ESC", |
| desc: "The direct access interface FSM is moved into an invalid state upon global escalation via life cycle." |
| } |
| { name: "LCI.FSM.GLOBAL_ESC", |
| desc: "The life cycle interface FSM is moved into an invalid state upon global escalation via life cycle." |
| } |
| { name: "KDI.FSM.GLOBAL_ESC", |
| desc: "The key derivation interface FSM is moved into an invalid state upon global escalation via life cycle." |
| } |
| { name: "PART.FSM.GLOBAL_ESC", |
| desc: "The partition FSMs are moved into an invalid state upon global escalation via life cycle." |
| } |
| { name: "SCRMBL.FSM.GLOBAL_ESC", |
| desc: "The scramble datapath FSM is moved into an invalid state upon global escalation via life cycle." |
| } |
| { name: "TIMER.FSM.GLOBAL_ESC", |
| desc: "The background check timer FSM is moved into an invalid state upon global escalation via life cycle." |
| } |
| { name: "PART.DATA_REG.INTEGRITY", |
| desc: "All partition buffer registers are protected with ECC on 64bit blocks." |
| } |
| { name: "PART.DATA_REG.BKGN_CHK", |
| desc: "The digest of buffered partitions is recomputed and checked at pseudorandom intervals in the background." |
| } |
| { name: "PART.MEM.REGREN" |
| desc: "Unbuffered ('software') partitions can be read-locked via a CSR until the next system reset." |
| } |
| { name: "PART.MEM.SW_UNREADABLE" |
| desc: "Secret buffered partitions become unreadable to software once they are locked via the digest." |
| } |
| { name: "PART.MEM.SW_UNWRITABLE" |
| desc: "All partitions become unwritable by software once they are locked via the digest." |
| } |
| { name: "LC_PART.MEM.SW_NOACCESS" |
| desc: "The life cycle partition is not directly readable nor writable via software." |
| } |
| { name: "ACCESS.CTRL.MUBI", |
| desc: "The access control signals going from the partitions to the DAI are MUBI encoded." |
| } |
| { name: "TOKEN_VALID.CTRL.MUBI", |
| desc: "The token valid signals going to the life cycle controller are MUBI encoded." |
| } |
| { name: "LC_CTRL.INTERSIG.MUBI", |
| desc: "The life cycle control signals are multibit encoded." |
| } |
| { name: "TEST.BUS.LC_GATED", |
| desc: "Prevent access to test signals and the OTP backdoor interface in non-test lifecycle states." |
| } |
| { name: "DIRECT_ACCESS.CONFIG.REGWEN", |
| desc: "The direct access CSRs are REGWEN protected." |
| } |
| { name: "CHECK_TRIGGER.CONFIG.REGWEN", |
| desc: "The check trigger CSR is REGWEN protected." |
| } |
| { name: "CHECK.CONFIG.REGWEN", |
| desc: "The check CSR is REGWEN protected." |
| } |
| { name: "MACRO.MEM.INTEGRITY", |
| desc: ''' |
| The OTP macro employs a vendor-specific integrity scheme at the granularity of the native 16bit OTP words. |
| The scheme is able to at least detect single bit errors. |
| ''' |
| } |
| { name: "MACRO.MEM.CM", |
| desc: "The OTP macro may contain additional vendor-specific countermeasures." |
| } |
| ] |
| |
| /////////////// |
| // Registers // |
| /////////////// |
| |
| regwidth: "32", |
| registers: { |
| core: [ |
| //////////////////////// |
| // Ctrl / Status CSRs // |
| //////////////////////// |
| |
| { name: "STATUS", |
| desc: "OTP status register.", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| resval: 0, |
| tags: [ // OTP internal HW can modify status register |
| "excl:CsrAllTests:CsrExclCheck"], |
| fields: [ |
| { bits: "0" |
| name: "VENDOR_TEST_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: "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: "2" |
| 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: "3" |
| 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: "4" |
| 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: "5" |
| 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: "6" |
| 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: "7" |
| 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: "8" |
| 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: "9" |
| 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: "10" |
| name: "TIMEOUT_ERROR" |
| desc: ''' |
| Set to 1 if an integrity or consistency check times out. |
| This raises an fatal_check_error alert and is an unrecoverable error condition. |
| ''' |
| } |
| { bits: "11" |
| name: "LFSR_FSM_ERROR" |
| desc: ''' |
| Set to 1 if the LFSR timer FSM has reached an invalid state. |
| This raises an fatal_check_error alert and is an unrecoverable error condition. |
| ''' |
| } |
| { bits: "12" |
| name: "SCRAMBLING_FSM_ERROR" |
| desc: ''' |
| Set to 1 if the scrambling datapath FSM has reached an invalid state. |
| This raises an fatal_check_error alert and is an unrecoverable error condition. |
| ''' |
| } |
| { bits: "13" |
| name: "KEY_DERIV_FSM_ERROR" |
| desc: ''' |
| Set to 1 if the key derivation FSM has reached an invalid state. |
| This raises an fatal_check_error alert and is an unrecoverable error condition. |
| ''' |
| } |
| { bits: "14" |
| name: "BUS_INTEG_ERROR" |
| desc: ''' |
| This bit is set to 1 if a fatal bus integrity fault is detected. |
| This error triggers a fatal_bus_integ_error alert. |
| ''' |
| } |
| { bits: "15" |
| name: "DAI_IDLE" |
| desc: "Set to 1 if the DAI is idle and ready to accept commands." |
| } |
| { bits: "16" |
| 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 about error conditions that occurred in the agents |
| interacting with the OTP macro via the internal bus. The error codes should be checked |
| if the partitions, DAI or LCI flag an error in the !!STATUS register, 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 fatal_macro_error or an |
| fatal_check_error alert. |
| ''', |
| count: "NumErrorEntries", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| cname: "AGENT", |
| resval: 0, |
| tags: [ // OTP internal HW can modify the error code registers |
| "excl:CsrAllTests:CsrExclCheck"], |
| fields: [ |
| { |
| bits: "2:0" |
| enum: [ |
| { value: "0", |
| name: "NO_ERROR", |
| desc: ''' |
| No error condition has occurred. |
| ''' |
| }, |
| { value: "1", |
| name: "MACRO_ERROR", |
| desc: ''' |
| Returned if the OTP macro command was invalid or did not complete successfully |
| due to a macro malfunction. |
| This error should never occur during normal operation and is not recoverable. |
| This error triggers an fatal_macro_error alert. |
| ''' |
| }, |
| { value: "2", |
| name: "MACRO_ECC_CORR_ERROR", |
| desc: ''' |
| A correctable ECC error has occured during an OTP read operation. |
| The corresponding controller automatically recovers from this error when |
| issuing a new command. |
| ''' |
| }, |
| { value: "3", |
| name: "MACRO_ECC_UNCORR_ERROR", |
| desc: ''' |
| An uncorrectable ECC 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 fatal_macro_error alert. |
| ''' |
| }, |
| { value: "4", |
| name: "MACRO_WRITE_BLANK_ERROR", |
| desc: ''' |
| This error is returned if a programming operation attempted to clear a bit that has previously been programmed to 1. |
| The corresponding controller automatically recovers from this error when issuing a new command. |
| |
| Note however that the affected OTP word may be left in an inconsistent state if this error occurs. |
| 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. |
| ''' |
| }, |
| { value: "5", |
| name: "ACCESS_ERROR", |
| 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: "6", |
| name: "CHECK_FAIL_ERROR", |
| desc: ''' |
| An ECC, integrity or consistency mismatch has been detected in the buffer registers. |
| This error should never occur during normal operation and is not recoverable. |
| This error triggers an fatal_check_error alert. |
| ''' |
| }, |
| { value: "7", |
| name: "FSM_STATE_ERROR", |
| desc: ''' |
| The FSM of the corresponding controller has reached an invalid state, or the FSM has |
| been moved into a terminal error state due to an escalation action via lc_escalate_en_i. |
| 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 |
| an invasive attack. This error triggers an fatal_check_error alert. |
| ''' |
| }, |
| ] |
| } |
| ] |
| } |
| } |
| { name: "DIRECT_ACCESS_REGWEN", |
| desc: ''' |
| Register write enable for all direct access interface registers. |
| ''', |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| tags: [ // OTP internal HW will set this enable register to 0 when OTP is not under IDLE |
| // state, so could not auto-predict its value |
| "excl:CsrNonInitTests:CsrExclCheck"], |
| 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", |
| resval: 0, |
| regwen: "DIRECT_ACCESS_REGWEN", |
| tags: [ // Write to DIRECT_ACCESS_CMD randomly might cause OTP_ERRORs and illegal sequences |
| "excl:CsrNonInitTests:CsrExclWrite"], |
| fields: [ |
| { bits: "0", |
| name: "RD", |
| 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: "WR", |
| 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", |
| resval: 0, |
| regwen: "DIRECT_ACCESS_REGWEN", |
| tags: [ // The enable register "DIRECT_ACCESS_REGWEN" is HW controlled, |
| // so not able to predict this register value automatically |
| "excl:CsrNonInitTests:CsrExclCheck"], |
| 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 partition base offset. |
| ''' |
| } |
| ] |
| } |
| { 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", |
| resval: 0, |
| tags: [ // The value of this register is written from "DIRECT_ACCESS_RDATA", |
| // so could not predict this register value automatically |
| "excl:CsrAllTests:CsrExclCheck"], |
| 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", |
| resval: 0, |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| |
| ////////////////////////////////////// |
| // Integrity and Consistency Checks // |
| ////////////////////////////////////// |
| { name: "CHECK_TRIGGER_REGWEN", |
| desc: ''' |
| Register write enable for !!CHECK_TRIGGER. |
| ''', |
| swaccess: "rw0c", |
| hwaccess: "none", |
| fields: [ |
| { bits: "0", |
| desc: ''' |
| When cleared to 0, the !!CHECK_TRIGGER register cannot be written anymore. |
| Write 0 to clear this bit. |
| ''' |
| resval: 1, |
| }, |
| ] |
| }, |
| { name: "CHECK_TRIGGER", |
| desc: "Command register for direct accesses.", |
| swaccess: "r0w1c", |
| hwaccess: "hro", |
| hwqe: "true", |
| hwext: "true", |
| resval: 0, |
| 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: "rw0c", |
| hwaccess: "none", |
| fields: [ |
| { bits: "0", |
| desc: ''' |
| When cleared to 0, !!INTEGRITY_CHECK_PERIOD and !!CONSISTENCY_CHECK_PERIOD registers cannot be written anymore. |
| Write 0 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", |
| tags: [ // Do not write to this automatically, as it may trigger fatal alert, and cause |
| // escalation. TODO: check with designer if the trigger escalation part is intended. |
| "excl:CsrAllTests:CsrExclWrite"], |
| 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 fatal_check_error 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: "VENDOR_TEST_READ_LOCK", |
| desc: ''' |
| Runtime read lock for the VENDOR_TEST partition. |
| ''', |
| swaccess: "rw0c", |
| hwaccess: "hro", |
| regwen: "DIRECT_ACCESS_REGWEN", |
| tags: [ // The value of this register can affect the read access of the this |
| // partition's memory window. Excluding this register from writing can ensure |
| // memories have read and write access. |
| "excl:CsrNonInitTests:CsrExclWrite"], |
| fields: [ |
| { bits: "0", |
| desc: ''' |
| When cleared to 0, read access to the VENDOR_TEST partition is locked. |
| Write 0 to clear this bit. |
| ''' |
| resval: 1, |
| }, |
| ] |
| }, |
| { name: "CREATOR_SW_CFG_READ_LOCK", |
| desc: ''' |
| Runtime read lock for the CREATOR_SW_CFG partition. |
| ''', |
| swaccess: "rw0c", |
| hwaccess: "hro", |
| regwen: "DIRECT_ACCESS_REGWEN", |
| tags: [ // The value of this register can affect the read access of the this |
| // partition's memory window. Excluding this register from writing can ensure |
| // memories have read and write access. |
| "excl:CsrNonInitTests:CsrExclWrite"], |
| fields: [ |
| { bits: "0", |
| desc: ''' |
| When cleared to 0, read access to the CREATOR_SW_CFG partition is locked. |
| Write 0 to clear this bit. |
| ''' |
| resval: 1, |
| }, |
| ] |
| }, |
| { name: "OWNER_SW_CFG_READ_LOCK", |
| desc: ''' |
| Runtime read lock for the OWNER_SW_CFG partition. |
| ''', |
| swaccess: "rw0c", |
| hwaccess: "hro", |
| regwen: "DIRECT_ACCESS_REGWEN", |
| tags: [ // The value of this register can affect the read access of the this |
| // partition's memory window. Excluding this register from writing can ensure |
| // memories have read and write access. |
| "excl:CsrNonInitTests:CsrExclWrite"], |
| fields: [ |
| { bits: "0", |
| desc: ''' |
| When cleared to 0, read access to the OWNER_SW_CFG partition is locked. |
| Write 0 to clear this bit. |
| ''' |
| resval: 1, |
| }, |
| ] |
| }, |
| |
| /////////////////////// |
| // Integrity Digests // |
| /////////////////////// |
| { multireg: { |
| name: "VENDOR_TEST_DIGEST", |
| desc: ''' |
| Integrity digest for the VENDOR_TEST 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 VENDOR_TEST partition is locked and |
| the digest becomes visible in this CSR. |
| ''', |
| count: "NumDigestWords", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| cname: "WORD", |
| resval: 0, |
| tags: [ // OTP internal HW will update status so can not auto-predict its value. |
| "excl:CsrAllTests:CsrExclCheck"], |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| { multireg: { |
| name: "CREATOR_SW_CFG_DIGEST", |
| desc: ''' |
| Integrity digest for the CREATOR_SW_CFG 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 CREATOR_SW_CFG partition is locked and |
| the digest becomes visible in this CSR. |
| ''', |
| count: "NumDigestWords", |
| swaccess: "ro", |
| hwaccess: "hwo", |
| hwext: "true", |
| cname: "WORD", |
| resval: 0, |
| tags: [ // OTP internal HW will update status so can not auto-predict its value. |
| "excl:CsrAllTests:CsrExclCheck"], |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| { multireg: { |
| name: "OWNER_SW_CFG_DIGEST", |
| desc: ''' |
| Integrity digest for the OWNER_SW_CFG 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", |
| resval: 0, |
| tags: [ // OTP internal HW will update status so can not auto-predict its value. |
| "excl:CsrAllTests:CsrExclCheck"], |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| { multireg: { |
| name: "HW_CFG_DIGEST", |
| desc: ''' |
| Integrity digest for the HW_CFG 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", |
| resval: 0, |
| tags: [ // OTP internal HW will update status so can not auto-predict its value. |
| "excl:CsrAllTests:CsrExclCheck"], |
| 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", |
| resval: 0, |
| tags: [ // OTP internal HW will update status so can not auto-predict its value. |
| "excl:CsrAllTests:CsrExclCheck"], |
| 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", |
| resval: 0, |
| tags: [ // OTP internal HW will update status so can not auto-predict its value. |
| "excl:CsrAllTests:CsrExclCheck"], |
| 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", |
| resval: 0, |
| tags: [ // OTP internal HW will update status so can not auto-predict its value. |
| "excl:CsrAllTests:CsrExclCheck"], |
| fields: [ |
| { bits: "31:0" |
| } |
| ] |
| } |
| }, |
| |
| //////////////////////////////// |
| // Software Config Partitions // |
| //////////////////////////////// |
| { skipto: "0x1000" } |
| |
| { window: { |
| name: "SW_CFG_WINDOW" |
| items: "NumSwCfgWindowWords" |
| swaccess: "ro", |
| desc: ''' |
| Any read to this window directly maps to the corresponding offset in the creator and owner software |
| config partitions, and triggers an OTP readout of the bytes requested. Note that the transaction |
| will block until OTP readout has completed. |
| ''' |
| } |
| } |
| ], |
| |
| // OTP wrapper-specific registers |
| prim: [ |
| { name: "CSR0", |
| desc: "" |
| swaccess: "rw", |
| hwaccess: "hro", |
| hwext: "false", |
| hwqe: "false", |
| // TODO: remove this tag once chip-level sims support alias registers. |
| tags: [ |
| "excl:CsrAllTests:CsrExclAll" |
| ] |
| fields: [ |
| { bits: "0", |
| name: "field0", |
| desc: "", |
| resval: "0x0", |
| } |
| { bits: "1", |
| name: "field1", |
| desc: "", |
| resval: "0x0", |
| } |
| { bits: "2", |
| name: "field2", |
| desc: "", |
| resval: "0x0", |
| } |
| { bits: "13:4", |
| name: "field3", |
| desc: "" |
| resval: "0x0", |
| } |
| { bits: "26:16", |
| name: "field4", |
| desc: "" |
| resval: "0x0", |
| } |
| ] |
| }, |
| { name: "CSR1", |
| desc: "" |
| swaccess: "rw", |
| hwaccess: "hro", |
| hwext: "false", |
| hwqe: "false", |
| // TODO: remove this tag once chip-level sims support alias registers. |
| tags: [ |
| "excl:CsrAllTests:CsrExclAll" |
| ] |
| fields: [ |
| { bits: "6:0", |
| name: "field0", |
| desc: "" |
| resval: "0x0", |
| } |
| { bits: "7:7", |
| name: "field1", |
| desc: "", |
| resval: "0x0", |
| } |
| { bits: "14:8", |
| name: "field2", |
| desc: "" |
| resval: "0x0", |
| } |
| { bits: "15:15", |
| name: "field3", |
| desc: "", |
| resval: "0x0", |
| } |
| { bits: "31:16", |
| name: "field4", |
| desc: "", |
| resval: "0x0", |
| } |
| ] |
| }, |
| { name: "CSR2", |
| desc: "" |
| swaccess: "rw", |
| hwaccess: "hro", |
| hwext: "false", |
| hwqe: "false", |
| // TODO: remove this tag once chip-level sims support alias registers. |
| tags: [ |
| "excl:CsrAllTests:CsrExclAll" |
| ] |
| fields: [ |
| { bits: "0", |
| name: "field0", |
| desc: "", |
| resval: "0x0", |
| } |
| ] |
| }, |
| { name: "CSR3", |
| desc: "" |
| swaccess: "rw", |
| hwaccess: "hrw", |
| hwext: "false", |
| hwqe: "false", |
| // TODO: remove this tag once chip-level sims support alias registers. |
| tags: [ |
| "excl:CsrAllTests:CsrExclAll" |
| ] |
| fields: [ |
| { bits: "2:0", |
| name: "field0", |
| desc: "" |
| swaccess: "rw1c", |
| resval: "0x0", |
| } |
| { bits: "13:4", |
| name: "field1", |
| desc: "", |
| swaccess: "rw1c", |
| resval: "0x0", |
| } |
| { bits: "16", |
| name: "field2", |
| desc: "", |
| swaccess: "rw1c", |
| resval: "0x0", |
| } |
| { bits: "17", |
| name: "field3", |
| desc: "", |
| swaccess: "rw1c", |
| resval: "0x0", |
| } |
| { bits: "18", |
| name: "field4", |
| desc: "", |
| swaccess: "rw1c", |
| resval: "0x0", |
| } |
| { bits: "19", |
| name: "field5", |
| desc: "", |
| swaccess: "rw1c", |
| resval: "0x0", |
| } |
| { bits: "20", |
| name: "field6", |
| desc: "", |
| swaccess: "rw1c", |
| resval: "0x0", |
| } |
| { bits: "21", |
| name: "field7", |
| desc: "", |
| swaccess: "rw1c", |
| resval: "0x0", |
| } |
| { bits: "22", |
| name: "field8", |
| desc: "", |
| swaccess: "rw1c", |
| resval: "0x0", |
| } |
| ] |
| }, |
| { name: "CSR4", |
| desc: "" |
| swaccess: "rw", |
| hwaccess: "hro", |
| hwext: "false", |
| hwqe: "false", |
| // TODO: remove this tag once chip-level sims support alias registers. |
| tags: [ |
| "excl:CsrAllTests:CsrExclAll" |
| ] |
| fields: [ |
| { bits: "9:0", |
| name: "field0", |
| desc: "" |
| resval: "0x0", |
| } |
| { bits: "12", |
| name: "field1", |
| desc: "" |
| resval: "0x0", |
| } |
| { bits: "13", |
| name: "field2", |
| desc: "" |
| resval: "0x0", |
| } |
| { bits: "14", |
| name: "field3", |
| desc: "" |
| resval: "0x0", |
| } |
| ] |
| }, |
| { name: "CSR5", |
| desc: "" |
| swaccess: "rw", |
| hwaccess: "hrw", |
| hwext: "false", |
| hwqe: "false", |
| // TODO: remove this tag once chip-level sims support alias registers. |
| tags: [ |
| "excl:CsrAllTests:CsrExclAll" |
| ] |
| fields: [ |
| { bits: "5:0", |
| name: "field0", |
| desc: "" |
| swaccess: "rw", |
| resval: "0x0", |
| } |
| { bits: "7:6", |
| name: "field1", |
| desc: "" |
| swaccess: "rw", |
| resval: "0x0", |
| } |
| { bits: "8", |
| name: "field2", |
| desc: "", |
| swaccess: "ro", |
| resval: "0x0", |
| } |
| { bits: "11:9", |
| name: "field3", |
| desc: "" |
| swaccess: "ro", |
| resval: "0x0", |
| } |
| { bits: "12", |
| name: "field4", |
| desc: "" |
| swaccess: "ro", |
| resval: "0x0", |
| } |
| { bits: "13", |
| name: "field5", |
| desc: "" |
| swaccess: "ro", |
| resval: "0x0", |
| } |
| { bits: "31:16", |
| name: "field6", |
| desc: "" |
| swaccess: "rw", |
| resval: "0x0", |
| } |
| ] |
| }, |
| { name: "CSR6", |
| desc: "" |
| swaccess: "rw", |
| hwaccess: "hro", |
| hwext: "false", |
| hwqe: "false", |
| // TODO: remove this tag once chip-level sims support alias registers. |
| tags: [ |
| "excl:CsrAllTests:CsrExclAll" |
| ] |
| fields: [ |
| { bits: "9:0", |
| name: "field0", |
| desc: "" |
| resval: "0x0", |
| } |
| { bits: "11", |
| name: "field1", |
| desc: "", |
| swaccess: "rw", |
| resval: "0x0", |
| } |
| { bits: "12", |
| name: "field2", |
| desc: "", |
| swaccess: "rw", |
| resval: "0x0", |
| } |
| { bits: "31:16", |
| name: "field3", |
| desc: "" |
| resval: "0x0", |
| } |
| ] |
| }, |
| { name: "CSR7", |
| desc: "", |
| swaccess: "ro", |
| hwaccess: "hrw", |
| hwext: "false", |
| hwqe: "false", |
| // TODO: remove this tag once chip-level sims support alias registers. |
| tags: [ |
| "excl:CsrAllTests:CsrExclAll" |
| ] |
| fields: [ |
| { bits: "5:0", |
| name: "field0", |
| desc: "" |
| swaccess: "ro", |
| resval: "0x0", |
| } |
| { bits: "10:8", |
| name: "field1", |
| desc: "", |
| swaccess: "ro", |
| resval: "0x0", |
| } |
| { bits: "14", |
| name: "field2", |
| desc: "", |
| swaccess: "ro", |
| resval: "0x0", |
| } |
| { bits: "15", |
| name: "field3", |
| desc: "", |
| swaccess: "ro", |
| resval: "0x0", |
| } |
| ] |
| }, |
| ] |
| } |
| } |