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 7da66c2c58cb9..0046132d3617f 100644 --- a/hw/ip/otp_ctrl/data/otp_ctrl_img.c.tpl +++ b/hw/ip/otp_ctrl/data/otp_ctrl_img.c.tpl @@ -64,7 +64,7 @@ ${fileheader} raise f"Invalid alignment: {alignment}" base_declaration = f"const {type_str} {ToConstLabelValue(item['name'])}" - if item["name"] != "CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG": + if item["name"] not in ["CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG", "OWNER_SW_CFG_ROM_BOOTSTRAP_DIS"]: base_declaration = "static " + base_declaration if item["num_items"] == 1: diff --git a/sw/device/silicon_creator/manuf/base/ft_personalize.c b/sw/device/silicon_creator/manuf/base/ft_personalize.c index 23a4af3d3e266..6de14079110c5 100644 --- a/sw/device/silicon_creator/manuf/base/ft_personalize.c +++ b/sw/device/silicon_creator/manuf/base/ft_personalize.c @@ -179,6 +179,13 @@ static status_t personalize_otp_and_flash_secrets(ujson_t *uj) { wait_for_interrupt(); } + // The last bootstrap process in the perso flow is done. + // Complete the provisioning of OTP OwnerSwCfg partition. + if (!status_ok(manuf_individualize_device_owner_sw_cfg_check(&otp_ctrl))) { + TRY(manuf_individualize_device_rom_bootstrap_dis_cfg(&otp_ctrl)); + TRY(manuf_individualize_device_owner_sw_cfg_lock(&otp_ctrl)); + } + // Provision OTP Secret2 partition and flash info pages 1, 2, and 4 (keymgr // and DICE keygen seeds). if (!status_ok(manuf_personalize_device_secrets_check(&otp_ctrl))) { diff --git a/sw/device/silicon_creator/manuf/base/sram_ft_individualize.c b/sw/device/silicon_creator/manuf/base/sram_ft_individualize.c index 0ad96e7a61af1..dfb619dced0f9 100644 --- a/sw/device/silicon_creator/manuf/base/sram_ft_individualize.c +++ b/sw/device/silicon_creator/manuf/base/sram_ft_individualize.c @@ -85,7 +85,9 @@ static status_t print_flash_info_0_data_to_console(void) { * * Note: CreatorSwCfg partition is not locked yet, as the flash scrambling OTP * field is not provisioned until after the Secret1 partition is provisioned - * during personalization. + * during personalization. OwnerSwCfg partition is also not locked yet, as the + * bootstrap disablement OTP field is not provisioned until the last bootstrap + * operation is done in the personalization flow. */ static status_t provision(ujson_t *uj) { LOG_INFO("Waiting for FT SRAM provisioning data ..."); diff --git a/sw/device/silicon_creator/manuf/lib/BUILD b/sw/device/silicon_creator/manuf/lib/BUILD index 2b64482d603f3..b7f2ad7c02fe4 100644 --- a/sw/device/silicon_creator/manuf/lib/BUILD +++ b/sw/device/silicon_creator/manuf/lib/BUILD @@ -204,6 +204,7 @@ opentitan_test( srcs = ["individualize_sw_cfg_functest.c"], exec_env = { "//hw/top_earlgrey:fpga_hyper310_rom_with_fake_keys": None, + "//hw/top_earlgrey:fpga_cw340_rom_with_fake_keys": None, }, fpga = fpga_params( changes_otp = True, 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 a3896706534f7..009dba5e72e46 100644 --- a/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.c +++ b/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.c @@ -52,11 +52,16 @@ static status_t otp_img_write(const dif_otp_ctrl_t *otp, // immediately before the transport image is loaded, after all other // provisioning is complete. // + // 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. + // // Additionally, we skip the provisioning of the AST configuration data, as // this should already be written to a flash info page. We will pull the // data directly from there. if (kv[i].offset == OTP_CTRL_PARAM_CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG_OFFSET || + kv[i].offset == OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_BOOTSTRAP_DIS_OFFSET || (kv[i].offset >= kValidAstCfgOtpAddrLow && kv[i].offset < kInvalidAstCfgOtpAddrHigh)) { continue; @@ -194,6 +199,23 @@ status_t manuf_individualize_device_owner_sw_cfg( const dif_otp_ctrl_t *otp_ctrl) { TRY(otp_img_write(otp_ctrl, kDifOtpCtrlPartitionOwnerSwCfg, kOtpKvOwnerSwCfg, kOtpKvOwnerSwCfgSize)); + return OK_STATUS(); +} + +status_t manuf_individualize_device_rom_bootstrap_dis_cfg( + const dif_otp_ctrl_t *otp_ctrl) { + uint32_t offset; + TRY(dif_otp_ctrl_relative_address( + kDifOtpCtrlPartitionOwnerSwCfg, + OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_BOOTSTRAP_DIS_OFFSET, &offset)); + TRY(otp_ctrl_testutils_dai_write32(otp_ctrl, kDifOtpCtrlPartitionOwnerSwCfg, + offset, &kOwnerSwCfgRomBootstrapDisValue, + /*len=*/1)); + return OK_STATUS(); +} + +status_t manuf_individualize_device_owner_sw_cfg_lock( + const dif_otp_ctrl_t *otp_ctrl) { TRY(lock_otp_partition(otp_ctrl, kDifOtpCtrlPartitionOwnerSwCfg)); return OK_STATUS(); } 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 d9d06dab1a5da..6fe8fcd0d2006 100644 --- a/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.h +++ b/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.h @@ -22,6 +22,7 @@ extern const uint32_t kCreatorSwCfgFlashDataDefaultCfgValue; */ extern const size_t kOtpKvOwnerSwCfgSize; extern const otp_kv_t kOtpKvOwnerSwCfg[]; +extern const uint32_t kOwnerSwCfgRomBootstrapDisValue; /** * Configures the CREATOR_SW_CFG OTP partition. @@ -101,7 +102,6 @@ status_t manuf_individualize_device_creator_sw_cfg_check( * Note: * - The operation will fail if there are any pre-programmed words not equal to * the expected test values. - * - The operation will lock the OWNER_SW_CFG OTP partition. * * @param otp_ctrl OTP controller instance. * @return OK_STATUS if the HW_CFG0 partition is locked. @@ -110,6 +110,34 @@ OT_WARN_UNUSED_RESULT status_t manuf_individualize_device_owner_sw_cfg( const dif_otp_ctrl_t *otp_ctrl); +/** + * Configures the ROM_BOOTSTRAP_DIS field in the OWNER_SW_CFG OTP + * partition. + * + * This must be called before `manuf_individualize_device_owner_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 ROM_BOOTSTRAP_DIS field was provisioned. + */ +OT_WARN_UNUSED_RESULT +status_t manuf_individualize_device_rom_bootstrap_dis_cfg( + const dif_otp_ctrl_t *otp_ctrl); + +/** + * Locks the OWNER_SW_CFG OTP partition. + * + * This must be called after both `manuf_individualize_device_owner_sw_cfg()` + * and `manuf_individualize_device_rom_bootstrap_dis_cfg()` have been called. + * + * @param otp_ctrl OTP controller instance. + * @return OK_STATUS if the OWNER_SW_CFG partition was locked. + */ +OT_WARN_UNUSED_RESULT +status_t manuf_individualize_device_owner_sw_cfg_lock( + const dif_otp_ctrl_t *otp_ctrl); + /** * Checks the OWNER_SW_CFG OTP partition end state. * 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 c5fe8f91e8771..69ca9965482b4 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 @@ -129,6 +129,9 @@ bool test_main(void) { if (!status_ok(manuf_individualize_device_owner_sw_cfg_check(&otp_ctrl))) { CHECK_STATUS_OK(manuf_individualize_device_owner_sw_cfg(&otp_ctrl)); + CHECK_STATUS_OK( + manuf_individualize_device_rom_bootstrap_dis_cfg(&otp_ctrl)); + CHECK_STATUS_OK(manuf_individualize_device_owner_sw_cfg_lock(&otp_ctrl)); LOG_INFO("Provisioned and locked OWNER_SW_CFG OTP partition."); // Perform SW reset to complete locking of the OWNER_SW_CFG partition. sw_reset();