alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/CapsuleIFWU/CapsuleLib/ChipsetCapsuleLib.c

816 lines
26 KiB
C

/** @file
Library instance to Capsule Update Criteria check
;******************************************************************************
;* Copyright (c) 2012 - 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.
;*
;******************************************************************************
*/
#include <Uefi.h>
//[-start-190613-IB16990069-add]//
#include <H2OIhisi.h>
//[-end-190613-IB16990069-add]//
#include <Library/UefiLib.h>
#include <Library/PcdLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/FdSupportLib.h>
#include <Library/FlashRegionLib.h>
#include <Library/VariableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Guid/EfiSystemResourceTable.h>
#include <Guid/IshUpdVariable.h>
#include <Guid/PdtUpdVariable.h>
#include <Library/ChipsetCapsuleLib.h>
#include <Library/FWUpdateLib.h>
#include <Protocol/FirmwareManagement.h>
#include <Library/PchInfoLib.h>
#include <MkhiMsgs.h>
#include <MeBiosPayloadHob.h>
#include <Library/HobLib.h>
//[-start-220103-BAIN000082-add]//
#ifdef LCFC_SUPPORT
#include <Library/LfcEcLib.h>
#endif
//[-end-220103-BAIN000082-add]//
STATIC UINT8 InsydeMeSig[] = {'_', 'M', 'E', '_','I', 'M', 'G', '_'};
STATIC UINT8 IntelIshSig[] = {'_', 'I', 'S', 'H','_', 'I', 'M', 'G'};
STATIC UINT8 IntelEcSig[] = {'T', 'K', 'S', 'C'};
STATIC UINT8 InsydeIomSig[] = {'_', 'I', 'O', 'M','_','I', 'M', 'G'};
STATIC UINT8 InsydeMgPhySig[] = {'_', 'M', 'G', 'P','H','Y', '_', '_'};
STATIC UINT8 InsydeTbtSig[] = {'_', 'T', 'B', 'T','_','I', 'M', 'G'};
STATIC UINT8 IntelBtGAcmSig[] = {0xAA, 0x3A, 0xC0, 0x7F, 0xA7, 0x46, 0xDB, 0x18, 0x2E, 0xAC, 0x69, 0x8F, 0x8D, 0x41, 0x7F, 0x5A}; //gTxtAcmInfoTableGuid
EFI_BOOT_SERVICES *BS = NULL;
//
// MSFT compiler uses this variable to inform itself whether floating
// point support is loaded.
//
static int _fltused;
//[-start-190613-IB16990069-add]//
UINT8 mAcStatus = AC_PlugIn;
UINT8 mBatteryLife = 0x64;
UINT8 mBatteryLowBound = 0;
/**
Check if this is PCH XXX series in PchInfoLib
@retval TRUE It's PCH LP series
@retval FALSE It's not PCH LP series
**/
typedef
BOOLEAN
(*IS_PCH_SERIES) (
VOID
);
typedef struct {
PCH_GENERATION PchGeneration;
IS_PCH_SERIES IsPchSeries;
UINT8 MeImageType;
EFI_GUID *ImageTypeIdGuid;
} ME_IMAGE_TYPE_ID_GUID_INFO;
ME_IMAGE_TYPE_ID_GUID_INFO mMeFwImageTypeIdGuidList[] = {
{ ADL_PCH, IsPchLp, IntelMeConsumerFw, &gFmpDeviceMeFwAdlLpConsGuid },
{ ADL_PCH, IsPchH, IntelMeConsumerFw, &gFmpDeviceMeFwAdlHConsGuid },
{ ADL_PCH, IsPchLp, IntelMeCorporateFw, &gFmpDeviceMeFwAdlLpCorpGuid },
{ ADL_PCH, IsPchH, IntelMeCorporateFw, &gFmpDeviceMeFwAdlHCorpGuid }
};
UINT8
EFIAPI
GetPlatformInfo (
IN OUT UINT8 *FbtsBuffer,
IN UINT16 SmiPort
);
UINT8
EFIAPI
MeGetCmdBuffer (
OUT UINT32 *CmdBuffer,
IN UINT16 SmiPort
);
EFI_STATUS
EFIAPI
GetImageTypeIdGuidPtr (
OUT EFI_GUID **Guid
)
{
UINT8 MeImageType;
PCH_GENERATION PchGen;
UINT8 Index;
ME_BIOS_PAYLOAD_HOB *MeBiosPayloadHob;
DEBUG ((DEBUG_INFO, "GetImageTypeIdGuidPtr (ME)\n"));
if (Guid == NULL) {
return EFI_INVALID_PARAMETER;
}
MeBiosPayloadHob = GetFirstGuidHob (&gMeBiosPayloadHobGuid);
if (MeBiosPayloadHob != NULL) {
PchGen = PchGeneration ();
MeImageType = (UINT8) MeBiosPayloadHob->MeBiosPayload.FwPlatType.RuleData.Fields.IntelMeFwImageType;
DEBUG ((DEBUG_INFO, "MeImageType = %x\n", MeImageType));
for (Index = 0; Index < sizeof (mMeFwImageTypeIdGuidList) / sizeof (ME_IMAGE_TYPE_ID_GUID_INFO); Index++) {
// To check PCH generation, PCH series, and GUID match to image
if ((PchGen == mMeFwImageTypeIdGuidList[Index].PchGeneration) && \
(mMeFwImageTypeIdGuidList[Index].IsPchSeries ()) && \
(MeImageType == mMeFwImageTypeIdGuidList[Index].MeImageType)) {
*Guid = mMeFwImageTypeIdGuidList[Index].ImageTypeIdGuid;
DEBUG ((DEBUG_INFO, "Report ME FMP ImageTypeID = %g.\n", *Guid));
return EFI_SUCCESS;
}
}
DEBUG ((DEBUG_ERROR, "Did not find a match.\n"));
}
return EFI_UNSUPPORTED;
}
VOID
EFIAPI
UpdatePlatformStatus (
VOID
)
{
EFI_STATUS Status;
FBTS_TOOLS_VERSION_BUFFER *FbtsSupportBuffer;
UINT32 CmdBuffer;
UINT8 IhisiStatus;
FbtsSupportBuffer = NULL;
IhisiStatus = MeGetCmdBuffer (&CmdBuffer, PcdGet16 (PcdSoftwareSmiPort));
if (IhisiStatus != 0) {
Status = gBS->AllocatePool (EfiBootServicesData, sizeof(FBTS_TOOLS_VERSION_BUFFER), (VOID **) &FbtsSupportBuffer);
if (Status != EFI_SUCCESS) {
return;
}
} else {
FbtsSupportBuffer = (FBTS_TOOLS_VERSION_BUFFER *) ((UINTN) CmdBuffer);
}
gBS->SetMem (FbtsSupportBuffer, sizeof(FBTS_TOOLS_VERSION_BUFFER), 0);
//
// Append signature for IHISI identification
//
FbtsSupportBuffer->Signature = FBTS_VERSION_SIGNATURE;
//
// Call IHISI FBTS 10h
//
GetPlatformInfo ((UINT8 *) FbtsSupportBuffer, PcdGet16 (PcdSoftwareSmiPort));
mAcStatus = ((FBTS_PLATFORM_STATUS_BUFFER *) FbtsSupportBuffer)->AcStatus;
mBatteryLife = ((FBTS_PLATFORM_STATUS_BUFFER *) FbtsSupportBuffer)->Battery;
mBatteryLowBound = ((FBTS_PLATFORM_STATUS_BUFFER *) FbtsSupportBuffer)->Bound;
if (IhisiStatus != 0) {
gBS->FreePool (FbtsSupportBuffer);
}
}
//[-end-190613-IB16990069-add]//
/**
Get system firmware revision for ESRT from capsule image
@param CapsuleHeader Points to a capsule header.
@return The system firmware revision from the capsule image
If the signature cannot be found, 0x00000000 will
be returned
**/
UINT32
EFIAPI
GetIntelMeCapsuleFirmwareVersion (
IN EFI_CAPSULE_HEADER *CapsuleHeader
)
{
UINTN Index;
EFI_STATUS Status;
UINTN Size;
UINT16 BufferMajor;
UINT16 BufferMinor;
UINT16 BufferHotfix;
UINT16 BufferBuild;
UINT8 *FwCapsuleImage;
UINT32 FwImageSize;
UINT32 FwVersion;
//[-start-190613-IB16990069-add]//
UINT8 MajorNum;
UINT8 MinorNum;
UINT8 Revision;
EFI_GUID *MeCapsuleGuid;
BS = gBS;
BufferMajor = 0;
BufferMinor = 0;
BufferHotfix = 0;
BufferBuild = 0;
FwCapsuleImage = NULL;
FwImageSize = 0;
FwVersion = 0x00;
MajorNum = 0;
MinorNum = 0;
Revision = 0;
MeCapsuleGuid = NULL;
//[-end-190613-IB16990069-add]//
Status = GetImageTypeIdGuidPtr (&MeCapsuleGuid);
if (CompareGuid (&CapsuleHeader->CapsuleGuid, MeCapsuleGuid) || CompareGuid (&CapsuleHeader->CapsuleGuid, PcdGetPtr (PcdWindowsMeFirmwareCapsuleGuid))) {
for (Index = 0; Index < CapsuleHeader->CapsuleImageSize; Index++) {
FwCapsuleImage = (UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize + Index;
if (CompareMem (FwCapsuleImage, InsydeMeSig, sizeof (InsydeMeSig)) == 0) {
//
// Find the signed image of signature
//
FwImageSize = *(UINT32 *)(FwCapsuleImage + 0x0C);
FwCapsuleImage += 0x10;
Status = FwuPartitionVersionFromBuffer(FwCapsuleImage, FwImageSize, FPT_PARTITION_NAME_FTPR, &BufferMajor, &BufferMinor, &BufferHotfix, &BufferBuild);
if (Status == EFI_SUCCESS){
if (CompareGuid(&CapsuleHeader->CapsuleGuid, MeCapsuleGuid)) {
//
// Fmp Me version = 0xMMHHBBBB
// MM: Minor version of CSMEFW
// HH: Hotfix value of CSMEFW
// BBBB: Build version of CSMEFW
//
FwVersion = (UINT32)((UINT8)BufferMinor << 24 | (UINT8)BufferHotfix << 16 | BufferBuild);
return FwVersion;
} else {
return BufferBuild;
}
}
}
}
}
if (CompareGuid(&CapsuleHeader->CapsuleGuid, PcdGetPtr (PcdWindowsIshFirmwareCapsuleGuid))) {
for (Index = 0; Index < CapsuleHeader->CapsuleImageSize; Index++) {
FwCapsuleImage = (UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize + Index;
if (CompareMem (FwCapsuleImage, IntelIshSig, sizeof (IntelIshSig)) == 0) {
//
// Get ISH Version
//
FwImageSize = *(UINT32 *)(FwCapsuleImage + 0x0C);
FwCapsuleImage += 0x10;
Status = FwuPartitionVersionFromBuffer(FwCapsuleImage, FwImageSize, FPT_PARTITION_NAME_ISHC, &BufferMajor, &BufferMinor, &BufferHotfix, &BufferBuild);
if (Status == EFI_SUCCESS){
return BufferBuild;
}
}
}
}
if (CompareGuid(&CapsuleHeader->CapsuleGuid, PcdGetPtr (PcdWindowsPdtFirmwareCapsuleGuid))) {
//
// Get PDT version
//
Size = sizeof (FwVersion);
Status = gRT->GetVariable (
L"PdtUpdVersion",
&gPdtUpdCountGuid,
NULL,
&Size,
&FwVersion
);
if (!EFI_ERROR (Status)) {
return FwVersion;
}
}
if (CompareGuid(&CapsuleHeader->CapsuleGuid, PcdGetPtr (PcdWindowsEcFirmwareCapsuleGuid))) {
for (Index = 0; Index < CapsuleHeader->CapsuleImageSize; Index++) {
FwCapsuleImage = (UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize + Index;
if (CompareMem (FwCapsuleImage, IntelEcSig, sizeof (IntelEcSig)) == 0) {
//
// Get EC Version
//
//[-start-190613-IB16990069-add]//
CopyMem (&MajorNum, FwCapsuleImage + 0x5, 1);
CopyMem (&MinorNum, FwCapsuleImage + 0x6, 1);
FwVersion = ((FwVersion | (UINT32) MajorNum) << 8) + (UINT32) MinorNum;
//[-end-190613-IB16990069-add]//
return FwVersion;
}
}
}
if (CompareGuid(&CapsuleHeader->CapsuleGuid, PcdGetPtr (PcdWindowsIomFirmwareCapsuleGuid))) {
for (Index = 0; Index < CapsuleHeader->CapsuleImageSize; Index++) {
FwCapsuleImage = (UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize + Index;
if (CompareMem (FwCapsuleImage, InsydeIomSig, sizeof (InsydeIomSig)) == 0) {
//
// Get IOM Version
//
FwImageSize = *(UINT32 *)(FwCapsuleImage + 0x0C);
FwCapsuleImage += 0x10;
Status = FwuPartitionVersionFromBuffer(FwCapsuleImage, FwImageSize, FPT_PARTITION_NAME_IOMP, &BufferMajor, &BufferMinor, &BufferHotfix, &BufferBuild);
if (Status == EFI_SUCCESS){
FwVersion = (UINT32) (BufferMajor << 8) + BufferMinor;
return FwVersion;
}
}
}
}
if (CompareGuid(&CapsuleHeader->CapsuleGuid, PcdGetPtr (PcdWindowsMgPhyFirmwareCapsuleGuid))) {
for (Index = 0; Index < CapsuleHeader->CapsuleImageSize; Index++) {
FwCapsuleImage = (UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize + Index;
if (CompareMem (FwCapsuleImage, InsydeMgPhySig, sizeof (InsydeMgPhySig)) == 0) {
//
// Get MG PHY Version
//
FwImageSize = *(UINT32 *)(FwCapsuleImage + 0x0C);
FwCapsuleImage += 0x10;
Status = FwuPartitionVersionFromBuffer(FwCapsuleImage, FwImageSize, FPT_PARTITION_NAME_NPHY, &BufferMajor, &BufferMinor, &BufferHotfix, &BufferBuild);
if (Status == EFI_SUCCESS){
FwVersion = (UINT32)(BufferHotfix << 8) + BufferBuild;
return FwVersion;
}
}
}
}
if (CompareGuid(&CapsuleHeader->CapsuleGuid, PcdGetPtr (PcdWindowsTbtFirmwareCapsuleGuid))) {
for (Index = 0; Index < CapsuleHeader->CapsuleImageSize; Index++) {
FwCapsuleImage = (UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize + Index;
if (CompareMem (FwCapsuleImage, InsydeTbtSig, sizeof (InsydeTbtSig)) == 0) {
//
// Get TBT Version
//
FwImageSize = *(UINT32 *)(FwCapsuleImage + 0x0C);
FwCapsuleImage += 0x10;
Status = FwuPartitionVersionFromBuffer(FwCapsuleImage, FwImageSize, FPT_PARTITION_NAME_TBTP, &BufferMajor, &BufferMinor, &BufferHotfix, &BufferBuild);
if (Status == EFI_SUCCESS){
return BufferBuild;
}
}
}
}
if (CompareGuid(&CapsuleHeader->CapsuleGuid, PcdGetPtr (PcdWindowsBtGAcmFirmwareCapsuleGuid))) {
for (Index = 0; Index < CapsuleHeader->CapsuleImageSize; Index++) {
FwCapsuleImage = (UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize + Index;
if (CompareMem (FwCapsuleImage, IntelBtGAcmSig, sizeof (IntelBtGAcmSig)) == 0) {
CopyMem (&MajorNum, FwCapsuleImage + 0x25, 1);
CopyMem (&MinorNum, FwCapsuleImage + 0x26, 1);
CopyMem (&Revision, FwCapsuleImage + 0x27, 1);
FwVersion = ((FwVersion | (UINT32) MajorNum) << 8) + (UINT32) MinorNum;
FwVersion = (FwVersion << 8) + (UINT32) Revision;
return FwVersion;
}
}
}
return 0;
}
/**
Return ISH, PDT, IOM, PHY, TBT firmware revision in current build.
@param[in, out] FwVersion Points to the firmware revision.
@param[in] FirwareType Firmware type.
@retval EFI_SUCCESS Get the firmware revision successfully
@return others Fail to get the firmware revision
**/
EFI_STATUS
EFIAPI
GetFirmwareVersion (
IN OUT UINT32 *FwVersion,
IN UINT8 FirwareType
)
{
EFI_STATUS Status;
UINT16 Major;
UINT16 Minor;
UINT16 Hotfix;
UINT16 Build;
UINTN Size;
Major = 0;
Minor = 0;
Hotfix = 0;
Build = 0;
//[-start-190611-IB16990047-add]//
Status = EFI_INVALID_PARAMETER;
//[-end-190611-IB16990047-add]//
//
// Apply the function call of ME FW Update API library kit to get the firmware revision
//
switch (FirwareType) {
case IshFirmware:
case PdtFirmware:
Status = FwuPartitionVersionFromFlash(FPT_PARTITION_NAME_ISHC, &Major, &Minor, &Hotfix, &Build);
if (Status == EFI_SUCCESS) {
*FwVersion = (UINT32) Build;
Size = sizeof (UINT32);
Status = CommonSetVariable (
L"IshFwVersion",
&gIshUpdVerGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
Size,
FwVersion
);
}
break;
case IomFirmware:
Status = FwuPartitionVersionFromFlash(FPT_PARTITION_NAME_IOMP, &Major, &Minor, &Hotfix, &Build);
if (Status == EFI_SUCCESS) {
*FwVersion = (UINT32) (Major << 8) + Minor;
}
break;
case MgPhyFirmware:
Status = FwuPartitionVersionFromFlash(FPT_PARTITION_NAME_NPHY, &Major, &Minor, &Hotfix, &Build);
*FwVersion = (UINT32) (Hotfix << 8) + Build;
break;
case TbtFirmware:
Status = FwuPartitionVersionFromFlash(FPT_PARTITION_NAME_TBTP, &Major, &Minor, &Hotfix, &Build);
if (Status == EFI_SUCCESS) {
*FwVersion = (UINT32) Build;
}
break;
default:
break;
}
if (Status != EFI_SUCCESS){
DEBUG ((DEBUG_ERROR | DEBUG_INFO, "FwuPartitionVersionFromFlash error: %d, FirwareType: %d\n", Status, FirwareType));
return Status;
}
return Status;
}
/**
AC power source existence check
@param CapsuleHeader Points to a capsule header.
@retval TRUE Criteria check is successful
@return others Failed to pass the criteria check
**/
BOOLEAN
EFIAPI
AcPowerCheck (
EFI_CAPSULE_HEADER *CapsuleHeader
)
{
//[-start-220103-BAIN000082-modify]//
#ifdef LCFC_SUPPORT
BOOLEAN PowerStateIsAc = TRUE;
LfcEcLibPowerStateIsAc(&PowerStateIsAc);
if (PowerStateIsAc == FALSE) {
return FALSE;
}
return TRUE;
#else
//[-start-190613-IB16990069-add]//
if (mAcStatus == AC_PlugOut) {
return FALSE;
}
//[-end-190613-IB16990069-add]//
return TRUE;
#endif
//[-end-220103-BAIN000082-modify]//
}
/**
Battery power check
@param CapsuleHeader Points to a capsule header.
@retval TRUE Criteria check is successful
@return others Failed to pass the criteria check
**/
BOOLEAN
EFIAPI
BatteryPowerCheck (
EFI_CAPSULE_HEADER *CapsuleHeader
)
{
//[-start-190613-IB16990069-add]//
if (mBatteryLife < mBatteryLowBound) {
return FALSE;
}
//[-end-190613-IB16990069-add]//
return TRUE;
}
/**
Security check
@param CapsuleHeader Points to a capsule header.
@retval TRUE Criteria check is successful
@return others Failed to pass the criteria check
**/
BOOLEAN
EFIAPI
SecurityCheck (
EFI_CAPSULE_HEADER *CapsuleHeader
)
{
return TRUE;
}
/**
Capsule image integrity check
@param CapsuleHeader Points to a capsule header.
@retval TRUE Criteria check is successful
@return others Failed to pass the criteria check
**/
BOOLEAN
EFIAPI
IntegrityCheck (
EFI_CAPSULE_HEADER *CapsuleHeader
)
{
return TRUE;
}
/**
Get FMP LowestSupportedImageVersion by ImageTypeId.
@param[in] ImageTypeId Used to identify device firmware targeted by this update.
@param[out] LowestSupportedImageVersion Describes the lowest ImageDescriptor version that the device will accept.
@retval EFI_SUCCESS LowestSupportedImageVersion is found in existing FMP instances.
@retval EFI_NOT_FOUND No FMP instances match the search.
@retval EFI_INVALID_PARAMETER Invalid parameters.
**/
EFI_STATUS
GetFmpLowestSupportedImageVersionByImageTypeId (
IN EFI_GUID *ImageTypeId,
OUT UINT32 *LowestSupportedImageVersion
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
UINTN NumberOfHandles;
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
UINTN Index;
UINTN Index2;
UINTN ImageInfoSize;
EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
UINT32 FmpImageInfoDescriptorVer;
UINT8 FmpImageInfoCount;
UINTN DescriptorSize;
UINT32 PackageVersion;
CHAR16 *PackageVersionName;
EFI_FIRMWARE_IMAGE_DESCRIPTOR *TempFmpImageInfo;
if ((ImageTypeId == NULL) || (LowestSupportedImageVersion == NULL)) {
return EFI_INVALID_PARAMETER;
}
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiFirmwareManagementProtocolGuid,
NULL,
&NumberOfHandles,
&HandleBuffer
);
if (EFI_ERROR(Status)) {
return Status;
}
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 = 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 (EFI_ERROR(Status)) {
FreePool(FmpImageInfoBuf);
continue;
}
if (PackageVersionName != NULL) {
FreePool(PackageVersionName);
}
TempFmpImageInfo = FmpImageInfoBuf;
for (Index2 = 0; Index2 < FmpImageInfoCount; Index2++) {
//
// Check if this FMP instance matches.
// LowestSupportedImageVersion is introduced with DescriptorVersion 2+
//
if ((CompareGuid(ImageTypeId, &TempFmpImageInfo->ImageTypeId)) && FmpImageInfoDescriptorVer >= 2) {
*LowestSupportedImageVersion = TempFmpImageInfo->LowestSupportedImageVersion;
FreePool (FmpImageInfoBuf);
FreePool (HandleBuffer);
return EFI_SUCCESS;
}
TempFmpImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)TempFmpImageInfo + DescriptorSize);
}
FreePool (FmpImageInfoBuf);
}
FreePool (HandleBuffer);
return EFI_NOT_FOUND;
}
/**
Firmware version check
@param[in] CapsuleHeader Points to a capsule header.
@retval TRUE Criteria check is successful
@return others Failed to pass the criteria check
**/
BOOLEAN
EFIAPI
MEVersionCheck (
IN EFI_CAPSULE_HEADER *CapsuleHeader
)
{
EFI_STATUS Status;
EFI_SYSTEM_RESOURCE_TABLE *Esrt;
UINTN Index;
UINT32 LowestSupportedImageVersion;
//
// If capsule is Monolithic capsule, skip this check
//
if(CompareGuid (&CapsuleHeader->CapsuleGuid, PcdGetPtr (PcdWindowsMonolithicFirmwareCapsuleGuid))) {
return TRUE;
}
Status = EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid, (VOID **)&Esrt);
if (Status == EFI_SUCCESS && Esrt != NULL) {
for (Index = 0; Index < Esrt->FirmwareResourceCount; Index++) {
if (CompareGuid (&Esrt->FirmwareResources[Index].FirmwareClass, &CapsuleHeader->CapsuleGuid)) {
if (GetIntelMeCapsuleFirmwareVersion (CapsuleHeader) >= Esrt->FirmwareResources[Index].LowestSupportedFirmwareVersion) {
return TRUE;
}
}
}
}
//
// ESRT may not installed. Check version with FMP instances.
//
LowestSupportedImageVersion = 0;
Status = GetFmpLowestSupportedImageVersionByImageTypeId (&CapsuleHeader->CapsuleGuid, &LowestSupportedImageVersion);
if (Status == EFI_SUCCESS) {
if (GetIntelMeCapsuleFirmwareVersion (CapsuleHeader) >= LowestSupportedImageVersion) {
return TRUE;
}
}
return FALSE;
}
/**
Storage check
@param CapsuleHeader Points to a capsule header.
@retval TRUE Criteria check is successful
@return others Failed to pass the criteria check
**/
BOOLEAN
EFIAPI
StorageCheck (
EFI_CAPSULE_HEADER *CapsuleHeader
)
{
return TRUE;
}
/**
Pre-installation check for Capsule Update
@param CapsuleHeader Points to a capsule header.
@retval ESRT_SUCCESS The Capsule passed the pre-installation criteria
@retval ESRT_ERROR_UNSUCCESSFUL The pre-installation criteria check failed
@retval ESRT_ERROR_INSUFFICIENT_RESOURCES Out of memory or persistent storage
@retval ESRT_ERROR_INCORRECT_VERSION Incorrect/incompatible firmware version
@retval ESRT_ERROR_INVALID_IMAGE_FORMAT Invalid Capsule image format
@retval ESRT_ERROR_AUTHENTICATION Capsule image authentication failed
@retval ESRT_ERROR_AC_NOT_CONNECTED The system is not connected to the AC power
@retval ESRT_ERROR_INSUFFICIENT_BATTERY The battery capacity is low
**/
ESRT_STATUS
EFIAPI
MEPreInstallationCheck (
EFI_CAPSULE_HEADER *Capsule
)
{
//[-start-190613-IB16990069-add]//
UpdatePlatformStatus();
if (!BatteryPowerCheck(Capsule)) {
return ESRT_ERROR_INSUFFICIENT_BATTERY;
}
//
// According to Pre-installation criteria from MSFT,
// (1) System must have at least 25% battery charge.
// (2) Tethered power (power via USB cable and/or AC power) is not required.
// so needn't check AC power in PreInstallationCheck function.
//
//[-end-190613-IB16990069-add]//
//[-start-211116-FLINT00031-add]//
#ifdef LCFC_SUPPORT
//
// Follow Lenovo spec requirement,
// add interface to get AC status to check during Windows Capsule Update.
//
if (!AcPowerCheck(Capsule)) {
return ESRT_ERROR_AC_NOT_CONNECTED;
}
#endif
//[-end-211116-FLINT00031-add]//
if (!StorageCheck(Capsule)) {
return ESRT_ERROR_INSUFFICIENT_RESOURCES;
}
if (!IntegrityCheck(Capsule)) {
return ESRT_ERROR_INVALID_IMAGE_FORMAT;
}
if (!MEVersionCheck(Capsule)) {
return ESRT_ERROR_INCORRECT_VERSION;
}
if (!SecurityCheck(Capsule)) {
return ESRT_ERROR_AUTHENTICATION;
}
return ESRT_SUCCESS;
}
/**
Post-installation check for Capsule Update
@param CapsuleHeader Points to a capsule header.
@retval ESRT_SUCCESS The Capsule passed the pre-installation criteria
@retval ESRT_ERROR_UNSUCCESSFUL The pre-installation criteria check failed
@retval ESRT_ERROR_INSUFFICIENT_RESOURCES Out of memory or persistent storage
@retval ESRT_ERROR_AUTHENTICATION Capsule image authentication failed
**/
ESRT_STATUS
EFIAPI
PostInstallationCheck (
EFI_CAPSULE_HEADER *Capsule
)
{
return ESRT_SUCCESS;
}