From 4e27ed473c1189d2af1384a60e6c435cca11d42e Mon Sep 17 00:00:00 2001 From: Jamin Lin Date: Thu, 12 Jan 2023 11:15:08 +0800 Subject: [PATCH] AFM: fix recovery failed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root Cause: Move AFM firmware update code from ast1060_update to “update_afm and update_afm_image” API. Solution: Change to call update_afm API to do AFM recovery if AFM active is bad Change to set AFM SVN policy only if users update recovery region. Test: Destroy the AFM active data AST1060: 1. flash erase fmc_cs0 f0000 2. reboot expected result: AFM active should be repaired. ``` aspeed_state_machine.do_recovery: Start [00:00:07.932,000] pfr: Image Type: AFM [00:00:07.932,000] pfr: Active Data Corrupted [00:00:08.573,000] pfr: Repair success ``` Signed-off-by: Jamin Lin Change-Id: I1665e3416397d9cdc24e6142749ade4a76ffd2a6 --- .../src/intel_pfr/intel_pfr_recovery.c | 23 +++++++++++--- .../src/intel_pfr/intel_pfr_update.c | 30 +++++++++---------- .../src/intel_pfr/intel_pfr_update.h | 12 ++++++++ apps/aspeed-pfr/src/pfr/pfr_recovery.c | 1 - 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.c index b8be833..bda25df 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.c @@ -23,6 +23,7 @@ #include "flash/flash_util.h" #include "Smbus_mailbox/Smbus_mailbox.h" #include "intel_pfr_svn.h" +#include "intel_pfr_update.h" LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); @@ -185,14 +186,28 @@ int pfr_recover_active_region(struct pfr_manifest *manifest) } #if defined(CONFIG_PFR_SPDM_ATTESTATION) else if (manifest->image_type == AFM_TYPE) { - manifest->image_type = BMC_TYPE; manifest->address = CONFIG_BMC_AFM_RECOVERY_OFFSET; - return ast1060_update(manifest); + manifest->image_type = BMC_TYPE; + if (pfr_spi_read(manifest->image_type, manifest->address, + sizeof(PFR_AUTHENTICATION_BLOCK0), buffer)) { + LOG_ERR("Block0: Flash read data failed"); + return Failure; + } + + block0_buffer = (PFR_AUTHENTICATION_BLOCK0 *)buffer; + manifest->pc_length = block0_buffer->PcLength; + manifest->address += PFM_SIG_BLOCK_SIZE; + + LOG_INF("AFM update start payload_address=%08x pc_length=%x", manifest->address, manifest->pc_length); + if (update_afm(AFM_PART_ACT_1, manifest->address, manifest->pc_length)) + return Failure; + + LOG_INF("Repair success"); + return Success; } #endif - else { + else return Failure; - } manifest->recovery_address = read_address; manifest->staging_address = staging_address; diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.c index feb81df..695f92a 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.c @@ -266,14 +266,6 @@ int update_rot_fw(uint32_t address, uint32_t length) } #if defined(CONFIG_PFR_SPDM_ATTESTATION) -enum AFM_PARTITION_TYPE { - AFM_PART_ACT_1, - AFM_PART_RCV_1, - // Reserved for Intel PFR 4.0 - AFM_PART_ACT_2, - AFM_PART_RCV_2, -}; - int update_afm(enum AFM_PARTITION_TYPE part, uint32_t address, size_t length) { uint32_t region_size = pfr_spi_get_device_size(ROT_INTERNAL_AFM); @@ -284,6 +276,11 @@ int update_afm(enum AFM_PARTITION_TYPE part, uint32_t address, size_t length) (length % PAGE_SIZE) ? (length + (PAGE_SIZE - (length % PAGE_SIZE))) : length; if (part == AFM_PART_ACT_1) { + if (length_page_align > region_size) { + LOG_ERR("length(%x) exceed region size(%x)", length_page_align, region_size); + return Failure; + } + if (pfr_spi_erase_region(ROT_INTERNAL_AFM, true, 0, region_size)) { LOG_ERR("Failed to erase AFM Active Partition"); return Failure; @@ -321,7 +318,6 @@ int update_afm_image(struct pfr_manifest *manifest, uint32_t flash_select, void { AO_DATA *ActiveObjectData = (AO_DATA *) AoData; uint32_t payload_address; - uint32_t pc_type_status; uint32_t pc_length = 0; uint32_t hrot_svn = 0; uint32_t pc_type; @@ -372,6 +368,10 @@ int update_afm_image(struct pfr_manifest *manifest, uint32_t flash_select, void } status = update_afm(AFM_PART_ACT_1, payload_address, pc_length); + if (status != Success) { + LOG_ERR("Update AFM Active failed"); + return Failure; + } } else if (flash_select == SECONDARY_FLASH_REGION) { if (ActiveObjectData->RestrictActiveUpdate == 1) { manifest->image_type = AFM_TYPE; @@ -382,15 +382,15 @@ int update_afm_image(struct pfr_manifest *manifest, uint32_t flash_select, void } } - status = update_afm(AFM_PART_RCV_1, payload_address, 64*1024 /*pc_length*/); - } + status = update_afm(AFM_PART_RCV_1, payload_address, pc_length); + if (status != Success) { + LOG_ERR("Update AFM Recovery failed"); + return Failure; + } - if (status != Success) { - LOG_ERR("Update AFM failed"); - return Failure; + set_ufm_svn(SVN_POLICY_FOR_AFM, hrot_svn); } - set_ufm_svn(SVN_POLICY_FOR_AFM, hrot_svn); LOG_INF("AFM update end"); return Success; diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.h b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.h index e09af02..7dda9c6 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.h @@ -8,6 +8,18 @@ #include +#if defined(CONFIG_PFR_SPDM_ATTESTATION) +enum AFM_PARTITION_TYPE { + AFM_PART_ACT_1, + AFM_PART_RCV_1, + // Reserved for Intel PFR 4.0 + AFM_PART_ACT_2, + AFM_PART_RCV_2, +}; + +int update_afm(enum AFM_PARTITION_TYPE part, uint32_t address, size_t length); +#endif + int intel_pfr_update_verify(struct firmware_image *fw, struct hash_engine *hash, struct rsa_engine *rsa); int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext); diff --git a/apps/aspeed-pfr/src/pfr/pfr_recovery.c b/apps/aspeed-pfr/src/pfr/pfr_recovery.c index 81143d5..4da1716 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_recovery.c +++ b/apps/aspeed-pfr/src/pfr/pfr_recovery.c @@ -42,7 +42,6 @@ int recover_image(void *AoData, void *EventContext) if (EventData->image == BMC_EVENT) { LOG_INF("Image Type: BMC"); pfr_manifest->image_type = BMC_TYPE; - } else if (EventData->image == PCH_EVENT) { LOG_INF("Image Type: PCH"); pfr_manifest->image_type = PCH_TYPE;