2019-09-03 11:58:42 +02:00
|
|
|
/** @file
|
|
|
|
Publishes ESRT table from Firmware Management Protocol instances
|
|
|
|
|
|
|
|
Copyright (c) 2016, Microsoft Corporation
|
|
|
|
Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
|
|
|
|
|
|
|
|
All rights reserved.
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include <Uefi.h>
|
|
|
|
#include <Library/BaseLib.h>
|
|
|
|
#include <Library/BaseMemoryLib.h>
|
|
|
|
#include <Library/MemoryAllocationLib.h>
|
|
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
|
|
#include <Library/DebugLib.h>
|
|
|
|
#include <Library/PcdLib.h>
|
|
|
|
#include <Library/UefiLib.h>
|
|
|
|
#include <Protocol/FirmwareManagement.h>
|
|
|
|
#include <Guid/EventGroup.h>
|
|
|
|
#include <Guid/SystemResourceTable.h>
|
|
|
|
|
|
|
|
///
|
|
|
|
/// Structure for array of unique GUID/HardwareInstance pairs from the
|
|
|
|
/// current set of EFI_FIRMWARE_IMAGE_DESCRIPTORs from all FMP Protocols.
|
|
|
|
///
|
|
|
|
typedef struct {
|
|
|
|
///
|
|
|
|
/// A unique GUID identifying the firmware image type.
|
|
|
|
///
|
|
|
|
EFI_GUID ImageTypeGuid;
|
|
|
|
///
|
|
|
|
/// An optional number to identify the unique hardware instance within the
|
|
|
|
/// system for devices that may have multiple instances whenever possible.
|
|
|
|
///
|
|
|
|
UINT64 HardwareInstance;
|
|
|
|
} GUID_HARDWAREINSTANCE_PAIR;
|
|
|
|
|
|
|
|
/**
|
|
|
|
Print ESRT to debug console.
|
|
|
|
|
|
|
|
@param[in] Table Pointer to the ESRT table.
|
|
|
|
|
|
|
|
**/
|
|
|
|
VOID
|
|
|
|
EFIAPI
|
|
|
|
PrintTable (
|
|
|
|
IN EFI_SYSTEM_RESOURCE_TABLE *Table
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Install EFI System Resource Table into the UEFI Configuration Table
|
|
|
|
|
|
|
|
@param[in] Table Pointer to the ESRT.
|
|
|
|
|
|
|
|
@return Status code.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
InstallEfiSystemResourceTableInUefiConfigurationTable (
|
|
|
|
IN EFI_SYSTEM_RESOURCE_TABLE *Table
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
if (Table->FwResourceCount == 0) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it has zero Entries. \n"));
|
|
|
|
Status = EFI_UNSUPPORTED;
|
|
|
|
} else {
|
|
|
|
//
|
|
|
|
// Install the pointer into config table
|
|
|
|
//
|
|
|
|
Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, Table);
|
2020-04-23 11:08:10 +02:00
|
|
|
if (EFI_ERROR(Status)) {
|
2019-09-03 11:58:42 +02:00
|
|
|
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table. Status: %r. \n", Status));
|
|
|
|
} else {
|
|
|
|
DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Installed ESRT table. \n"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo.
|
|
|
|
|
|
|
|
@param[in] FmpImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR
|
|
|
|
|
|
|
|
@return TRUE It is a system FMP.
|
|
|
|
@return FALSE It is a device FMP.
|
|
|
|
**/
|
|
|
|
BOOLEAN
|
|
|
|
IsSystemFmp (
|
|
|
|
IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo
|
|
|
|
)
|
|
|
|
{
|
|
|
|
GUID *Guid;
|
|
|
|
UINTN Count;
|
|
|
|
UINTN Index;
|
|
|
|
|
|
|
|
Guid = PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid);
|
|
|
|
Count = PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof(GUID);
|
|
|
|
|
|
|
|
for (Index = 0; Index < Count; Index++, Guid++) {
|
|
|
|
if (CompareGuid (&FmpImageInfo->ImageTypeId, Guid)) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Function to create a single ESRT Entry and add it to the ESRT with
|
|
|
|
a given FMP descriptor. If the GUID is already in the ESRT, then the ESRT
|
|
|
|
entry is updated.
|
|
|
|
|
|
|
|
@param[in,out] Table Pointer to the ESRT Table.
|
|
|
|
@param[in,out] HardwareInstances Pointer to the GUID_HARDWAREINSTANCE_PAIR.
|
|
|
|
@param[in,out] NumberOfDescriptors The number of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
|
|
|
|
@param[in] FmpImageInfoBuf Pointer to the EFI_FIRMWARE_IMAGE_DESCRIPTOR.
|
|
|
|
@param[in] FmpVersion FMP Version.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS FmpImageInfoBuf was use to fill in a new ESRT entry
|
|
|
|
in Table.
|
|
|
|
@retval EFI_SUCCESS The ImageTypeId GUID in FmpImageInfoBuf matches an
|
|
|
|
existing ESRT entry in Table, and the information
|
|
|
|
from FmpImageInfoBuf was merged into the the existing
|
|
|
|
ESRT entry.
|
|
|
|
@retval EFI_UNSPOORTED The GUID/HardareInstance in FmpImageInfoBuf has is a
|
|
|
|
duplicate.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
CreateEsrtEntry (
|
|
|
|
IN OUT EFI_SYSTEM_RESOURCE_TABLE *Table,
|
|
|
|
IN OUT GUID_HARDWAREINSTANCE_PAIR *HardwareInstances,
|
|
|
|
IN OUT UINT32 *NumberOfDescriptors,
|
|
|
|
IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf,
|
|
|
|
IN UINT32 FmpVersion
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN Index;
|
|
|
|
EFI_SYSTEM_RESOURCE_ENTRY *Entry;
|
|
|
|
UINT64 FmpHardwareInstance;
|
|
|
|
|
|
|
|
FmpHardwareInstance = 0;
|
|
|
|
if (FmpVersion >= 3) {
|
|
|
|
FmpHardwareInstance = FmpImageInfoBuf->HardwareInstance;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Check to see of FmpImageInfoBuf GUID/HardwareInstance is unique
|
|
|
|
//
|
|
|
|
for (Index = 0; Index < *NumberOfDescriptors; Index++) {
|
|
|
|
if (CompareGuid (&HardwareInstances[Index].ImageTypeGuid, &FmpImageInfoBuf->ImageTypeId)) {
|
|
|
|
if (HardwareInstances[Index].HardwareInstance == FmpHardwareInstance) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Duplicate firmware image descriptor with GUID %g HardwareInstance:0x%x\n", &FmpImageInfoBuf->ImageTypeId, FmpHardwareInstance));
|
|
|
|
ASSERT (
|
|
|
|
!CompareGuid (&HardwareInstances[Index].ImageTypeGuid, &FmpImageInfoBuf->ImageTypeId) ||
|
|
|
|
HardwareInstances[Index].HardwareInstance != FmpHardwareInstance
|
|
|
|
);
|
|
|
|
return EFI_UNSUPPORTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Record new GUID/HardwareInstance pair
|
|
|
|
//
|
|
|
|
CopyGuid (&HardwareInstances[*NumberOfDescriptors].ImageTypeGuid, &FmpImageInfoBuf->ImageTypeId);
|
|
|
|
HardwareInstances[*NumberOfDescriptors].HardwareInstance = FmpHardwareInstance;
|
|
|
|
*NumberOfDescriptors = *NumberOfDescriptors + 1;
|
|
|
|
|
|
|
|
DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Add new image descriptor with GUID %g HardwareInstance:0x%x\n", &FmpImageInfoBuf->ImageTypeId, FmpHardwareInstance));
|
|
|
|
|
|
|
|
//
|
|
|
|
// Check to see if GUID is already in the ESRT table
|
|
|
|
//
|
|
|
|
Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(Table + 1);
|
|
|
|
for (Index = 0; Index < Table->FwResourceCount; Index++, Entry++) {
|
|
|
|
if (!CompareGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "EsrtFmpDxe: ESRT Entry already exists for FMP Instance with GUID %g\n", &Entry->FwClass));
|
|
|
|
|
|
|
|
//
|
|
|
|
// Set ESRT FwVersion to the smaller of the two values
|
|
|
|
//
|
|
|
|
Entry->FwVersion = MIN (FmpImageInfoBuf->Version, Entry->FwVersion);
|
|
|
|
|
|
|
|
//
|
|
|
|
// VERSION 2 has Lowest Supported
|
|
|
|
//
|
|
|
|
if (FmpVersion >= 2) {
|
|
|
|
//
|
|
|
|
// Set ESRT LowestSupportedFwVersion to the smaller of the two values
|
|
|
|
//
|
|
|
|
Entry->LowestSupportedFwVersion =
|
|
|
|
MIN (
|
|
|
|
FmpImageInfoBuf->LowestSupportedImageVersion,
|
|
|
|
Entry->LowestSupportedFwVersion
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// VERSION 3 supports last attempt values
|
|
|
|
//
|
|
|
|
if (FmpVersion >= 3) {
|
|
|
|
//
|
|
|
|
// Update the ESRT entry with the last attempt status and last attempt
|
|
|
|
// version from the first FMP instance whose last attempt status is not
|
|
|
|
// SUCCESS. If all FMP instances are SUCCESS, then set version to the
|
|
|
|
// smallest value from all FMP instances.
|
|
|
|
//
|
|
|
|
if (Entry->LastAttemptStatus == LAST_ATTEMPT_STATUS_SUCCESS) {
|
|
|
|
if (FmpImageInfoBuf->LastAttemptStatus != LAST_ATTEMPT_STATUS_SUCCESS) {
|
|
|
|
Entry->LastAttemptStatus = FmpImageInfoBuf->LastAttemptStatus;
|
|
|
|
Entry->LastAttemptVersion = FmpImageInfoBuf->LastAttemptVersion;
|
|
|
|
} else {
|
|
|
|
Entry->LastAttemptVersion =
|
|
|
|
MIN (
|
|
|
|
FmpImageInfoBuf->LastAttemptVersion,
|
|
|
|
Entry->LastAttemptVersion
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Add a new ESRT Table Entry
|
|
|
|
//
|
|
|
|
Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(Table + 1) + Table->FwResourceCount;
|
|
|
|
|
|
|
|
CopyGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId);
|
|
|
|
|
|
|
|
if (IsSystemFmp (FmpImageInfoBuf)) {
|
|
|
|
DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Found an ESRT entry for a System Device.\n"));
|
|
|
|
Entry->FwType = (UINT32)(ESRT_FW_TYPE_SYSTEMFIRMWARE);
|
|
|
|
} else {
|
|
|
|
Entry->FwType = (UINT32)(ESRT_FW_TYPE_DEVICEFIRMWARE);
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry->FwVersion = FmpImageInfoBuf->Version;
|
|
|
|
Entry->LowestSupportedFwVersion = 0;
|
|
|
|
Entry->CapsuleFlags = 0;
|
|
|
|
Entry->LastAttemptVersion = 0;
|
|
|
|
Entry->LastAttemptStatus = 0;
|
|
|
|
|
|
|
|
//
|
|
|
|
// VERSION 2 has Lowest Supported
|
|
|
|
//
|
|
|
|
if (FmpVersion >= 2) {
|
|
|
|
Entry->LowestSupportedFwVersion = FmpImageInfoBuf->LowestSupportedImageVersion;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// VERSION 3 supports last attempt values
|
|
|
|
//
|
|
|
|
if (FmpVersion >= 3) {
|
|
|
|
Entry->LastAttemptVersion = FmpImageInfoBuf->LastAttemptVersion;
|
|
|
|
Entry->LastAttemptStatus = FmpImageInfoBuf->LastAttemptStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Increment the number of active ESRT Table Entries
|
|
|
|
//
|
|
|
|
Table->FwResourceCount++;
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Function to retrieve the EFI_FIRMWARE_IMAGE_DESCRIPTOR from an FMP Instance.
|
|
|
|
The returned buffer is allocated using AllocatePool() and must be freed by the
|
|
|
|
caller using FreePool().
|
|
|
|
|
|
|
|
@param[in] Fmp Pointer to an EFI_FIRMWARE_MANAGEMENT_PROTOCOL.
|
|
|
|
@param[out] FmpImageInfoDescriptorVer Pointer to the version number associated
|
|
|
|
with the returned EFI_FIRMWARE_IMAGE_DESCRIPTOR.
|
|
|
|
@param[out] FmpImageInfoCount Pointer to the number of the returned
|
|
|
|
EFI_FIRMWARE_IMAGE_DESCRIPTORs.
|
|
|
|
@param[out] DescriptorSize Pointer to the size, in bytes, of each
|
|
|
|
returned EFI_FIRMWARE_IMAGE_DESCRIPTOR.
|
|
|
|
|
|
|
|
@return Pointer to the retrieved EFI_FIRMWARE_IMAGE_DESCRIPTOR. If the
|
|
|
|
descriptor can not be retrieved, then NULL is returned.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_FIRMWARE_IMAGE_DESCRIPTOR *
|
|
|
|
FmpGetFirmwareImageDescriptor (
|
|
|
|
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp,
|
|
|
|
OUT UINT32 *FmpImageInfoDescriptorVer,
|
|
|
|
OUT UINT8 *FmpImageInfoCount,
|
|
|
|
OUT UINTN *DescriptorSize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
UINTN ImageInfoSize;
|
|
|
|
UINT32 PackageVersion;
|
|
|
|
CHAR16 *PackageVersionName;
|
|
|
|
EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
|
|
|
|
|
|
|
|
ImageInfoSize = 0;
|
|
|
|
Status = Fmp->GetImageInfo (
|
|
|
|
Fmp, // FMP Pointer
|
|
|
|
&ImageInfoSize, // Buffer Size (in this case 0)
|
|
|
|
NULL, // NULL so we can get size
|
|
|
|
FmpImageInfoDescriptorVer, // DescriptorVersion
|
|
|
|
FmpImageInfoCount, // DescriptorCount
|
|
|
|
DescriptorSize, // DescriptorSize
|
|
|
|
&PackageVersion, // PackageVersion
|
|
|
|
&PackageVersionName // PackageVersionName
|
|
|
|
);
|
|
|
|
if (Status != EFI_BUFFER_TOO_SMALL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Unexpected Failure in GetImageInfo. Status = %r\n", Status));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-04-28 12:49:24 +02:00
|
|
|
FmpImageInfoBuf = AllocateZeroPool(ImageInfoSize);
|
2019-09-03 11:58:42 +02:00
|
|
|
if (FmpImageInfoBuf == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get memory for FMP descriptor.\n"));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
PackageVersionName = NULL;
|
|
|
|
Status = Fmp->GetImageInfo (
|
|
|
|
Fmp, // FMP Pointer
|
|
|
|
&ImageInfoSize, // ImageInfoSize
|
|
|
|
FmpImageInfoBuf, // ImageInfo
|
|
|
|
FmpImageInfoDescriptorVer, // DescriptorVersion
|
|
|
|
FmpImageInfoCount, // DescriptorCount
|
|
|
|
DescriptorSize, // DescriptorSize
|
|
|
|
&PackageVersion, // PackageVersion
|
|
|
|
&PackageVersionName // PackageVersionName
|
|
|
|
);
|
|
|
|
if (PackageVersionName != NULL) {
|
2020-04-23 11:08:10 +02:00
|
|
|
FreePool(PackageVersionName);
|
2019-09-03 11:58:42 +02:00
|
|
|
}
|
2020-04-23 11:08:10 +02:00
|
|
|
if (EFI_ERROR(Status)) {
|
2019-09-03 11:58:42 +02:00
|
|
|
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failure in GetImageInfo. Status = %r\n", Status));
|
2020-04-23 11:08:10 +02:00
|
|
|
FreePool(FmpImageInfoBuf);
|
2019-09-03 11:58:42 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FmpImageInfoBuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Function to create ESRT based on FMP Instances.
|
|
|
|
Create ESRT table, get the descriptors from FMP Instance and
|
|
|
|
create ESRT entries (ESRE).
|
|
|
|
|
|
|
|
@return Pointer to the ESRT created.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_SYSTEM_RESOURCE_TABLE *
|
|
|
|
CreateFmpBasedEsrt (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
UINTN NoProtocols;
|
|
|
|
VOID **Buffer;
|
|
|
|
UINTN Index;
|
|
|
|
UINT32 FmpImageInfoDescriptorVer;
|
|
|
|
UINT8 FmpImageInfoCount;
|
|
|
|
UINTN DescriptorSize;
|
|
|
|
UINT32 NumberOfDescriptors;
|
|
|
|
EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
|
|
|
|
EFI_FIRMWARE_IMAGE_DESCRIPTOR *OrgFmpImageInfoBuf;
|
|
|
|
EFI_SYSTEM_RESOURCE_TABLE *Table;
|
|
|
|
GUID_HARDWAREINSTANCE_PAIR *HardwareInstances;
|
|
|
|
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
NoProtocols = 0;
|
|
|
|
Buffer = NULL;
|
|
|
|
FmpImageInfoBuf = NULL;
|
|
|
|
OrgFmpImageInfoBuf = NULL;
|
|
|
|
Table = NULL;
|
|
|
|
HardwareInstances = NULL;
|
|
|
|
|
|
|
|
Status = EfiLocateProtocolBuffer (
|
|
|
|
&gEfiFirmwareManagementProtocolGuid,
|
|
|
|
&NoProtocols,
|
|
|
|
&Buffer
|
|
|
|
);
|
|
|
|
if (EFI_ERROR(Status) || (Buffer == NULL)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Count the total number of EFI_FIRMWARE_IMAGE_DESCRIPTORs
|
|
|
|
//
|
|
|
|
for (Index = 0, NumberOfDescriptors = 0; Index < NoProtocols; Index++) {
|
|
|
|
FmpImageInfoBuf = FmpGetFirmwareImageDescriptor (
|
|
|
|
(EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) Buffer[Index],
|
|
|
|
&FmpImageInfoDescriptorVer,
|
|
|
|
&FmpImageInfoCount,
|
|
|
|
&DescriptorSize
|
|
|
|
);
|
|
|
|
if (FmpImageInfoBuf != NULL) {
|
|
|
|
NumberOfDescriptors += FmpImageInfoCount;
|
2020-04-23 11:08:10 +02:00
|
|
|
FreePool(FmpImageInfoBuf);
|
2019-09-03 11:58:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Allocate ESRT Table and GUID/HardwareInstance table
|
|
|
|
//
|
2020-04-28 12:49:24 +02:00
|
|
|
Table = AllocateZeroPool(
|
2019-09-03 11:58:42 +02:00
|
|
|
(NumberOfDescriptors * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)
|
|
|
|
);
|
|
|
|
if (Table == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for ESRT.\n"));
|
2020-04-23 11:08:10 +02:00
|
|
|
FreePool(Buffer);
|
2019-09-03 11:58:42 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-04-28 12:49:24 +02:00
|
|
|
HardwareInstances = AllocateZeroPool(NumberOfDescriptors * sizeof (GUID_HARDWAREINSTANCE_PAIR));
|
2019-09-03 11:58:42 +02:00
|
|
|
if (HardwareInstances == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for HW Instance Table.\n"));
|
2020-04-23 11:08:10 +02:00
|
|
|
FreePool(Table);
|
|
|
|
FreePool(Buffer);
|
2019-09-03 11:58:42 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Initialize ESRT Table
|
|
|
|
//
|
|
|
|
Table->FwResourceCount = 0;
|
|
|
|
Table->FwResourceCountMax = NumberOfDescriptors;
|
|
|
|
Table->FwResourceVersion = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;
|
|
|
|
|
|
|
|
NumberOfDescriptors = 0;
|
|
|
|
for (Index = 0; Index < NoProtocols; Index++) {
|
|
|
|
FmpImageInfoBuf = FmpGetFirmwareImageDescriptor (
|
|
|
|
(EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) Buffer[Index],
|
|
|
|
&FmpImageInfoDescriptorVer,
|
|
|
|
&FmpImageInfoCount,
|
|
|
|
&DescriptorSize
|
|
|
|
);
|
|
|
|
if (FmpImageInfoBuf == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Check each descriptor and read from the one specified
|
|
|
|
//
|
|
|
|
OrgFmpImageInfoBuf = FmpImageInfoBuf;
|
|
|
|
while (FmpImageInfoCount > 0) {
|
|
|
|
//
|
|
|
|
// If the descriptor has the IN USE bit set, create ESRT entry otherwise ignore.
|
|
|
|
//
|
|
|
|
if ((FmpImageInfoBuf->AttributesSetting & FmpImageInfoBuf->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE) == IMAGE_ATTRIBUTE_IN_USE) {
|
|
|
|
//
|
|
|
|
// Create ESRT entry
|
|
|
|
//
|
|
|
|
CreateEsrtEntry (Table, HardwareInstances, &NumberOfDescriptors, FmpImageInfoBuf, FmpImageInfoDescriptorVer);
|
|
|
|
}
|
|
|
|
FmpImageInfoCount--;
|
|
|
|
//
|
|
|
|
// Increment the buffer pointer ahead by the size of the descriptor
|
|
|
|
//
|
|
|
|
FmpImageInfoBuf = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)(((UINT8 *)FmpImageInfoBuf) + DescriptorSize);
|
|
|
|
}
|
|
|
|
|
2020-04-23 11:08:10 +02:00
|
|
|
FreePool(OrgFmpImageInfoBuf);
|
2019-09-03 11:58:42 +02:00
|
|
|
OrgFmpImageInfoBuf = NULL;
|
|
|
|
}
|
|
|
|
|
2020-04-23 11:08:10 +02:00
|
|
|
FreePool(Buffer);
|
|
|
|
FreePool(HardwareInstances);
|
2019-09-03 11:58:42 +02:00
|
|
|
return Table;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to
|
|
|
|
install the Efi System Resource Table.
|
|
|
|
|
|
|
|
@param[in] Event The Event that is being processed.
|
|
|
|
@param[in] Context The Event Context.
|
|
|
|
|
|
|
|
**/
|
|
|
|
VOID
|
|
|
|
EFIAPI
|
|
|
|
EsrtReadyToBootEventNotify (
|
|
|
|
IN EFI_EVENT Event,
|
|
|
|
IN VOID *Context
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
EFI_SYSTEM_RESOURCE_TABLE *Table;
|
|
|
|
|
|
|
|
Table = CreateFmpBasedEsrt ();
|
|
|
|
if (Table != NULL) {
|
|
|
|
//
|
|
|
|
// Print table on debug builds
|
|
|
|
//
|
|
|
|
DEBUG_CODE_BEGIN ();
|
|
|
|
PrintTable (Table);
|
|
|
|
DEBUG_CODE_END ();
|
|
|
|
|
|
|
|
Status = InstallEfiSystemResourceTableInUefiConfigurationTable (Table);
|
2020-04-23 11:08:10 +02:00
|
|
|
if (EFI_ERROR(Status)) {
|
|
|
|
FreePool(Table);
|
2019-09-03 11:58:42 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it is NULL. \n"));
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Close the event to prevent it be signalled again.
|
|
|
|
//
|
|
|
|
gBS->CloseEvent (Event);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
The module Entry Point of the Efi System Resource Table DXE driver.
|
|
|
|
|
|
|
|
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
|
|
|
@param[in] SystemTable A pointer to the EFI System Table.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS The entry point is executed successfully.
|
|
|
|
@retval Other Some error occurs when executing this entry point.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
EsrtFmpEntryPoint (
|
|
|
|
IN EFI_HANDLE ImageHandle,
|
|
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
EFI_EVENT EsrtReadyToBootEvent;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Register notify function to install ESRT on ReadyToBoot Event.
|
|
|
|
//
|
|
|
|
Status = EfiCreateEventReadyToBootEx (
|
|
|
|
TPL_CALLBACK,
|
|
|
|
EsrtReadyToBootEventNotify,
|
|
|
|
NULL,
|
|
|
|
&EsrtReadyToBootEvent
|
|
|
|
);
|
|
|
|
|
2020-04-23 11:08:10 +02:00
|
|
|
ASSERT_EFI_ERROR(Status);
|
|
|
|
if (EFI_ERROR(Status)) {
|
2019-09-03 11:58:42 +02:00
|
|
|
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to register for ready to boot\n"));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|