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 0046132d3617f..8f5afb61867a6 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,11 @@ ${fileheader} raise f"Invalid alignment: {alignment}" base_declaration = f"const {type_str} {ToConstLabelValue(item['name'])}" - if item["name"] not in ["CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG", "OWNER_SW_CFG_ROM_BOOTSTRAP_DIS"]: + if item['name'] not in [ + 'CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG', + 'CREATOR_SW_CFG_MANUF_STATE', + '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 e27056d654764..9a12ee81c5c9c 100644 --- a/sw/device/silicon_creator/manuf/base/ft_personalize.c +++ b/sw/device/silicon_creator/manuf/base/ft_personalize.c @@ -684,6 +684,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_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 aef4aac613a26..d5a543b0650a9 100644 --- a/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.c +++ b/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.c @@ -57,6 +57,12 @@ 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 skip the provisioning of the creator manufacturing status as it must + // be provisioned only at the end of the personalization flow. The + // personalization firmware is bound with the INITIAL (empty) manufacturing + // state, so once the manufacturing state is provisioned, the + // personalization firmware can't be re-entrant. + // // 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. @@ -66,6 +72,7 @@ static status_t otp_img_write(const dif_otp_ctrl_t *otp, // 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_CREATOR_SW_CFG_MANUF_STATE_OFFSET || kv[i].offset == OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_BOOTSTRAP_DIS_OFFSET || (kv[i].offset >= kValidAstCfgOtpAddrLow && kv[i].offset < kInvalidAstCfgOtpAddrHigh)) { @@ -111,6 +118,10 @@ static status_t otp_img_expected_value_read(dif_otp_ctrl_partition_t partition, memcpy(buffer + relative_addr, &kOwnerSwCfgRomBootstrapDisValue, sizeof(uint32_t)); break; + case OTP_CTRL_PARAM_CREATOR_SW_CFG_MANUF_STATE_OFFSET: + memcpy(buffer + relative_addr, &kCreatorSwCfgManufStateValue, + sizeof(uint32_t)); + break; default: return INTERNAL(); } @@ -249,6 +260,18 @@ status_t manuf_individualize_device_flash_data_default_cfg_check( return is_provisioned ? OK_STATUS() : INTERNAL(); } +status_t manuf_individualize_device_creator_manuf_state_cfg( + const dif_otp_ctrl_t *otp_ctrl) { + uint32_t offset; + TRY(dif_otp_ctrl_relative_address( + kDifOtpCtrlPartitionCreatorSwCfg, + OTP_CTRL_PARAM_CREATOR_SW_CFG_MANUF_STATE_OFFSET, &offset)); + TRY(otp_ctrl_testutils_dai_write32(otp_ctrl, kDifOtpCtrlPartitionCreatorSwCfg, + offset, &kCreatorSwCfgManufStateValue, + /*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)); @@ -291,6 +314,8 @@ status_t manuf_individualize_device_partition_expected_read( buffer)); break; case kDifOtpCtrlPartitionCreatorSwCfg: + TRY(otp_img_expected_value_read( + partition, OTP_CTRL_PARAM_CREATOR_SW_CFG_MANUF_STATE_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 4b6e6eca7d3ae..e0d4593284353 100644 --- a/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.h +++ b/sw/device/silicon_creator/manuf/lib/individualize_sw_cfg.h @@ -16,6 +16,7 @@ extern const size_t kOtpKvCreatorSwCfgSize; extern const otp_kv_t kOtpKvCreatorSwCfg[]; extern const uint32_t kCreatorSwCfgFlashDataDefaultCfgValue; +extern const uint32_t kCreatorSwCfgManufStateValue; /** * OTP Owner Software Configuration Partition. @@ -37,11 +38,12 @@ extern const uint32_t kOwnerSwCfgRomBootstrapDisValue; * - The operation will fail if there are any pre-programmed words not equal * to the expected test values. * - This operation will explicitly NOT provision the FLASH_DATA_DEFAULT_CFG - * field in the CREATOR_SW_CFG partition. This field must be explicitly - * configured after all other provisioning operations are done, but before the - * partition is locked, and the final transport image is loaded. + * and MANUF_STATE fields in the CREATOR_SW_CFG partition. These fields must + * be explicitly configured after all other provisioning operations are done, + * but before the partition is locked, and the final transport image is loaded. * - This function will NOT lock the partition either. This must be done after - * provisioning the final FLASH_DATA_DEFAULT_CFG filed mentioned above. + * provisioning the final FLASH_DATA_DEFAULT_CFG and MANUF_STATE fields + * mentioned above. * - The partition must be configured and the chip reset, before the ROM can be * booted, thus enabling bootstrap. * @@ -68,6 +70,21 @@ OT_WARN_UNUSED_RESULT status_t manuf_individualize_device_flash_data_default_cfg( const dif_otp_ctrl_t *otp_ctrl); +/** + * Configures the MANUF_STATE 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 MANUF_STATE field was provisioned. + */ +OT_WARN_UNUSED_RESULT +status_t manuf_individualize_device_creator_manuf_state_cfg( + const dif_otp_ctrl_t *otp_ctrl); + /** * Checks the FLASH_DATA_DEFAULT_CFG field in the CREATOR_SW_CFG OTP * partition. @@ -83,7 +100,8 @@ status_t manuf_individualize_device_flash_data_default_cfg_check( * Locks the CREATOR_SW_CFG OTP partition. * * This must be called after both `manuf_individualize_device_creator_sw_cfg()` - * and `manuf_individualize_device_flash_data_default_cfg()` have been called. + * , `manuf_individualize_device_flash_data_default_cfg()` and + * `manuf_individualize_device_creator_manuf_state_cfg()` have been called. * * @param otp_ctrl OTP controller instance. * @return OK_STATUS if the CREATOR_SW_CFG partition was locked. @@ -107,12 +125,15 @@ status_t manuf_individualize_device_creator_sw_cfg_check( * The OWNER_SW_CFG partition contains additional settings for the ROM and * ROM_EXT, for example: * - Alert handler configuration - * - ROM bootstrap disablement * - ROM_EXT bootstrap enablement * * Note: - * - The operation will fail if there are any pre-programmed words not equal to - * the expected test values. + * - The operation will fail if there are any pre-programmed words not equal to + * the expected test values. + * - This operation will explicitly NOT provision the ROM_BOOTSTRAP_DIS + * field in the OWNER_SW_CFG partition. This field must be explicitly + * configured after all other provisioning operations are done, but before the + * partition is locked, and the final transport image is loaded. * * @param otp_ctrl OTP controller instance. * @return OK_STATUS if the HW_CFG0 partition is locked. 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 80ff8c7ae461f..76b6e06499729 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,8 @@ bool test_main(void) { &otp_ctrl, &flash_ctrl_state)); CHECK_STATUS_OK( 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_creator_sw_cfg_lock(&otp_ctrl)); CHECK_STATUS_OK(check_otp_ast_cfg()); LOG_INFO("Provisioned and locked CREATOR_SW_CFG OTP partition.");