alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/Recovery/MeUpdateFaultToleranceDxe/MeUpdateFaultToleranceDxe.c

1531 lines
48 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2020 - 2021, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
/** @file
ME Resiliency init Dxe driver.
@copyright
INTEL CONFIDENTIAL
Copyright 2020 Intel Corporation.
The source code contained or described herein and all documents related to the
source code ("Material") are owned by Intel Corporation or its suppliers or
licensors. Title to the Material remains with Intel Corporation or its suppliers
and licensors. The Material may contain trade secrets and proprietary and
confidential information of Intel Corporation and its suppliers and licensors,
and is protected by worldwide copyright and trade secret laws and treaty
provisions. No part of the Material may be used, copied, reproduced, modified,
published, uploaded, posted, transmitted, distributed, or disclosed in any way
without Intel's prior express written permission.
No license under any patent, copyright, trade secret or other intellectual
property right is granted to or conferred upon you by disclosure or delivery
of the Materials, either expressly, by implication, inducement, estoppel or
otherwise. Any license under such intellectual property rights must be
express and approved by Intel in writing.
Unless otherwise agreed by Intel in writing, you may not remove or alter
this notice or any other notice embedded in Materials by Intel or
Intel's suppliers or licensors in any way.
This file contains a 'Sample Driver' and is licensed as such under the terms
of your license agreement with Intel or your vendor. This file may be modified
by the user, subject to the additional terms of the license agreement.
@par Specification Reference:
**/
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PciSegmentLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Protocol/FirmwareManagement.h>
//[-start-201112-IB16810138-remove]//
//#include <Protocol/PlatformSpecificResetFilter.h>
//[-end-201112-IB16810138-remove]//
#include <Register/HeciRegs.h>
#include <Register/MeRegs.h>
//[-start-201112-IB16810138-remove]//
//#include <Library/SeamlessRecoverySupportLib.h>
//#include <PchResetPlatformSpecific.h>
//[-end-201112-IB16810138-remove]//
//[-start-201112-IB16810138-add]//
#include <Library/H2OCpLib.h>
#include <Library/VariableLib.h>
//[-end-201112-IB16810138-add]//
//[-start-201112-IB16810138-add]//
#include <Library/CapsuleUpdateCriteriaLib.h>
#include <Library/BaseCryptLib.h>
#include <Uefi.h>
#include <Uefi/UefiSpec.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/DevicePath.h>
#include <Library/DevicePathLib.h>
#include <Guid/FileSystemInfo.h>
#include <Guid/FileInfo.h>
#include <Guid/SysFwUpdateProgress.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <SecureFlash.h>
#include <Library/UefiLib.h>
#define MAX_BOOT_OPTIONS 128
#define SHA256_DIGEST_HASH_SIZE 0x20
#define EFI_CAPSULE_FILE_PATH L"EFI\\UpdateCapsule"
#define EFI_CAPSULE_FILE_NAME L"CapsuleUpdateFile"
STATIC UINT8 InsydeBiosSignature[] = {'$', '_', 'I', 'F', 'L', 'A', 'S', 'H', '_', 'B', 'I', 'O', 'S', 'I', 'M', 'G'};
STATIC UINT8 InsydeMeSig[] = {'_', 'M', 'E', '_','I', 'M', 'G', '_'};
EFI_STATUS
GetFwUpdateInfo (
OUT SYSTEM_FIRMWARE_COMPONENT *Component
)
{
EFI_STATUS Status;
UINTN DataSize;
SYSTEM_FIRMWARE_COMPONENT TempComponent;
DataSize = sizeof (SYSTEM_FIRMWARE_COMPONENT);
Status = CommonGetVariable (
FW_UPDATEINFO_VARIABLE_NAME,
&gSysFwUpdateProgressGuid,
&DataSize,
&TempComponent
);
if (EFI_ERROR (Status)) {
return Status;
}
CopyMem (Component, &TempComponent, sizeof (SYSTEM_FIRMWARE_COMPONENT));
return EFI_SUCCESS;
}
EFI_STATUS
SetFwUpdateInfo (
IN SYSTEM_FIRMWARE_COMPONENT *Component
)
{
return SetVariableToSensitiveVariable (
FW_UPDATEINFO_VARIABLE_NAME,
&gSysFwUpdateProgressGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (SYSTEM_FIRMWARE_COMPONENT),
Component
);
}
VOID
ClearFwUpdateInfo (
VOID
)
{
SetVariableToSensitiveVariable (
FW_UPDATEINFO_VARIABLE_NAME,
&gSysFwUpdateProgressGuid,
0,
0,
NULL
);
}
/**
Dump raw data.
@param[in] Data raw data
@param[in] Size raw data size
**/
VOID
InternalDumpData (
IN UINT8 *Data8,
IN UINTN DataSize
)
{
DEBUG_CODE_BEGIN();
UINTN Index;
for (Index = 0; Index < DataSize; Index++) {
if (Index % 0x10 == 0) {
DEBUG ((DEBUG_INFO, "\n%08X:", Index));
}
DEBUG ((DEBUG_INFO, " %02X", *Data8++));
}
DEBUG ((DEBUG_INFO, "\n"));
DEBUG_CODE_END();
}
/**
Calculate SHA256 Hash
@param[in] Data data
@param[in] Size data size
@param[out] Digest SHA256 digest
**/
VOID
CreateSha256Hash (
IN UINT8 *Data,
IN UINTN Size,
OUT UINT8 *Digest
)
{
UINTN CtxSize;
VOID *HashCtx;
CtxSize = Sha256GetContextSize ();
HashCtx = AllocatePool (CtxSize);
ASSERT (HashCtx != NULL);
Sha256Init (HashCtx);
Sha256Update (HashCtx, Data, Size);
Sha256Final (HashCtx, Digest);
InternalDumpData (Digest, 32);
FreePool (HashCtx);
}
/**
Check if root file system has capsule image file or not.
@param[in] SysRootHandle A pointer to a file handle.
@retval TRUE It has the capsule image file.
@retval FALSE It does not has the capsule image file.
**/
STATIC
BOOLEAN
HaveCapsuleImageFile (
IN EFI_FILE_HANDLE SysRootHandle
)
{
EFI_STATUS Status;
EFI_FILE_HANDLE CapsuleHandle;
UINTN FileInfoSize;
EFI_FILE_INFO *FileInfo;
UINTN FileSize;
BOOLEAN Result;
if (SysRootHandle == NULL) {
return FALSE;
}
Status = SysRootHandle->Open (
SysRootHandle,
&CapsuleHandle,
EFI_CAPSULE_FILE_PATH,
EFI_FILE_MODE_READ,
EFI_FILE_DIRECTORY
);
if (EFI_ERROR (Status)) {
return FALSE;
}
Result = FALSE;
FileInfo = NULL;
FileInfoSize = 0;
Status = CapsuleHandle->GetInfo (CapsuleHandle, &gEfiFileInfoGuid, &FileInfoSize, NULL);
if (Status != EFI_BUFFER_TOO_SMALL) {
goto Exit;
}
FileInfo = AllocatePool (FileInfoSize);
if (FileInfo == NULL) {
goto Exit;
}
Status = CapsuleHandle->GetInfo (CapsuleHandle,&gEfiFileInfoGuid, &FileInfoSize, (VOID *) FileInfo);
if (EFI_ERROR (Status) || FileInfo->FileSize == 0) {
goto Exit;
}
FileInfoSize = (UINTN) FileInfo->FileSize;
FreePool (FileInfo);
FileInfo = AllocatePool (FileInfoSize);
if (FileInfo == NULL) {
goto Exit;
}
while (TRUE) {
FileSize = FileInfoSize;
Status = CapsuleHandle->Read (
CapsuleHandle,
&FileSize,
(VOID *) FileInfo
);
if (EFI_ERROR (Status) || FileSize == 0) {
break;
}
if (FileInfo->FileSize > 0 &&
((FileInfo->Attribute & EFI_FILE_DIRECTORY) != EFI_FILE_DIRECTORY) &&
StrnCmp (FileInfo->FileName, EFI_CAPSULE_FILE_NAME, sizeof (EFI_CAPSULE_FILE_NAME) / sizeof (CHAR16) - 1) == 0) {
Result = TRUE;
break;
}
}
Exit:
CapsuleHandle->Close (CapsuleHandle);
if (FileInfo != NULL) {
FreePool (FileInfo);
}
return Result;
}
/**
Get the offset of the boot loader file path from system partition for the boot
device path of the current boot option
@param[in] BootDevicePath The device path of the boot option
@param[out] BootFilePathOffset The offset from the boot device path of the boot
loader file path
@retval EFI_SUCCESS The BootFilePathOffset is correctly set
@return Others Unable to get boot file path offset
**/
STATIC
EFI_STATUS
GetBootFilePathDevicePathOffset (
IN EFI_DEVICE_PATH_PROTOCOL *BootDevicePath,
OUT UINTN *BootFilePathDevicePathOffset
)
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_STATUS Status;
if (BootDevicePath == NULL || BootFilePathDevicePathOffset == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = EFI_NOT_FOUND;
DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)BootDevicePath;
while (!IsDevicePathEnd(DevicePath)) {
if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
(DevicePathSubType (DevicePath) == MEDIA_FILEPATH_DP)) {
*BootFilePathDevicePathOffset = (UINTN)((UINT8 *)DevicePath - (UINT8 *)BootDevicePath);
Status = EFI_SUCCESS;
break;
}
DevicePath = NextDevicePathNode (DevicePath);
}
return Status;
}
/**
Get the information of system drive which contain capsule image file from all simple file system instances.
@param[out] SysRootDevicePath The pointer of system root device path pointer
@param[out] SysRoorHandle The pointer of EFI_FILE_HANDLE of system drive
@retval EFI_SUCCESS The system drive information is correctly get
@return Others Unable to get system drive information
**/
STATIC
EFI_STATUS
GetSystemRootInfoFromFileSystems (
OUT EFI_DEVICE_PATH **SysRootDevicePath,
OUT EFI_FILE_HANDLE *SysRootHandle
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
UINTN NumberOfHandles;
UINTN Index;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
EFI_FILE_HANDLE RootHandle;
EFI_DEVICE_PATH *DevicePath;
if (SysRootDevicePath == NULL || SysRootHandle == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleFileSystemProtocolGuid,
NULL,
&NumberOfHandles,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return Status;
}
for (Index = 0; Index < NumberOfHandles; Index++) {
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **) &SimpleFileSystem);
if (EFI_ERROR (Status)) {
continue;
}
Status = SimpleFileSystem->OpenVolume (SimpleFileSystem, &RootHandle);
if (EFI_ERROR (Status)) {
continue;
}
Status = gBS->HandleProtocol(HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath);
if (EFI_ERROR (Status)) {
RootHandle->Close (RootHandle);
continue;
}
*SysRootDevicePath = DevicePath;
*SysRootHandle = RootHandle;
break;
}
FreePool (HandleBuffer);
return (Index < NumberOfHandles) ? EFI_SUCCESS : EFI_NOT_FOUND;
}
/**
Get the system drive information through the boot loader file path under system partition
@param[out] SysRootDevicePath The pointer of system root device path pointer
@param[out] SysRoorHandle The pointer of EFI_FILE_HANDLE of system drive
@retval EFI_SUCCESS The system drive information is correctly get
@return Others Unable to get system drive information
**/
STATIC
EFI_STATUS
GetSystemRootInfoFromCurrentBootOption (
OUT EFI_DEVICE_PATH **SysRootDevicePath,
OUT EFI_FILE_HANDLE *SysRootHandle
)
{
EFI_STATUS Status;
UINTN TotalBootOptions;
UINT16 BootOptions[MAX_BOOT_OPTIONS];
UINTN Size;
CHAR16 BootOption[] = L"Boot0000";
UINT8 *BootOptionData;
CHAR16 *BootOptionDesc;
EFI_DEVICE_PATH_PROTOCOL *BootDevicePath;
UINTN BootFilePathDevicePathOffset;
UINTN CompareSize;
BOOLEAN Found;
EFI_HANDLE *HandleBuffer;
UINTN NumberOfHandles;
UINTN CurrentOption;
UINTN Index;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
if (SysRootDevicePath == NULL || SysRootHandle == NULL) {
return EFI_INVALID_PARAMETER;
}
TotalBootOptions = 0;
Status = EFI_NOT_FOUND;
Size = sizeof(UINT16);
Status = CommonGetVariable (
L"BootNext",
&gEfiGlobalVariableGuid,
&Size,
&BootOptions[0]
);
if (!EFI_ERROR (Status)) {
TotalBootOptions ++;
}
Size = sizeof(UINT16) * (MAX_BOOT_OPTIONS - TotalBootOptions);
Status = CommonGetVariable (
L"BootOrder",
&gEfiGlobalVariableGuid,
&Size,
&BootOptions[TotalBootOptions]
);
if (EFI_ERROR (Status) && TotalBootOptions == 0) {
return Status;
}
TotalBootOptions += (Size / sizeof(UINT16));
for (CurrentOption = 0, Found = FALSE, Status = EFI_NOT_FOUND; CurrentOption < TotalBootOptions && !Found; CurrentOption ++) {
UnicodeSPrint (BootOption, sizeof(BootOption), L"Boot%04x", BootOptions[CurrentOption]);
BootOptionData = CommonGetVariableData (BootOption, &gEfiGlobalVariableGuid);
if (BootOptionData == NULL) {
continue;
}
//
// Get the boot loader file path from the current Boot Option data
//
BootOptionDesc = (CHAR16 *)(BootOptionData + sizeof(UINT32) + sizeof(UINT16));
BootDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)(BootOptionData + sizeof(UINT32) + sizeof(UINT16) + StrSize(BootOptionDesc));
Status = GetBootFilePathDevicePathOffset (BootDevicePath, &BootFilePathDevicePathOffset);
if (Status == EFI_SUCCESS) {
CompareSize = BootFilePathDevicePathOffset;
} else {
CompareSize = GetDevicePathSize (BootDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);
}
Status = gBS->LocateHandleBuffer(
ByProtocol,
&gEfiSimpleFileSystemProtocolGuid,
NULL,
&NumberOfHandles,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
FreePool (BootOptionData);
continue;
}
for (Index = 0; Index < NumberOfHandles; Index++) {
Status = gBS->HandleProtocol(
HandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
(VOID **)SysRootDevicePath
);
if (EFI_ERROR (Status)) {
continue;
}
if (CompareMem (
((UINT8 *)*SysRootDevicePath) + GetDevicePathSize (*SysRootDevicePath) - CompareSize - sizeof(EFI_DEVICE_PATH),
BootDevicePath,
CompareSize) == 0) {
Found = TRUE;
break;
}
}
if (Found) {
Status = gBS->HandleProtocol(
HandleBuffer[Index],
&gEfiSimpleFileSystemProtocolGuid,
(VOID **)&SimpleFileSystem
);
if (!EFI_ERROR (Status)) {
Status = SimpleFileSystem->OpenVolume(SimpleFileSystem, SysRootHandle);
}
} else {
Status = EFI_NOT_FOUND;
}
FreePool (HandleBuffer);
FreePool (BootOptionData);
}
return Status;
}
/**
Get the information of system drive which contain capsule image file.
@param[out] SysRootDevicePath The pointer of system root device path pointer
@param[out] SysRoorHandle The pointer of EFI_FILE_HANDLE of system drive
@retval EFI_SUCCESS The system drive information is correctly get
@return Others Unable to get system drive information
**/
STATIC
EFI_STATUS
GetSystemRootInfo (
OUT EFI_DEVICE_PATH **SysRootDevicePath,
OUT EFI_FILE_HANDLE *SysRootHandle
)
{
EFI_STATUS Status;
Status = GetSystemRootInfoFromCurrentBootOption (SysRootDevicePath, SysRootHandle);
if (!EFI_ERROR (Status)) {
if (HaveCapsuleImageFile (*SysRootHandle)) {
return EFI_SUCCESS;
}
(*SysRootHandle)->Close (*SysRootHandle);
}
return GetSystemRootInfoFromFileSystems (SysRootDevicePath, SysRootHandle);
}
/**
Write a file to an root file handle.
@param[in] SysRoot The system root file handle.
@param[in] FileName Pointer to file name.
@param[in] FileBuffer The buffer to be written into file system.
@param[in] FileSize The size of FileBuffer.
@retval EFI_SUCCESS Wrote the file successfully.
@retval Others Failed to write the file.
**/
EFI_STATUS
WriteFileToStorage (
IN EFI_FILE_HANDLE SysRoot,
IN CHAR16 *FileName,
IN UINT8 *FileBuffer,
IN UINTN FileSize,
IN BOOLEAN IsWriteToDirectory
)
{
EFI_STATUS Status;
EFI_FILE *FileHandle;
EFI_FILE *DirHandle;
UINTN WriteSize;
DEBUG ((DEBUG_INFO, "WriteFileToStorage - start\n"));
if (IsWriteToDirectory){
//
// Ensure that efi and updatecapsule directories exist
//
Status = SysRoot->Open (SysRoot, &DirHandle, L"\\EFI", EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
if (EFI_ERROR (Status)) {
Status = SysRoot->Open (SysRoot, &DirHandle, L"\\EFI", EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, EFI_FILE_DIRECTORY);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "Unable to create %s directory\n", L"\\EFI"));
return EFI_NOT_FOUND;
}
}
Status = SysRoot->Open (SysRoot, &DirHandle, EFI_CAPSULE_FILE_DIRECTORY, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE , 0);
if (EFI_ERROR (Status)) {
Status = SysRoot->Open (SysRoot, &DirHandle, EFI_CAPSULE_FILE_DIRECTORY, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, EFI_FILE_DIRECTORY);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "Unable to create %s directory\n", EFI_CAPSULE_FILE_DIRECTORY));
return EFI_NOT_FOUND;
}
}
} else {
Status = SysRoot->Open (SysRoot, &FileHandle, FileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "Cannot open file: %s. Status = %r\n", FileName, Status));
return Status;
}
}
if (IsWriteToDirectory) {
//
// Open UpdateCapsule file
//
Status = DirHandle->Open (DirHandle, &FileHandle, FileName, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Unable to create %s file\n", FileName));
return EFI_NOT_FOUND;
}
}
if (FileHandle == NULL) {
Status = EFI_UNSUPPORTED;
DEBUG ((DEBUG_ERROR, "Failed to open root dir on partition for writing. Stautus = %r\n", Status));
return Status;
}
do {
WriteSize = (FileSize > SIZE_4KB) ? SIZE_4KB : FileSize;
Status = FileHandle->Write (FileHandle, &WriteSize, FileBuffer);
if (EFI_ERROR (Status)) {
break;
}
FileSize = FileSize - WriteSize;
FileBuffer = FileBuffer + WriteSize;
} while (FileSize > 0);
DEBUG ((DEBUG_INFO, "WriteFileToStorage %s %r\n", FileName, Status));
FileHandle->Close (FileHandle);
return Status;
}
/**
Delete a file from root file handle.
@param[in] Root The root file handle.
@param[in] FileName Pointer to file name.
@retval EFI_SUCCESS File does not exist or deleted the file successfully.
@retval Others Failed to delete the file.
**/
EFI_STATUS
DeleteFileFromSys (
IN EFI_FILE_HANDLE Root,
IN CHAR16 *FileName
)
{
EFI_STATUS Status;
EFI_FILE *FileHandle;
DEBUG ((DEBUG_INFO, "DeleteFileFromRoot - start\n"));
Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
if (Status == EFI_NOT_FOUND) {
DEBUG ((DEBUG_INFO, "File %s does not exist. No need to delete\n", FileName));
return EFI_SUCCESS;
} else if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Cannot open file: %s. Status = %r\n", FileName, Status));
return Status;
}
if (FileHandle == NULL) {
Status = EFI_UNSUPPORTED;
DEBUG ((DEBUG_ERROR, "Failed to open root dir - %r\n", Status));
return Status;
}
Status = FileHandle->Delete (FileHandle);
DEBUG ((DEBUG_INFO, "DeleteFileFromRoot %s %r\n", FileName, Status));
return Status;
}
/**
Read a file from a root file handle.
@param[in] SysRoot The system root file handle.
@param[in] FileName Pointer to file name.
@param[in] FileBuffer The buffer read from file system.
@param[in] FileSize The size of FileBuffer.
@retval EFI_SUCCESS Read the file successfully.
@retval Others Failed to read the file.
**/
EFI_STATUS
ReadFileFromStorage (
IN EFI_FILE_HANDLE SysRoot,
IN CHAR16 *FileName,
OUT VOID **Buffer,
OUT UINTN *BufferSize
)
{
EFI_STATUS Status;
EFI_FILE *FileHandle;
UINTN FileInfoSize;
EFI_FILE_INFO *FileInfo;
EFI_GUID FileInfoGuid = EFI_FILE_INFO_ID;
DEBUG ((DEBUG_INFO, "ReadFileFromStorage - start\n"));
Status = SysRoot->Open (SysRoot, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Open file on root: %s. error - %r\n", FileName, Status));
return Status;
}
if (FileHandle == NULL) {
Status = EFI_UNSUPPORTED;
DEBUG ((DEBUG_ERROR, "Open file on root: %s. error - %r\n", FileName, Status));
return Status;
}
FileInfoSize = 0;
FileInfo = NULL;
Status = FileHandle->GetInfo (
FileHandle,
&FileInfoGuid,
&FileInfoSize,
NULL
);
if (EFI_ERROR (Status)) {
if (Status != EFI_BUFFER_TOO_SMALL) {
DEBUG ((DEBUG_ERROR, "GetInfo error - %r\n", Status));
goto Exit;
}
}
DEBUG ((DEBUG_INFO, "FileRead\n"));
FileInfo = AllocatePool (FileInfoSize);
if (FileInfo == NULL) {
DEBUG ((DEBUG_ERROR, "GetInfo fail, AllocatePool(Size: %x) error\n", FileInfoSize));
goto Exit;
}
Status = FileHandle->GetInfo (
FileHandle,
&FileInfoGuid,
&FileInfoSize,
FileInfo
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "FileRead fail, GetInfo error, Status: %r\n", Status));
goto Exit;
}
*BufferSize = (UINT32) FileInfo->FileSize;
if (*BufferSize != 0) {
*Buffer = AllocateZeroPool (*BufferSize);
if (*Buffer == NULL) {
DEBUG ((DEBUG_ERROR, "Read fail, AllocatePool(Size: %x) error\n", FileInfoSize));
Status = EFI_OUT_OF_RESOURCES;
goto Exit;
}
Status = FileHandle->Read (
FileHandle,
BufferSize,
*Buffer
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Read fail, error - %r\n", Status));
FreePool (*Buffer);
goto Exit;
}
} else {
DEBUG ((DEBUG_INFO, "File size is 0, set return Buffer to NULL.\n"));
*Buffer = NULL;
}
Status = EFI_SUCCESS;
Exit:
if (FileInfo != NULL) {
FreePool (FileInfo);
}
FileHandle->Close (FileHandle);
DEBUG ((DEBUG_INFO, "ReadFileFromStorage %s BufferSize: %x %r\n", FileName, *BufferSize, Status));
return Status;
}
EFI_STATUS
GetBackupMeAsCapsule(
OUT BOOLEAN *IsMultiple
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *SysRootDevicePath;
EFI_FILE_HANDLE SysRootHandle;
UINT8 CapsuleSha256[SHA256_DIGEST_HASH_SIZE];
UINT8 BackupSha256[SHA256_DIGEST_HASH_SIZE];
UINTN VariableSize;
UINT8 *Buffer;
UINTN BufferSize;
UINT8 *Ptr;
UINTN Index;
Ptr = NULL;
Index = 0;
*IsMultiple = FALSE;
DEBUG ((DEBUG_INFO, "GetBackupMeAsCapsule - entry\n"));
Status = GetSystemRootInfo (&SysRootDevicePath, &SysRootHandle);
if (EFI_ERROR (Status) || SysRootHandle == NULL) {
return EFI_UNSUPPORTED;
}
Status = ReadFileFromStorage (SysRootHandle,SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME_NEW,(VOID **)&Buffer, &BufferSize);
if (!EFI_ERROR (Status)) {
//
// Delete broken capsule.
//
DeleteFileFromSys (SysRootHandle, SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME_NEW);
}
//
// Get backup ME.
//
Status = ReadFileFromStorage (SysRootHandle,SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME,(VOID **)&Buffer, &BufferSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Cannot find Backup ME Capsule image.\n"));
return EFI_NOT_FOUND;
}
//
// Verify capsule
//
ZeroMem (CapsuleSha256, SHA256_DIGEST_HASH_SIZE);
CreateSha256Hash (Buffer, BufferSize, CapsuleSha256);
VariableSize = SHA256_DIGEST_HASH_SIZE;
ZeroMem (BackupSha256, SHA256_DIGEST_SIZE);
Status = gRT->GetVariable (
ME_CAPSULE_DIGEST_VARIABLE_NAME,
&gSysFwUpdateDigiestGuid,
NULL,
&VariableSize,
&BackupSha256
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Can't find Me backup digest.\n"));
return Status;
}
if (CompareMem (CapsuleSha256, BackupSha256, SHA256_DIGEST_HASH_SIZE) == 0) {
Status = WriteFileToStorage (SysRootHandle, CAPSULE_IMAGE_NAME, (UINT8 *)(UINTN) Buffer, BufferSize, TRUE);
} else {
DEBUG ((DEBUG_ERROR, "Me backup image loaded from ESP is corrupted.\n"));
return EFI_DEVICE_ERROR;
}
Index = 0;
Ptr = Buffer + Index;
while (Index < BufferSize) {
if (CompareMem (Ptr, InsydeBiosSignature, sizeof (InsydeBiosSignature)) == 0) {
*IsMultiple = TRUE;
break;
}
Index += sizeof(UINT64);
Ptr = Buffer + Index;
}
//
// Get backup ux
//
Status = ReadFileFromStorage (SysRootHandle,SYSFW_UPDATE_WINDOWS_UX_CAPSULE_FILE_NAME, (VOID **)&Buffer, &BufferSize);
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
Status = WriteFileToStorage (SysRootHandle, UX_IMAGE_NAME, (UINT8 *)(UINTN) Buffer, BufferSize, TRUE);
return Status;
}
/**
Save current ME/Monolithic Capsule as ME rollback capsule.
@param[in] PayloadImage Pointer to ME/Monolithic FMP payload image (FMP image header is stripped off).
@param[in] PayloadImageSize The size of PayloadImage.
@retval EFI_SUCCESS Successfully backed up necessary files on external storage.
@retval Others Failed to back up necessary files.
**/
EFI_STATUS
SaveMeCapsuleForRollback (
IN BOOLEAN IsSecureflash
)
{
EFI_STATUS Status;
UINT8 *Buffer;
UINTN Length;
UINT8 Sha256[SHA256_DIGEST_HASH_SIZE];
EFI_DEVICE_PATH_PROTOCOL *SysRootDevicePath;
EFI_FILE_HANDLE SysRootHandle;
EFI_CAPSULE_HEADER CapsuleHeader;
UINT8 *NewBuffer;
UINTN NewLength;
UINT8 *CurrentBuffer;
UINTN CurrentLength;
Buffer = NULL;
Length = 0;
NewBuffer = NULL;
NewLength = 0;
CurrentBuffer = NULL;
CurrentLength = 0;
DEBUG ((DEBUG_INFO, "SaveMeCapsuleForRollback - entry\n"));
Status = GetSystemRootInfo (&SysRootDevicePath, &SysRootHandle);
if (EFI_ERROR (Status) || SysRootHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Get capsule as backup ME.
//
Status = ReadFileFromStorage (SysRootHandle, CAPSULE_IMAGE_FULL_PATH,(VOID **)&Buffer, &Length);
if (EFI_ERROR (Status)) {
if (IsSecureflash) {
//
// Get isflash.bin as backup ME.
//
Status = ReadFileFromStorage (SysRootHandle, SECURE_FLASH_IMAGE_PATH,(VOID **)&NewBuffer, &NewLength);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Cannot find ME image.\n"));
return Status;
} else {
Buffer = NULL;
//
// Append EFI_CAPSULE_HEADER
//
CopyGuid (&CapsuleHeader.CapsuleGuid, PcdGetPtr (PcdWindowsMeFirmwareCapsuleGuid));
CapsuleHeader.Flags = 0x50000;
CapsuleHeader.HeaderSize = 0x1000;
CapsuleHeader.CapsuleImageSize = (UINT32)NewLength + CapsuleHeader.HeaderSize;
Buffer = AllocateZeroPool(CapsuleHeader.CapsuleImageSize);
CopyMem(Buffer, &CapsuleHeader, sizeof(EFI_CAPSULE_HEADER));
CopyMem((VOID*)((UINT8*)Buffer + CapsuleHeader.HeaderSize), (VOID*)NewBuffer, NewLength);
Length = CapsuleHeader.CapsuleImageSize;
}
} else {
DEBUG ((DEBUG_ERROR, "Cannot find ME image.\n"));
return Status;
}
}
//
// Replace the any existing old recovery capsule with new capsule.
//
Status = DeleteFileFromSys (SysRootHandle, SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME_NEW);
if (!EFI_ERROR (Status) || (Status == EFI_NOT_FOUND)) {
Status = WriteFileToStorage (SysRootHandle, SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME_NEW, (UINT8 *)(UINTN) Buffer, Length, FALSE);
}
//
// Caculate temp digest
//
ZeroMem (Sha256, SHA256_DIGEST_HASH_SIZE);
CreateSha256Hash (Buffer, Length, Sha256);
Status = SetVariableToSensitiveVariable (
ME_CAPSULE_DIGEST_TEMP_VARIABLE_NAME,
&gSysFwUpdateDigiestGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
SHA256_DIGEST_HASH_SIZE,
Sha256
);
//
// If system has UX, save UX capsule.
//
Status = ReadFileFromStorage (SysRootHandle,UX_IMAGE_FULL_PATH,(VOID **)&Buffer, &Length);
if (!EFI_ERROR (Status)) {
Status = WriteFileToStorage (SysRootHandle, SYSFW_UPDATE_WINDOWS_UX_CAPSULE_FILE_NAME, (UINT8 *)(UINTN) Buffer, Length, FALSE);
} else {
DEBUG ((DEBUG_INFO, "System don't have UX.\n"));
return EFI_SUCCESS;
}
return Status;
}
/**
Replace MeRecovCap with MeRecovCapNew upon successful capsule update.
@retval EFI_SUCCESS Successfully old recovery capsule with new recovery capsule.
@retval Others Failed to sync old/new recovery capsules.
**/
EFI_STATUS
SyncMeRecoveryCapsules (
VOID
)
{
EFI_STATUS Status;
UINT8 *Buffer;
UINTN Length;
UINT8 Sha256[SHA256_DIGEST_HASH_SIZE];
UINTN VariableSize;
EFI_DEVICE_PATH_PROTOCOL *SysRootDevicePath;
EFI_FILE_HANDLE SysRootHandle;
SYSTEM_FIRMWARE_COMPONENT Component;
Status = EFI_SUCCESS;
Buffer = NULL;
Length = 0;
DEBUG ((DEBUG_INFO, "SyncMeRecoveryCapsules - entry\n"));
Status = GetFwUpdateInfo (&Component);
if(!EFI_ERROR(Status)) {
if(Component != UpdatingBios){
//During flash.
goto Exit;
} else {
// Flash ME done, clear flag.
ClearFwUpdateInfo ();
}
}
Status = GetSystemRootInfo (&SysRootDevicePath, &SysRootHandle);
if (EFI_ERROR (Status) || SysRootHandle == NULL) {
return EFI_UNSUPPORTED;
}
Status = ReadFileFromStorage (SysRootHandle,SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME_NEW,(VOID **)&Buffer, &Length);
if (!EFI_ERROR (Status)) {
VariableSize = SHA256_DIGEST_HASH_SIZE;
ZeroMem (Sha256, SHA256_DIGEST_SIZE);
Status = gRT->GetVariable (
ME_CAPSULE_DIGEST_TEMP_VARIABLE_NAME,
&gSysFwUpdateDigiestGuid,
NULL,
&VariableSize,
&Sha256
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "Get me digest fail, Status %r\n", Status));
goto Exit;
}
//
// A new ME Recovery capsule exists on storage. Replace old recovery capsule with new capsule.
//
Status = DeleteFileFromSys (SysRootHandle, SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME);
if (!EFI_ERROR (Status) || (Status == EFI_NOT_FOUND)) {
Status = WriteFileToStorage (SysRootHandle, SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME, (UINT8 *) (UINTN) Buffer, Length, FALSE);
if(EFI_ERROR (Status)){
DEBUG ((DEBUG_INFO, "Write ME backup fail, Status %r\n", Status));
goto Exit;
}
Status = SetVariableToSensitiveVariable (
ME_CAPSULE_DIGEST_VARIABLE_NAME,
&gSysFwUpdateDigiestGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
SHA256_DIGEST_HASH_SIZE,
Sha256
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "Write me digest fail, Status %r\n", Status));
goto Exit;
}
Status = DeleteFileFromSys (SysRootHandle, SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME_NEW);
SetVariableToSensitiveVariable (
ME_CAPSULE_DIGEST_TEMP_VARIABLE_NAME,
&gSysFwUpdateProgressGuid,
0,
0,
NULL
);
}
FreePool (Buffer);
}
Exit:
return Status;
}
/**
Search for ME recovery capsule on storage and return TRUE if present.
@retval TRUE ME recovery image is present.
@retval FALSE ME recovery image is not present.
**/
BOOLEAN
IsMeBackupExistOnStorage (
VOID
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *SysRootDevicePath;
EFI_FILE_HANDLE SysRootHandle;
Status = GetSystemRootInfo (&SysRootDevicePath, &SysRootHandle);
if (!EFI_ERROR (Status) || SysRootHandle != NULL) {
Status = ReadFileFromStorage (SysRootHandle, SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME, NULL, NULL);
}
return (Status == EFI_SUCCESS);
}
//[-end-201112-IB16810138-add]//
BOOLEAN
IsCapsuleUpdate(
VOID
)
{
UINTN Size;
UINT64 OsIndications;
SYSTEM_FIRMWARE_COMPONENT Component;
EFI_STATUS Status;
Size = sizeof (UINT64);
Status = CommonGetVariable (
L"OsIndications",
&gEfiGlobalVariableGuid,
&Size,
&OsIndications
);
if (!EFI_ERROR (Status) && (OsIndications & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED)) {
Status = GetFwUpdateInfo (&Component);
if ((!EFI_ERROR (Status) && Component == UpdatingMe) || (!EFI_ERROR (Status) && Component == UpdatingTypeMax)) {
return TRUE;
}
}
return FALSE;
}
BOOLEAN
IsSecureFlash(
OUT BOOLEAN *IsMultipleImage
)
{
EFI_STATUS Status;
UINT8 *Buffer;
UINTN Length;
EFI_DEVICE_PATH_PROTOCOL *SysRootDevicePath;
EFI_FILE_HANDLE SysRootHandle;
IMAGE_INFO ImageInfo;
UINTN Size;
UINTN Index;
UINT8 *Ptr;
BOOLEAN FoundMeFlag;
SYSTEM_FIRMWARE_COMPONENT Component;
DEBUG ((DEBUG_INFO, "IsSecureFlash - entry\n"));
Buffer = NULL;
Length = 0;
Ptr = NULL;
FoundMeFlag = FALSE;
Size = sizeof (IMAGE_INFO);
Status = CommonGetVariable (
SECURE_FLASH_INFORMATION_NAME,
&gSecureFlashInfoGuid,
&Size,
&ImageInfo
);
if ((Status == EFI_SUCCESS) && (ImageInfo.FlashMode)) {
Status = GetSystemRootInfo (&SysRootDevicePath, &SysRootHandle);
if (EFI_ERROR (Status) || SysRootHandle == NULL) {
DEBUG ((DEBUG_ERROR, "GetSystemRootInfo fail.\n"));
return FALSE;
}
Status = GetFwUpdateInfo (&Component);
if(!EFI_ERROR (Status)) {
return FALSE;
} else {
//
//First time do secure flash
//
Status = ReadFileFromStorage (SysRootHandle, SECURE_FLASH_IMAGE_PATH,(VOID **)&Buffer, &Length);
if (!EFI_ERROR (Status)) {
// Find Signature
if (Buffer != NULL) {
Index = 0;
Ptr = Buffer + Index;
while (Index < Length) {
if (CompareMem (Ptr, InsydeMeSig, sizeof (InsydeMeSig)) == 0) {
FoundMeFlag = TRUE;
break;
}
Index += sizeof(UINT64);
Ptr = Buffer + Index;
}
}
if(FoundMeFlag) {
if(Length > PcdGet32 (PcdFlashAreaSize)){
*IsMultipleImage = TRUE;
return TRUE;
} else {
*IsMultipleImage = FALSE;
return TRUE;
}
}
}
}
}
return FALSE;
}
/**
MeResiliencyCallBack
ME Resiliency Feature to determine the CSE Image health and then
initiate capsule based recovery.
@param[in] Event - A pointer to the Event that triggered the callback.
@param[in] Context - A pointer to private data registered with the callback function.
**/
//[-start-201112-IB16810138-modify]//
VOID
EFIAPI
MeUpdateFaultToleranceCallBack (
//[-end-201112-IB16810138-modify]//
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINT8 *Buffer;
UINTN Length;
UINT64 HeciBaseAddress;
HECI_FWS_REGISTER MeFwSts;
HECI_GS_SHDW_REGISTER MeFwSts2;
//[-start-201112-IB16810138-remove]//
// PCH_RESET_DATA ResetData;
// UINTN ResetDataSize;
// SYSTEM_FIRMWARE_UPDATE_PROGRESS PreviousProgress;
//[-end-201112-IB16810138-remove]//
//[-start-201112-IB16810138-add]//
UINTN Size;
UINT64 OsIndications;
SYSTEM_FIRMWARE_COMPONENT Component;
BOOLEAN IsMultipleImage;
//[-end-201112-IB16810138-add]//
//[-start-201112-IB16810138-modify]//
DEBUG((DEBUG_INFO, "MeUpdateFaultToleranceCallBack Start\n"));
//[-end-201112-IB16810138-modify]//
Status = EFI_SUCCESS;
Buffer = NULL;
Length = 0;
IsMultipleImage = FALSE;
HeciBaseAddress = PCI_SEGMENT_LIB_ADDRESS (ME_SEGMENT, ME_BUS, ME_DEVICE_NUMBER, HECI_FUNCTION_NUMBER, 0);
//
// Read ME FWS
//
MeFwSts.ul = PciSegmentRead32 (HeciBaseAddress + R_ME_HFS);
DEBUG ((DEBUG_INFO, "MeFwSts = 0x%X!\n", MeFwSts.ul));
//
// Read ME FWS2
//
MeFwSts2.ul = PciSegmentRead32 (HeciBaseAddress + R_ME_HFS_2);
DEBUG ((DEBUG_INFO, "MeFwSts2 = 0x%X!\n", MeFwSts2.ul));
if ((MeFwSts.r.CurrentState == ME_STATE_RECOVERY) ||
(MeFwSts.r.FtBupLdFlr == 1) ||
(MeFwSts2.r.FwUpdIpu == 1)) {
DEBUG ((DEBUG_INFO, "ME region is corrupted, initiate ME recovery\n"));
//[-start-201112-IB16810138-modify]//
//[-start-201112-IB16810138-add]//
Status = GetFwUpdateInfo (&Component);
//[-start-201112-IB16810138-modify]//
if (EFI_ERROR (Status) && IsMeBackupExistOnStorage ()) {
//[-end-201112-IB16810138-modify]//
//[-start-201112-IB16810138-add]//
Status = GetBackupMeAsCapsule (&IsMultipleImage);
if (!EFI_ERROR (Status)) {
//[-end-201112-IB16810138-add]//
//
// Set Update Progress variable for resiliency.
// Clear this variable in ClearFirmwareUpdateProgress() after TriggerCapsuleUpdate()
//
// SetUpdateProgress (UpdatingMeResiliency, 0);
//[-start-201112-IB16810138-add]//
if (IsMultipleImage) {
//
// Set Bios update flag
//
Component = UpdatingBios;
Status = gRT->SetVariable (
L"FmpCapsuleInfo",
&gFmpCapsuleInfoGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof(SYSTEM_FIRMWARE_COMPONENT),
&Component
);
}
Component = UpdatingMe;
Status = SetVariableToSensitiveVariable (
FW_UPDATEINFO_VARIABLE_NAME,
&gSysFwUpdateProgressGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof(SYSTEM_FIRMWARE_COMPONENT),
&Component
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Set FW_UPDATEINFO_VARIABLE_NAME to UpdatingMeResiliency fail.\n"));
}
//
// Trigger capsule update to fix ME
//
Size = sizeof(UINT64);
OsIndications = 0;
Status = CommonGetVariable (
L"OsIndications",
&gEfiGlobalVariableGuid,
&Size,
&OsIndications
);
if (EFI_ERROR (Status) || (OsIndications & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) == 0) {
OsIndications |= EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
Status = CommonSetVariable (
L"OsIndications",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof(UINT64),
&OsIndications
);
//[-end-201112-IB16810138-add]//
//
// Issue a global reset to initiate capsule based recovery.
//
// ResetDataSize = sizeof (PCH_RESET_DATA);
// CopyMem (&ResetData.Guid, &gPchGlobalResetGuid, sizeof (EFI_GUID));
// StrCpyS (ResetData.Description, PCH_RESET_DATA_STRING_MAX_LENGTH, PCH_PLATFORM_SPECIFIC_RESET_STRING);
// DEBUG ((DEBUG_INFO, "Issue global reset for capsule based recovery\n"));
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
}
}
} else {
DEBUG ((DEBUG_ERROR, "ME Recovery capsule is not found on storage - skip recovery.\n"));
}
} else {
//
// Sync ME Recovery Capsules.
//
//[-start-201112-IB16810138-add]//
if (IsCapsuleUpdate ()) {
Status = SaveMeCapsuleForRollback (FALSE);
} else if (IsSecureFlash (&IsMultipleImage)) {
if (IsMultipleImage) {
Component = UpdatingTypeMax;
} else {
Component = UpdatingMe;
}
Status = SetFwUpdateInfo (&Component);
if (EFI_ERROR (Status)) {
goto Exit;
}
Status = SaveMeCapsuleForRollback (TRUE);
} else {
//
// ME update completed and boot success.
// Sync ME Recovery Capsules.
//
//[-end-201112-IB16810138-add]//
Status = SyncMeRecoveryCapsules ();
DEBUG ((DEBUG_INFO, "SyncMeRecoveryCapsules - %r\n", Status));
}
}
//[-end-201112-IB16810138-modify]//
Exit:
DEBUG((DEBUG_INFO, "MeResiliencyCallBack End\n"));
return;
}
VOID
EFIAPI
MeUpdateFaultToleranceOnReadyToBootBefore (
IN EFI_EVENT Event,
IN H2O_CP_HANDLE Handle
)
{
EFI_STATUS Status;
UINT8 *Buffer;
UINTN Length;
EFI_DEVICE_PATH_PROTOCOL *SysRootDevicePath;
EFI_FILE_HANDLE SysRootHandle;
Status = EFI_SUCCESS;
Buffer = NULL;
Length = 0;
H2OCpUnregisterHandler (Handle);
//
// The update has been processed before this funtion called.
// Clear flag at this point.
//
ClearFwUpdateInfo ();
Status = GetSystemRootInfo (&SysRootDevicePath, &SysRootHandle);
if (EFI_ERROR (Status) || SysRootHandle == NULL) {
return;
}
//
// Delete backup temp file.
//
Status = ReadFileFromStorage (SysRootHandle,SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME_NEW,(VOID **)&Buffer, &Length);
if (!EFI_ERROR (Status)) {
DeleteFileFromSys (SysRootHandle, SYSFW_UPDATE_ME_RECOVERY_CAPSULE_NAME_NEW);
SetVariableToSensitiveVariable (
ME_CAPSULE_DIGEST_TEMP_VARIABLE_NAME,
&gSysFwUpdateProgressGuid,
0,
0,
NULL
);
}
}
/**
Initialize Resiliency Support for ME.
@retval EFI_SUCCESS Resiliency Support is initialized successfully
@retval EFI_NOT_FOUND Resiliency Support is not initialized successfully
**/
//[-start-201112-IB16810138-modify]//
EFI_STATUS
EFIAPI
MeUpdateFaultToleranceEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
//[-end-201112-IB16810138-modify]//
{
EFI_STATUS Status;
//[-start-201112-IB16810138-modify]//
// EFI_EVENT BeforeEndOfDxeEvent;
H2O_CP_HANDLE CpHandle;
Status = EFI_SUCCESS;
// BeforeEndOfDxeEvent = NULL;
//[-start-201112-IB16810138-modify]//
DEBUG ((DEBUG_INFO, "MeUpdateFaultToleranceEntryPoint Start\n"));
//[-end-201112-IB16810138-modify]//
DEBUG ((DEBUG_INFO, "Register an EndOfDxe Callback Function for ME Resiliency Health Check \n"));
//[-start-201112-IB16810138-remove]//
// Status = gBS->CreateEventEx (
// EVT_NOTIFY_SIGNAL,
// TPL_CALLBACK,
// MeResiliencyCallBack,
// NULL,
// &gPlatformBeforeEndOfDxeEventGroupGuid,
// &BeforeEndOfDxeEvent
// );
// ASSERT_EFI_ERROR (Status);
// if (EFI_ERROR (Status)) {
// DEBUG ((DEBUG_ERROR, "Failed to Register an EndOfDxe CallBack function for ME Resiliency, Status: %d\n", Status));
// }
//[-end-201112-IB16810138-remove]//
//[-start-201112-IB16810138-add]//
if (FeaturePcdGet (PcdH2OBdsCpEndOfDxeBeforeSupported)) {
//[-start-201112-IB16810138-modify]//
Status = H2OCpRegisterHandler (
&gH2OBdsCpEndOfDxeBeforeGuid,
MeUpdateFaultToleranceCallBack,
H2O_CP_MEDIUM_HIGH,
&CpHandle
);
//[-end-201112-IB16810138-modify]//
if (EFI_ERROR (Status)) {
DEBUG_CP ((DEBUG_ERROR, "Checkpoint Register Fail: %g (%r)\n", &gH2OBdsCpEndOfDxeBeforeGuid, Status));
return Status;
}
DEBUG_CP ((DEBUG_INFO, "Checkpoint Registered: %g (%r)\n", &gH2OBdsCpEndOfDxeBeforeGuid, Status));
}
//[-end-201112-IB16810138-add]//
if (FeaturePcdGet (PcdH2OBdsCpReadyToBootBeforeSupported)) {
Status = H2OCpRegisterHandler (
&gH2OBdsCpReadyToBootBeforeGuid,
MeUpdateFaultToleranceOnReadyToBootBefore,
H2O_CP_LOW,
&CpHandle
);
if (EFI_ERROR (Status)) {
DEBUG_CP ((DEBUG_ERROR, "Checkpoint Register Fail: %g (%r)\n", &gH2OBdsCpReadyToBootBeforeGuid, Status));
return Status;
}
DEBUG_CP ((DEBUG_INFO, "Checkpoint Registered: %g (%r)\n", &gH2OBdsCpReadyToBootBeforeGuid, Status));
}
//[-end-201112-IB16810138-modify]//
//[-start-201112-IB16810138-modify]//
DEBUG ((DEBUG_INFO, "MeUpdateFaultToleranceEntryPoint End\n"));
//[-end-201112-IB16810138-modify]//
return Status;
}