Update full FW update status structure on recovery

This change makes sure that, during each recovery,
the FW update status structure is cleared and
repopulated

Without this change, in the event that there is
a full recovery and then an interrupted recovery,
the interrupted recovery is unable to resume

Signed-off-by: Sean McGinn <sean.mcginn@intel.com>
This commit is contained in:
Sean McGinn 2022-08-11 11:16:22 -07:00 committed by Guo Dong
parent ffa3f9935d
commit 1e677e5a4d
3 changed files with 56 additions and 7 deletions

View File

@ -64,8 +64,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define FW_UPDATE_COMP_DEFAULT_ORDER 4
#define FW_UPDATE_STATUS_SIGNATURE SIGNATURE_32 ('F', 'W', 'U', 'S')
#define FW_UPDATE_STATUS_VERSION 0x1
#define FW_UPDATE_STATUS_SIGNATURE SIGNATURE_32 ('F', 'W', 'U', 'S')
#define FW_RECOVERY_STATUS_SIGNATURE SIGNATURE_32 ('F', 'W', 'R', 'S')
#define FW_UPDATE_STATUS_VERSION 0x1
///
/// "FWST" Firmware Update status data Table

View File

@ -341,7 +341,7 @@ GetStateMachineFlag (
/**
Set state machine flag in flash.
This function will set state machine flag in the bootloader reserved region
This function will set state machine flag (via bitwise AND) in the bootloader reserved region
First byte in the booloader reserved region is state machine flag
----------------------------------------------------------------------------------------
@ -1429,6 +1429,54 @@ InitFirmwareUpdate (
return EFI_SUCCESS;
}
/**
Initialize FW update status region for recovery.
@retval EFI_SUCCESS The operation completed successfully.
@retval others There is error happening.
**/
EFI_STATUS
InitFwUpdStatusForRecovery (
VOID
)
{
EFI_STATUS Status;
UINT32 FwUpdStatusOffset;
FW_UPDATE_STATUS FwUpdStatus;
UINT8 StateMachine;
FwUpdStatusOffset = PcdGet32(PcdFwUpdStatusBase);
GetStateMachineFlag (&StateMachine);
if (StateMachine != FW_UPDATE_SM_RECOVERY) {
// Set up the initial reserved region structure
FwUpdStatus.Signature = FW_RECOVERY_STATUS_SIGNATURE;
FwUpdStatus.Version = FW_UPDATE_STATUS_VERSION;
FwUpdStatus.Length = sizeof(FW_UPDATE_STATUS);
ZeroMem (&FwUpdStatus.CapsuleSig, sizeof(FwUpdStatus.CapsuleSig));
FwUpdStatus.StateMachine = FW_UPDATE_SM_RECOVERY;
FwUpdStatus.RetryCount = 0;
FwUpdStatus.CsmeNeedReset = CSME_NEED_RESET_INIT;
// Clear the reserved region structure, if not already null bytes
if (StateMachine != FW_UPDATE_SM_INIT) {
Status = BootMediaErase (FwUpdStatusOffset, EFI_PAGE_SIZE);
if (EFI_ERROR (Status)) {
DEBUG((DEBUG_ERROR, "BootMediaErase failed with status %r\n", Status));
return Status;
}
}
// Write the reserved region structure
Status = BootMediaWrite (FwUpdStatusOffset, sizeof(FW_UPDATE_STATUS), (UINT8 *)&FwUpdStatus);
if (EFI_ERROR(Status)) {
DEBUG((DEBUG_ERROR, "BootMediaWrite failed with status %r\n", Status));
return Status;
}
}
return EFI_SUCCESS;
}
/**
Try to recover a working boot partition.
@ -1438,7 +1486,7 @@ InitFirmwareUpdate (
EFI_STATUS
InitFirmwareRecovery (
VOID
)
)
{
FLASH_MAP *FlashMap;
EFI_STATUS Status;
@ -1462,9 +1510,9 @@ InitFirmwareRecovery (
RomBase = (UINT32) (0x100000000ULL - FlashMap->RomSize);
Status = SetStateMachineFlag (FW_UPDATE_SM_RECOVERY);
Status = InitFwUpdStatusForRecovery ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "SetStateMachineFlag, Status = 0x%x\n", Status));
DEBUG ((DEBUG_ERROR, "InitFwUpdStatusForRecovery, Status = 0x%x\n", Status));
return Status;
}

View File

@ -281,7 +281,7 @@ CheckStateMachine (
// firmare update process, continue doing firmware update
// If Bit 3 of State Machine is 0, SM is set to Done. Rest of the bits are ignored while checking for Done state.
//
if (pFwUpdStatus->Signature == FW_UPDATE_STATUS_SIGNATURE) {
if ((pFwUpdStatus->Signature == FW_UPDATE_STATUS_SIGNATURE) || (pFwUpdStatus->Signature == FW_RECOVERY_STATUS_SIGNATURE)) {
if ((pFwUpdStatus->StateMachine != FW_UPDATE_SM_INIT) && (pFwUpdStatus->StateMachine & BIT3)) {
DEBUG((DEBUG_ERROR, "State Machine set to processing mode, triggering firmware update\n"));
return EFI_SUCCESS;