816 lines
26 KiB
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;
|
|
}
|