From db8a61121158bc54944c94d13f320807bf77636a Mon Sep 17 00:00:00 2001 From: Anthony Chen Date: Mon, 21 Oct 2024 16:59:20 +0800 Subject: [PATCH] [manuf] Delay IMMUTABLE_ROM_EXT_EN provisioning to end of perso This separates the provisioning of the IMMUTABLE_ROM_EXT_EN OTP field from the rest of the CREATOR_SW_CFG partition. This is necessary because the personalization firmware doesn't include an immutable ROM_EXT section. Enabling immutable ROM_EXT earlier would prevent the personalization from being executed. This also builds personalization firmware using the ROM_EXT immutable section OTP gen tool by default. Signed-off-by: Anthony Chen --- hw/ip/otp_ctrl/data/earlgrey_skus/prodc/BUILD | 16 ++++++++++ hw/ip/otp_ctrl/data/earlgrey_skus/sival/BUILD | 16 ++++++++++ hw/ip/otp_ctrl/data/otp_ctrl_img.c.tpl | 1 + .../manuf/base/ft_personalize.c | 1 + .../manuf/lib/individualize_sw_cfg.c | 29 +++++++++++++++++++ .../manuf/lib/individualize_sw_cfg.h | 16 ++++++++++ .../manuf/lib/individualize_sw_cfg_functest.c | 2 ++ 7 files changed, 81 insertions(+) diff --git a/hw/ip/otp_ctrl/data/earlgrey_skus/prodc/BUILD b/hw/ip/otp_ctrl/data/earlgrey_skus/prodc/BUILD index 1e5beb48eefd01..7327cf83e037e3 100644 --- a/hw/ip/otp_ctrl/data/earlgrey_skus/prodc/BUILD +++ b/hw/ip/otp_ctrl/data/earlgrey_skus/prodc/BUILD @@ -22,6 +22,7 @@ load( "otp_image", "otp_image_consts", "otp_json", + "otp_json_immutable_rom_ext", "otp_partition", "otp_per_class_bytes", "otp_per_class_ints", @@ -202,6 +203,20 @@ otp_json( ], ) +otp_json_immutable_rom_ext( + name = "otp_json_immutable_rom_ext", + partitions = [ + otp_partition( + name = "CREATOR_SW_CFG", + items = { + "CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN": otp_hex(CONST.HARDENED_FALSE), + }, + ), + ], + rom_ext = "//sw/device/silicon_creator/rom_ext/sival:rom_ext_fake_prod_signed_slot_b", + visibility = ["//visibility:private"], +) + # Create an overlay for the alert_handler digest. otp_alert_digest( name = "alert_digest_cfg", @@ -294,6 +309,7 @@ MANUF_SW_INITIALIZED = [ ":alert_digest_cfg", ":otp_json_creator_sw_cfg", ":otp_json_owner_sw_cfg", + ":otp_json_immutable_rom_ext", ] # The `MANUF_INDIVIDUALIZED` OTP profile configures the HW_CFG0/1, CREATOR_SW and diff --git a/hw/ip/otp_ctrl/data/earlgrey_skus/sival/BUILD b/hw/ip/otp_ctrl/data/earlgrey_skus/sival/BUILD index f52092b530d11f..b19d2e07bde31a 100644 --- a/hw/ip/otp_ctrl/data/earlgrey_skus/sival/BUILD +++ b/hw/ip/otp_ctrl/data/earlgrey_skus/sival/BUILD @@ -22,6 +22,7 @@ load( "otp_image", "otp_image_consts", "otp_json", + "otp_json_immutable_rom_ext", "otp_partition", "otp_per_class_bytes", "otp_per_class_ints", @@ -201,6 +202,20 @@ otp_json( ], ) +otp_json_immutable_rom_ext( + name = "otp_json_immutable_rom_ext", + partitions = [ + otp_partition( + name = "CREATOR_SW_CFG", + items = { + "CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN": otp_hex(CONST.HARDENED_FALSE), + }, + ), + ], + rom_ext = "//sw/device/silicon_creator/rom_ext/sival:rom_ext_fake_prod_signed_slot_b", + visibility = ["//visibility:private"], +) + # Create an overlay for the alert_handler digest. otp_alert_digest( name = "alert_digest_cfg", @@ -307,6 +322,7 @@ MANUF_SW_INITIALIZED = [ ":alert_digest_cfg", ":otp_json_creator_sw_cfg", ":otp_json_owner_sw_cfg", + ":otp_json_immutable_rom_ext", ] # The `MANUF_INDIVIDUALIZED` OTP profile configures the HW_CFG0/1, CREATOR_SW and diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_img.c.tpl b/hw/ip/otp_ctrl/data/otp_ctrl_img.c.tpl index 8f5afb61867a6d..334f2761182078 100644 --- a/hw/ip/otp_ctrl/data/otp_ctrl_img.c.tpl +++ b/hw/ip/otp_ctrl/data/otp_ctrl_img.c.tpl @@ -65,6 +65,7 @@ ${fileheader} base_declaration = f"const {type_str} {ToConstLabelValue(item['name'])}" if item['name'] not in [ + 'CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN', 'CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG', 'CREATOR_SW_CFG_MANUF_STATE', 'OWNER_SW_CFG_ROM_BOOTSTRAP_DIS', diff --git a/sw/device/silicon_creator/manuf/base/ft_personalize.c b/sw/device/silicon_creator/manuf/base/ft_personalize.c index 4d6e6e904c5748..5dc8789b6fcd07 100644 --- a/sw/device/silicon_creator/manuf/base/ft_personalize.c +++ b/sw/device/silicon_creator/manuf/base/ft_personalize.c @@ -685,6 +685,7 @@ static status_t finalize_otp_partitions(void) { // Complete the provisioning of OTP CreatorSwCfg partition. if (!status_ok(manuf_individualize_device_creator_sw_cfg_check(&otp_ctrl))) { TRY(manuf_individualize_device_creator_manuf_state_cfg(&otp_ctrl)); + TRY(manuf_individualize_device_immutable_rom_ext_en_cfg(&otp_ctrl)); TRY(manuf_individualize_device_creator_sw_cfg_lock(&otp_ctrl)); } TRY(check_otp_measurement(&otp_creator_sw_cfg_measurement, diff --git a/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.c b/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.c index d5a543b0650a96..6b2d184367b77f 100644 --- a/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.c +++ b/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.c @@ -63,6 +63,13 @@ static status_t otp_img_write(const dif_otp_ctrl_t *otp, // state, so once the manufacturing state is provisioned, the // personalization firmware can't be re-entrant. // + // We skip the provisioning of the immutable ROM_EXT enablement + // configuration as it must be provisioned only at the end of the + // personalization flow. The personalization firmware doesn't include an + // immutable ROM_EXT section. Enabling this feature with personalization + // firmware would result in ROM self-shutdown due to an invalid immutable + // ROM extension hash. + // // We also skip the provisioning of the ROM bootstrap disablement // configuration. This should only be disabled after all bootstrap // operations in the personalization flow have been completed. @@ -73,6 +80,8 @@ static status_t otp_img_write(const dif_otp_ctrl_t *otp, if (kv[i].offset == OTP_CTRL_PARAM_CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG_OFFSET || kv[i].offset == OTP_CTRL_PARAM_CREATOR_SW_CFG_MANUF_STATE_OFFSET || + kv[i].offset == + OTP_CTRL_PARAM_CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN_OFFSET || kv[i].offset == OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_BOOTSTRAP_DIS_OFFSET || (kv[i].offset >= kValidAstCfgOtpAddrLow && kv[i].offset < kInvalidAstCfgOtpAddrHigh)) { @@ -122,6 +131,10 @@ static status_t otp_img_expected_value_read(dif_otp_ctrl_partition_t partition, memcpy(buffer + relative_addr, &kCreatorSwCfgManufStateValue, sizeof(uint32_t)); break; + case OTP_CTRL_PARAM_CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN_OFFSET: + memcpy(buffer + relative_addr, &kCreatorSwCfgImmutableRomExtEnValue, + sizeof(uint32_t)); + break; default: return INTERNAL(); } @@ -272,6 +285,19 @@ status_t manuf_individualize_device_creator_manuf_state_cfg( return OK_STATUS(); } +status_t manuf_individualize_device_immutable_rom_ext_en_cfg( + const dif_otp_ctrl_t *otp_ctrl) { + uint32_t offset; + TRY(dif_otp_ctrl_relative_address( + kDifOtpCtrlPartitionCreatorSwCfg, + OTP_CTRL_PARAM_CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN_OFFSET, &offset)); + TRY(otp_ctrl_testutils_dai_write32(otp_ctrl, kDifOtpCtrlPartitionCreatorSwCfg, + offset, + &kCreatorSwCfgImmutableRomExtEnValue, + /*len=*/1)); + return OK_STATUS(); +} + status_t manuf_individualize_device_creator_sw_cfg_lock( const dif_otp_ctrl_t *otp_ctrl) { TRY(lock_otp_partition(otp_ctrl, kDifOtpCtrlPartitionCreatorSwCfg)); @@ -316,6 +342,9 @@ status_t manuf_individualize_device_partition_expected_read( case kDifOtpCtrlPartitionCreatorSwCfg: TRY(otp_img_expected_value_read( partition, OTP_CTRL_PARAM_CREATOR_SW_CFG_MANUF_STATE_OFFSET, buffer)); + TRY(otp_img_expected_value_read( + partition, OTP_CTRL_PARAM_CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN_OFFSET, + buffer)); break; default: return INTERNAL(); diff --git a/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.h b/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.h index e0d4593284353c..e4380f96b5b0ba 100644 --- a/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.h +++ b/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.h @@ -17,6 +17,7 @@ extern const size_t kOtpKvCreatorSwCfgSize; extern const otp_kv_t kOtpKvCreatorSwCfg[]; extern const uint32_t kCreatorSwCfgFlashDataDefaultCfgValue; extern const uint32_t kCreatorSwCfgManufStateValue; +extern const uint32_t kCreatorSwCfgImmutableRomExtEnValue; /** * OTP Owner Software Configuration Partition. @@ -85,6 +86,21 @@ OT_WARN_UNUSED_RESULT status_t manuf_individualize_device_creator_manuf_state_cfg( const dif_otp_ctrl_t *otp_ctrl); +/** + * Configures the IMMUTABLE_ROM_EXT_EN field in the CREATOR_SW_CFG OTP + * partition. + * + * This must be called before `manuf_individualize_device_creator_sw_cfg_lock()` + * is called. The operation will fail if there are any pre-programmed words not + * equal to the expected test values. + * + * @param otp_ctrl OTP controller instance. + * @return OK_STATUS if the IMMUTABLE_ROM_EXT_EN field was provisioned. + */ +OT_WARN_UNUSED_RESULT +status_t manuf_individualize_device_immutable_rom_ext_en_cfg( + const dif_otp_ctrl_t *otp_ctrl); + /** * Checks the FLASH_DATA_DEFAULT_CFG field in the CREATOR_SW_CFG OTP * partition. diff --git a/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg_functest.c b/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg_functest.c index 76b6e06499729b..a87e4d62f62c97 100644 --- a/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg_functest.c +++ b/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg_functest.c @@ -131,6 +131,8 @@ bool test_main(void) { manuf_individualize_device_flash_data_default_cfg(&otp_ctrl)); CHECK_STATUS_OK( manuf_individualize_device_creator_manuf_state_cfg(&otp_ctrl)); + CHECK_STATUS_OK( + manuf_individualize_device_immutable_rom_ext_en_cfg(&otp_ctrl)); CHECK_STATUS_OK(manuf_individualize_device_creator_sw_cfg_lock(&otp_ctrl)); CHECK_STATUS_OK(check_otp_ast_cfg()); LOG_INFO("Provisioned and locked CREATOR_SW_CFG OTP partition.");