910 lines
26 KiB
C
910 lines
26 KiB
C
//;******************************************************************************
|
|
//;* Copyright (c) 2021, Insyde Software Corporation. 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.
|
|
//;*
|
|
//;******************************************************************************
|
|
|
|
#include "L05DxeServiceBody.h"
|
|
#include "CapsuleProcessorDxe.h"
|
|
|
|
EFI_GUID mL05DxeServiceBodyFontGuid = {0x81b1e2f8, 0x355, 0x4cd7, {0x96, 0x63, 0xdf, 0xb3, 0x78, 0x41, 0x5e, 0x44}};
|
|
EFI_GUID mSecureFlashErrorMsgGuid = {0x2719F233, 0xDD1A, 0xABCD, {0xA9, 0xDC, 0xAA, 0xE0, 0x7B, 0x67, 0x88, 0xF2}};
|
|
EFI_HII_HANDLE mHiiHandle = NULL;
|
|
|
|
extern UINT8 L05DxeServiceBodyStrings[];
|
|
|
|
HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
|
|
{
|
|
{
|
|
HARDWARE_DEVICE_PATH,
|
|
HW_VENDOR_DP,
|
|
{
|
|
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
|
|
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
|
|
}
|
|
},
|
|
{0xe313f1ba, 0x25b9, 0x4b1d, {0x82, 0xf6, 0x12, 0x23, 0xa6, 0xa, 0x94, 0x8b}}
|
|
},
|
|
{
|
|
END_DEVICE_PATH_TYPE,
|
|
END_ENTIRE_DEVICE_PATH_SUBTYPE,
|
|
{
|
|
(UINT8) (END_DEVICE_PATH_LENGTH),
|
|
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
The HII driver handle passed in for HiiDatabase.NewPackageList() requires
|
|
that there should be DevicePath Protocol installed on it.
|
|
This routine create a virtual Driver Handle by installing a vendor device
|
|
path on it, so as to use it to invoke HiiDatabase.NewPackageList().
|
|
|
|
@param DriverHandle Handle to be returned.
|
|
|
|
@retval EFI_SUCCESS Handle destroy success.
|
|
@retval EFI_OUT_OF_RESOURCES Not enough memory.
|
|
**/
|
|
EFI_STATUS
|
|
CreateHiiDriverHandle (
|
|
OUT EFI_HANDLE *DriverHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
*DriverHandle = NULL;
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
DriverHandle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
&mHiiVendorDevicePath,
|
|
NULL
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Init Hii Handle.
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others An unexpected error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
InitHiiHandle (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE DriverHandle;
|
|
|
|
DriverHandle = NULL;
|
|
|
|
Status = CreateHiiDriverHandle (&DriverHandle);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
mHiiHandle = HiiAddPackages (
|
|
&mL05DxeServiceBodyFontGuid,
|
|
DriverHandle,
|
|
L05DxeServiceBodyStrings,
|
|
NULL
|
|
);
|
|
|
|
if (mHiiHandle == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Set BIOS update String.
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others An unexpected error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
L05SetBiosUpdateString (
|
|
VOID
|
|
)
|
|
{
|
|
CHAR8 *PlatformLangVar;
|
|
CHAR16 *StringPtr;
|
|
UINTN StringSize;
|
|
|
|
PlatformLangVar = NULL;
|
|
StringPtr = NULL;
|
|
|
|
if (mHiiHandle == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
PlatformLangVar = CommonGetVariableData (
|
|
L"PlatformLang",
|
|
&gEfiGlobalVariableGuid
|
|
);
|
|
|
|
if (PlatformLangVar == NULL) {
|
|
PlatformLangVar = L05_RFC_3066_ENGLISH_CODE;
|
|
}
|
|
|
|
StringPtr = HiiGetString (mHiiHandle, STRING_TOKEN (L05_STR_BIOS_UPDATE_UI_ERROR_CODE_STRING), NULL);
|
|
|
|
if (StringPtr != NULL) {
|
|
StringSize = StrSize (StringPtr);
|
|
PcdSetPtrS (PcdL05BiosUpdateUiErrorCodeString, &StringSize, (VOID *) StringPtr);
|
|
FreePool (StringPtr);
|
|
StringPtr = NULL;
|
|
}
|
|
|
|
StringPtr = HiiGetString (mHiiHandle, STRING_TOKEN (L05_STR_BIOS_UPDATE_UI_STRING_EN1), NULL);
|
|
|
|
if (StringPtr != NULL) {
|
|
StringSize = StrSize (StringPtr);
|
|
PcdSetPtrS (PcdL05BiosUpdateUiStringEn1, &StringSize, (VOID *) StringPtr);
|
|
FreePool (StringPtr);
|
|
StringPtr = NULL;
|
|
}
|
|
|
|
StringPtr = HiiGetString (mHiiHandle, STRING_TOKEN (L05_STR_BIOS_UPDATE_UI_STRING_EN2), NULL);
|
|
|
|
if (StringPtr != NULL) {
|
|
StringSize = StrSize (StringPtr);
|
|
PcdSetPtrS (PcdL05BiosUpdateUiStringEn2, &StringSize, (VOID *) StringPtr);
|
|
FreePool (StringPtr);
|
|
StringPtr = NULL;
|
|
}
|
|
|
|
|
|
if (AsciiStrCmp (PlatformLangVar, L05_RFC_3066_SIMPLIFIED_CHINESE_CODE) == 0) {
|
|
StringPtr = HiiGetString (mHiiHandle, STRING_TOKEN (L05_STR_BIOS_UPDATE_UI_STRING_ZH), NULL);
|
|
|
|
if (StringPtr != NULL) {
|
|
StringSize = StrSize (StringPtr);
|
|
PcdSetPtrS (PcdL05BiosUpdateUiStringZh, &StringSize, (VOID *) StringPtr);
|
|
FreePool (StringPtr);
|
|
StringPtr = NULL;
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Display the boot logo.
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others Failed on displaying the boot logo.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
DisplayBootLogo (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
|
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
|
|
UINTN DestinationX;
|
|
UINTN DestinationY;
|
|
UINTN Width;
|
|
UINTN Height;
|
|
|
|
BltBuffer = NULL;
|
|
DestinationX = 0;
|
|
DestinationY = 0;
|
|
Width = 0;
|
|
Height = 0;
|
|
|
|
Status = BgrtGetBootImageInfo (
|
|
&BltBuffer,
|
|
&DestinationX,
|
|
&DestinationY,
|
|
&Width,
|
|
&Height
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
gST->ConOut->ClearScreen (gST->ConOut);
|
|
gST->ConOut->EnableCursor (gST->ConOut, FALSE);
|
|
|
|
Status = gBS->HandleProtocol (
|
|
gST->ConsoleOutHandle,
|
|
&gEfiGraphicsOutputProtocolGuid,
|
|
(VOID **) &GraphicsOutput
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = GraphicsOutput->Blt (
|
|
GraphicsOutput,
|
|
BltBuffer,
|
|
EfiBltBufferToVideo,
|
|
0,
|
|
0,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height,
|
|
Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
|
|
);
|
|
|
|
if (BltBuffer != NULL) {
|
|
gBS->FreePool (BltBuffer);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Init Flash Firmware Tool Error Process.
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others An unexpected error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
InitFlashFirmwareToolErrorProcess (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
L05_FLASH_FIRMWARE_TOOL_ERROR_PROCESS_PROTOCOL *FlashErrorProcessProtocol;
|
|
EFI_HANDLE Handle;
|
|
|
|
Status = EFI_SUCCESS;
|
|
FlashErrorProcessProtocol = NULL;
|
|
Handle = NULL;
|
|
|
|
FlashErrorProcessProtocol = AllocateZeroPool (sizeof (L05_FLASH_FIRMWARE_TOOL_ERROR_PROCESS_PROTOCOL));
|
|
|
|
if (FlashErrorProcessProtocol == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
FlashErrorProcessProtocol->ErrorProcess = L05ErrorProcess;
|
|
Status = gBS->InstallProtocolInterface (
|
|
&Handle,
|
|
&gEfiL05FlashFirmwareToolErrorProcessProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
FlashErrorProcessProtocol
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Callback from checkpoint CapsuleUpdateProgress for Capsule Update Progress to display progress bar.
|
|
|
|
@param[in] Event A pointer to the Event that triggered the callback.
|
|
@param[in] CpHandle Checkpoint handle.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
EFIAPI
|
|
CapsuleUpdateProgressHandler (
|
|
IN EFI_EVENT Event,
|
|
IN H2O_CP_HANDLE CpHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
H2O_BDS_CP_CAPSULE_UPDATE_PROGRESS_DATA *BdsCapsuleUpdateProgressData;
|
|
EFI_GUID BdsCpCapsuleUpdateProgressGuid;
|
|
|
|
Status = H2OCpLookup (CpHandle, (VOID **) &BdsCapsuleUpdateProgressData, &BdsCpCapsuleUpdateProgressGuid);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG_CP ((DEBUG_ERROR, "Checkpoint Data Not Found: %x (%r)\n", CpHandle, Status));
|
|
DEBUG_CP ((DEBUG_ERROR, " %a\n", __FUNCTION__));
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Display L05 progress bar.
|
|
//
|
|
L05ProgressBar (BdsCapsuleUpdateProgressData->Completion);
|
|
|
|
//
|
|
// Update Checkpoint Status
|
|
//
|
|
BdsCapsuleUpdateProgressData->Status = H2O_CP_TASK_SKIP;
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
L05 Windows Ux Set Image.
|
|
|
|
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
|
|
@param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
|
|
The number is between 1 and DescriptorCount.
|
|
@param[in] Image Points to the new image.
|
|
@param[in] ImageSize Size of the new image in bytes.
|
|
@param[in] VendorCode This enables vendor to implement vendor-specific firmware image update policy.
|
|
Null indicates the caller did not specify the policy or use the default policy.
|
|
@param[in] Progress A function used by the driver to report the progress of the firmware update.
|
|
@param[out] AbortReason A pointer to a pointer to a null-terminated string providing more
|
|
details for the aborted operation. The buffer is allocated by this function
|
|
with AllocatePool(), and it is the caller's responsibility to free it with a
|
|
call to FreePool().
|
|
|
|
@retval EFI_SUCCESS The device was successfully updated with the new image.
|
|
@retval EFI_ABORTED The operation is aborted.
|
|
@retval EFI_INVALID_PARAMETER The Image was NULL.
|
|
@retval EFI_UNSUPPORTED The operation is not supported.
|
|
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
L05WindowsUxSetImage (
|
|
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
|
|
IN UINT8 ImageIndex,
|
|
IN CONST VOID *Capsule,
|
|
IN UINTN CapsuleSize,
|
|
IN CONST VOID *VendorCode,
|
|
IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress,
|
|
OUT CHAR16 **AbortReason
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
DisplayBootLogo ();
|
|
|
|
//
|
|
// Paint BIOS update warning message.
|
|
//
|
|
Status = L05BiosUpdateWarningMsg (TRUE);
|
|
|
|
//
|
|
// Init BIOS update error message.
|
|
//
|
|
Status = InitFlashFirmwareToolErrorProcess ();
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Find the Capsule Fmp Entry with specific ImageIndex from the CapsuleFmp instance.
|
|
|
|
@param[in] ImageIndex ImageIndex in EFI_FIRMWARE_IMAGE_DESCRIPTOR.
|
|
|
|
@returns The Capsule Fmp Entry pointer with the specified ImageIndex.
|
|
NULL if Capsule Fmp Entry was not found.
|
|
**/
|
|
CAPSULE_FMP_ENTRY*
|
|
FindCapsuleFmpEntryByIndex (
|
|
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp,
|
|
UINT8 ImageIndex
|
|
)
|
|
{
|
|
CAPSULE_FMP_INSTANCE *CapsuleFmpPrivate;
|
|
LIST_ENTRY *Link;
|
|
CAPSULE_FMP_ENTRY *CapsuleFmpEntry;
|
|
|
|
CapsuleFmpPrivate = NULL;
|
|
Link = NULL;
|
|
CapsuleFmpEntry = NULL;
|
|
|
|
CapsuleFmpPrivate = CAPSULE_FMP_INSTANCE_FROM_THIS (Fmp);
|
|
|
|
if (CapsuleFmpPrivate == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
Link = GetFirstNode (&CapsuleFmpPrivate->CapsuleProcessorListHead);
|
|
|
|
while (!IsNull (&CapsuleFmpPrivate->CapsuleProcessorListHead, Link)) {
|
|
CapsuleFmpEntry = (CAPSULE_FMP_ENTRY *) Link;
|
|
|
|
if (CapsuleFmpEntry->ImageIndex == ImageIndex) {
|
|
return CapsuleFmpEntry;
|
|
}
|
|
|
|
Link = GetNextNode (&CapsuleFmpPrivate->CapsuleProcessorListHead, Link);
|
|
};
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
Callback function to hook SetImage function of Windows UX capsule image.
|
|
|
|
@param[in] Event Event whose notification function is being invoked.
|
|
@param[in] Context Pointer to the notification function's context.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
EFIAPI
|
|
L05HookWindowsUxSetImage (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BOOLEAN IsFoundWindowsUxCapsule;
|
|
EFI_HANDLE *HandleBuffer;
|
|
UINTN NumberOfHandles;
|
|
UINTN Index;
|
|
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
|
|
UINTN ImageInfoSize;
|
|
EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
|
|
UINT32 FmpImageInfoDescriptorVer;
|
|
UINT8 FmpImageInfoCount;
|
|
UINTN DescriptorSize;
|
|
UINT32 PackageVersion;
|
|
CHAR16 *PackageVersionName;
|
|
CAPSULE_FMP_ENTRY *CapsuleFmpEntry;
|
|
|
|
IsFoundWindowsUxCapsule = FALSE;
|
|
HandleBuffer = NULL;
|
|
Fmp = NULL;
|
|
FmpImageInfoBuf = NULL;
|
|
PackageVersionName = NULL;
|
|
CapsuleFmpEntry = NULL;
|
|
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gEfiFirmwareManagementProtocolGuid,
|
|
NULL,
|
|
&NumberOfHandles,
|
|
&HandleBuffer
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
for (Index = 0; Index < NumberOfHandles; Index++) {
|
|
Status = gBS->HandleProtocol (
|
|
HandleBuffer[Index],
|
|
&gEfiFirmwareManagementProtocolGuid,
|
|
(VOID **) &Fmp
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
continue;
|
|
}
|
|
|
|
ImageInfoSize = 0;
|
|
Status = Fmp->GetImageInfo (
|
|
Fmp,
|
|
&ImageInfoSize,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
|
continue;
|
|
}
|
|
|
|
FmpImageInfoBuf = NULL;
|
|
FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
|
|
|
|
if (FmpImageInfoBuf == NULL) {
|
|
continue;
|
|
}
|
|
|
|
PackageVersionName = NULL;
|
|
Status = Fmp->GetImageInfo (
|
|
Fmp,
|
|
&ImageInfoSize, // ImageInfoSize
|
|
FmpImageInfoBuf, // ImageInfo
|
|
&FmpImageInfoDescriptorVer, // DescriptorVersion
|
|
&FmpImageInfoCount, // DescriptorCount
|
|
&DescriptorSize, // DescriptorSize
|
|
&PackageVersion, // PackageVersion
|
|
&PackageVersionName // PackageVersionName
|
|
);
|
|
|
|
//
|
|
// If FMP GetInformation interface failed, skip this resource
|
|
//
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (FmpImageInfoBuf);
|
|
FmpImageInfoBuf = NULL;
|
|
continue;
|
|
}
|
|
|
|
if (PackageVersionName != NULL) {
|
|
FreePool (PackageVersionName);
|
|
PackageVersionName = NULL;
|
|
}
|
|
|
|
if (CompareGuid (&FmpImageInfoBuf->ImageTypeId, &gWindowsUxCapsuleGuid)) {
|
|
CapsuleFmpEntry = FindCapsuleFmpEntryByIndex (Fmp, FmpImageInfoBuf->ImageIndex);
|
|
|
|
if ((CapsuleFmpEntry == NULL) || (CapsuleFmpEntry->SetImage == NULL)) {
|
|
continue;
|
|
}
|
|
|
|
IsFoundWindowsUxCapsule = TRUE;
|
|
}
|
|
|
|
if (FmpImageInfoBuf != NULL) {
|
|
FreePool (FmpImageInfoBuf);
|
|
FmpImageInfoBuf = NULL;
|
|
}
|
|
|
|
if (IsFoundWindowsUxCapsule) {
|
|
CapsuleFmpEntry->SetImage = L05WindowsUxSetImage;
|
|
break;
|
|
}
|
|
}
|
|
|
|
FreePool (HandleBuffer);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
Init BIOS Update UI for capsule update.
|
|
|
|
@param None
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others An unexpected error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
L05InitCapsuleUpdate (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
H2O_CP_HANDLE CpHandle;
|
|
VOID *Registration;
|
|
|
|
CpHandle = NULL;
|
|
Registration = NULL;
|
|
|
|
//
|
|
// Set BIOS update String.
|
|
//
|
|
Status = L05SetBiosUpdateString ();
|
|
|
|
//
|
|
// Hook progress bar to L05 BIOS Update UI.
|
|
//
|
|
if (FeaturePcdGet (PcdH2OBdsCpCapsuleUpdateProgressSupported)) {
|
|
Status = H2OCpRegisterHandler (
|
|
&gH2OBdsCpCapsuleUpdateProgressGuid,
|
|
CapsuleUpdateProgressHandler,
|
|
H2O_CP_MEDIUM,
|
|
&CpHandle
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG_CP ((DEBUG_ERROR, "Checkpoint Register Fail: %g (%r)\n", &gH2OBdsCpCapsuleUpdateProgressGuid, Status));
|
|
return Status;
|
|
}
|
|
|
|
DEBUG_CP ((DEBUG_INFO, "Checkpoint Registered: %g (%r)\n", &gH2OBdsCpCapsuleUpdateProgressGuid, Status));
|
|
}
|
|
|
|
//
|
|
// Hook Windows Ux Set Image to L05 BIOS Update UI.
|
|
//
|
|
EfiCreateProtocolNotifyEvent (
|
|
&gEfiFirmwareManagementProtocolGuid,
|
|
TPL_NOTIFY,
|
|
L05HookWindowsUxSetImage,
|
|
NULL,
|
|
&Registration
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Callback from checkpoint ReadyToBootBefore or NoBootDevice for BIOS Update UI for Secure Flash.
|
|
1. Paint BIOS update warning message.
|
|
2. Install gH2OCapsuleUpdateProgressProtocolGuid protocol for tool side to send capsule update percentage to BIOS.
|
|
|
|
@param[in] Event A pointer to the Event that triggered the callback.
|
|
@param[in] CpHandle Checkpoint handle.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
EFIAPI
|
|
L0SecureFlashUiCallback (
|
|
IN EFI_EVENT Event,
|
|
IN H2O_CP_HANDLE CpHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
IMAGE_INFO ImageInfo;
|
|
UINTN ImageInfoSize;
|
|
H2O_CAPSULE_UPDATE_PROGRESS_PROTOCOL *CapsuleUpdateProgressProtocol;
|
|
EFI_HANDLE Handle;
|
|
|
|
CapsuleUpdateProgressProtocol = NULL;
|
|
Handle = NULL;
|
|
|
|
H2OCpUnregisterHandler (CpHandle);
|
|
|
|
ImageInfoSize = sizeof (IMAGE_INFO);
|
|
Status = gRT->GetVariable (
|
|
SECURE_FLASH_INFORMATION_NAME,
|
|
&gSecureFlashInfoGuid,
|
|
NULL,
|
|
&ImageInfoSize,
|
|
&ImageInfo
|
|
);
|
|
|
|
if ((Status == EFI_SUCCESS) && (ImageInfo.FlashMode)) {
|
|
|
|
CapsuleUpdateProgressProtocol = AllocateZeroPool (sizeof (H2O_CAPSULE_UPDATE_PROGRESS_PROTOCOL));
|
|
|
|
if (CapsuleUpdateProgressProtocol == NULL) {
|
|
return;
|
|
}
|
|
|
|
DisplayBootLogo ();
|
|
|
|
//
|
|
// Paint BIOS update warning message.
|
|
//
|
|
Status = L05BiosUpdateWarningMsg (TRUE);
|
|
|
|
//
|
|
// Install gH2OCapsuleUpdateProgressProtocolGuid protocol for tool side to send capsule update
|
|
// percentage to BIOS.
|
|
//
|
|
Handle = NULL;
|
|
CapsuleUpdateProgressProtocol->CapsuleUpdateProgress = L05ProgressBar;
|
|
Status = gBS->InstallProtocolInterface (
|
|
&Handle,
|
|
&gH2OCapsuleUpdateProgressProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
CapsuleUpdateProgressProtocol
|
|
);
|
|
|
|
//
|
|
// Init BIOS update error message.
|
|
//
|
|
Status = InitFlashFirmwareToolErrorProcess ();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
Init BIOS Update UI for Secure Flash.
|
|
|
|
@param None
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others An unexpected error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
L05InitSecureFlash (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
H2O_CP_HANDLE CpHandle;
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
if (FeaturePcdGet (PcdH2OBdsCpReadyToBootBeforeSupported)) {
|
|
CpHandle = NULL;
|
|
Status = H2OCpRegisterHandler (
|
|
&gH2OBdsCpReadyToBootBeforeGuid,
|
|
L0SecureFlashUiCallback,
|
|
H2O_CP_MEDIUM,
|
|
&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));
|
|
}
|
|
|
|
if (FeaturePcdGet (PcdH2OBdsCpNoBootDeviceSupported)) {
|
|
CpHandle = NULL;
|
|
Status = H2OCpRegisterHandler (
|
|
&gH2OBdsCpNoBootDeviceGuid,
|
|
L0SecureFlashUiCallback,
|
|
H2O_CP_MEDIUM,
|
|
&CpHandle
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG_CP ((DEBUG_ERROR, "Checkpoint Register Fail: %g (%r)\n", &gH2OBdsCpNoBootDeviceGuid, Status));
|
|
return Status;
|
|
}
|
|
|
|
DEBUG_CP ((DEBUG_INFO, "Checkpoint Registered: %g (%r)\n", &gH2OBdsCpNoBootDeviceGuid, Status));
|
|
}
|
|
|
|
#if (FixedPcdGet32 (PcdL05ChipsetName) == L05_CHIPSET_NAME_ALDERLAKE)
|
|
if (FeaturePcdGet (PcdH2OBiosUpdateFaultToleranceEnabled)) {
|
|
if (FeaturePcdGet (PcdH2OBdsCpEndOfDxeBeforeSupported)) {
|
|
//
|
|
// The flash update procedure must be processed before end of dxe in some cases.
|
|
// For instance, TopSwap control may not be availabled after end of dxe.
|
|
//
|
|
CpHandle = NULL;
|
|
Status = H2OCpRegisterHandler (
|
|
&gH2OBdsCpEndOfDxeBeforeGuid,
|
|
L0SecureFlashUiCallback,
|
|
H2O_CP_MEDIUM,
|
|
&CpHandle
|
|
);
|
|
|
|
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));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Show error message of SecureErrorMessageCallBack () for BIOS Update UI.
|
|
|
|
@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.
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
L05SecureFlashErrorMsgNotify (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS *ErrorStatus;
|
|
EFI_STATUS Status;
|
|
CHAR16 *StringPtr;
|
|
UINTN StringSize;
|
|
L05_FLASH_FIRMWARE_TOOL_ERROR_PROCESS_PROTOCOL *FlashErrorProcessProtocol;
|
|
|
|
ErrorStatus = NULL;
|
|
StringPtr = NULL;
|
|
FlashErrorProcessProtocol = NULL;
|
|
|
|
//
|
|
// Check mSecureFlashErrorMsgGuid is ready.
|
|
//
|
|
Status = gBS->LocateProtocol (
|
|
&mSecureFlashErrorMsgGuid,
|
|
NULL,
|
|
(VOID **) &ErrorStatus
|
|
);
|
|
|
|
if (EFI_ERROR (Status) || (ErrorStatus == NULL)) {
|
|
return;
|
|
}
|
|
|
|
if (mHiiHandle == NULL) {
|
|
return;
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiL05FlashFirmwareToolErrorProcessProtocolGuid,
|
|
NULL,
|
|
(VOID **) &FlashErrorProcessProtocol
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
switch (*ErrorStatus) {
|
|
|
|
case EFI_ACCESS_DENIED:
|
|
StringPtr = HiiGetString (mHiiHandle, STRING_TOKEN (L05_STR_SECURE_FLASH_ACCESS_DENIED), NULL);
|
|
break;
|
|
|
|
case EFI_SUCCESS:
|
|
StringPtr = HiiGetString (mHiiHandle, STRING_TOKEN (L05_STR_SECURE_FLASH_SUCCESS), NULL);
|
|
break;
|
|
|
|
case EFI_INVALID_PARAMETER:
|
|
StringPtr = HiiGetString (mHiiHandle, STRING_TOKEN (L05_STR_SECURE_FLASH_INVALID_PARAMETER), NULL);
|
|
break;
|
|
|
|
case EFI_BUFFER_TOO_SMALL:
|
|
StringPtr = HiiGetString (mHiiHandle, STRING_TOKEN (L05_STR_SECURE_FLASH_BUFFER_TOO_SMALL), NULL);
|
|
break;
|
|
|
|
default:
|
|
StringPtr = HiiGetString (mHiiHandle, STRING_TOKEN (L05_STR_SECURE_FLASH_FAILED), NULL);
|
|
break;
|
|
|
|
}
|
|
|
|
if (StringPtr != NULL) {
|
|
StringSize = StrSize (StringPtr);
|
|
PcdSetPtrS (PcdL05BiosUpdateUiErrorCodeString, &StringSize, (VOID *) StringPtr);
|
|
FreePool (StringPtr);
|
|
StringPtr = NULL;
|
|
}
|
|
|
|
StringPtr = HiiGetString (mHiiHandle, STRING_TOKEN (L05_STR_SECURE_FLASH_PRESS_ANY_KEY), NULL);
|
|
FlashErrorProcessProtocol->ErrorProcess (*ErrorStatus, StringPtr);
|
|
FreePool (StringPtr);
|
|
StringPtr = NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
Init BIOS Update UI.
|
|
|
|
@param None
|
|
|
|
@retval EFI_SUCCESS The operation completed successfully.
|
|
@retval Others An unexpected error occurred.
|
|
**/
|
|
EFI_STATUS
|
|
L05InitBiosUpdateUi (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS FunStatus;
|
|
VOID *Registration;
|
|
|
|
Status = EFI_SUCCESS;
|
|
FunStatus = EFI_SUCCESS;
|
|
Registration = NULL;
|
|
|
|
FunStatus = InitHiiHandle ();
|
|
if (EFI_ERROR (FunStatus)) {
|
|
Status = FunStatus;
|
|
}
|
|
|
|
FunStatus = L05InitCapsuleUpdate ();
|
|
|
|
if (EFI_ERROR (FunStatus)) {
|
|
Status = FunStatus;
|
|
}
|
|
|
|
FunStatus = L05InitSecureFlash ();
|
|
|
|
if (EFI_ERROR (FunStatus)) {
|
|
Status = FunStatus;
|
|
}
|
|
|
|
//
|
|
// Register mSecureFlashErrorMsgGuid protocol notify function.
|
|
//
|
|
EfiCreateProtocolNotifyEvent (
|
|
&mSecureFlashErrorMsgGuid,
|
|
TPL_NOTIFY,
|
|
L05SecureFlashErrorMsgNotify,
|
|
NULL,
|
|
&Registration
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|