diff options
-rw-r--r-- | MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c | 239 |
1 files changed, 103 insertions, 136 deletions
diff --git a/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c index cc9dd63b53..219059760e 100644 --- a/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c +++ b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c @@ -55,47 +55,34 @@ PrintTable ( //
#define GROWTH_STEP 10
-//
-// Module globals.
-//
-EFI_EVENT mEsrtReadyToBootEvent;
-EFI_SYSTEM_RESOURCE_TABLE *mTable = NULL;
-BOOLEAN mEsrtInstalled = FALSE;
-EFI_EVENT mFmpInstallEvent;
-VOID *mFmpInstallEventRegistration = NULL;
-
/**
Install EFI System Resource Table into the UEFI Configuration Table
+ @param[in] Table Pointer to the ESRT.
+
@return Status code.
**/
EFI_STATUS
InstallEfiSystemResourceTableInUefiConfigurationTable (
- VOID
+ IN EFI_SYSTEM_RESOURCE_TABLE *Table
)
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
- if (!mEsrtInstalled) {
- if (mTable == NULL) {
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it is NULL. \n"));
- Status = EFI_OUT_OF_RESOURCES;
- } else if (mTable->FwResourceCount == 0) {
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it has zero Entries. \n"));
- Status = EFI_UNSUPPORTED;
+ 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);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table. Status: %r. \n", Status));
} else {
- //
- // Install the pointer into config table
- //
- Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, mTable);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table. Status: %r. \n", Status));
- } else {
- DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Installed ESRT table. \n"));
- mEsrtInstalled = TRUE;
- }
+ DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Installed ESRT table. \n"));
}
}
return Status;
@@ -135,15 +122,18 @@ IsSystemFmp ( given a FMP descriptor. If the guid is already in the ESRT it
will be ignored. The ESRT will grow if it does not have enough room.
- @param[in] FmpImageInfoBuf Pointer to the EFI_FIRMWARE_IMAGE_DESCRIPTOR.
- @param[in] FmpVersion FMP Version.
+ @param[in, out] Table On input, pointer to the pointer to the ESRT.
+ On output, same as input or pointer to the pointer
+ to new enlarged ESRT.
+ @param[in] FmpImageInfoBuf Pointer to the EFI_FIRMWARE_IMAGE_DESCRIPTOR.
+ @param[in] FmpVersion FMP Version.
@return Status code.
**/
EFI_STATUS
-EFIAPI
CreateEsrtEntry (
+ IN OUT EFI_SYSTEM_RESOURCE_TABLE **Table,
IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf,
IN UINT32 FmpVersion
)
@@ -156,18 +146,11 @@ CreateEsrtEntry ( Index = 0;
Entry = NULL;
- //
- // Get our ESRT table. This should never be null at this point
- //
- if (mTable == NULL) {
- return EFI_DEVICE_ERROR;
- }
-
- Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mTable + 1);
+ Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)((*Table) + 1);
//
// Make sure Guid isn't already in the list
//
- for (Index = 0; Index < mTable->FwResourceCount; Index++) {
+ for (Index = 0; Index < (*Table)->FwResourceCount; Index++) {
if (CompareGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId)) {
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: ESRT Entry already exists for FMP Instance with GUID %g\n", &Entry->FwClass));
return EFI_INVALID_PARAMETER;
@@ -178,18 +161,8 @@ CreateEsrtEntry ( //
// Grow table if needed
//
- if (mTable->FwResourceCount >= mTable->FwResourceCountMax) {
- //
- // Can't grow table after installed.
- // Only because didn't add support for this.
- // Would need to re-install ESRT in system table if wanted to support
- //
- if (mEsrtInstalled) {
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to install entry because ESRT table needed to grow after table already installed. \n"));
- return EFI_OUT_OF_RESOURCES;
- }
-
- NewSize = ((mTable->FwResourceCountMax + GROWTH_STEP) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE);
+ if ((*Table)->FwResourceCount >= (*Table)->FwResourceCountMax) {
+ NewSize = (((*Table)->FwResourceCountMax + GROWTH_STEP) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE);
NewTable = AllocateZeroPool (NewSize);
if (NewTable == NULL) {
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory larger table for ESRT. \n"));
@@ -200,8 +173,8 @@ CreateEsrtEntry ( //
CopyMem (
NewTable,
- mTable,
- ((mTable->FwResourceCountMax) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)
+ (*Table),
+ (((*Table)->FwResourceCountMax) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)
);
//
// Update max
@@ -210,25 +183,25 @@ CreateEsrtEntry ( //
// Free old table
//
- FreePool (mTable);
+ FreePool ((*Table));
//
// Reassign pointer to new table.
//
- mTable = NewTable;
+ (*Table) = NewTable;
}
//
// ESRT table has enough room for the new entry so add new entry
//
- Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(((UINT8 *)mTable) + sizeof (EFI_SYSTEM_RESOURCE_TABLE));
+ Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(((UINT8 *)(*Table)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE));
//
// Move to the location of new entry
//
- Entry = Entry + mTable->FwResourceCount;
+ Entry = Entry + (*Table)->FwResourceCount;
//
// Increment resource count
//
- mTable->FwResourceCount++;
+ (*Table)->FwResourceCount++;
CopyGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId);
@@ -264,23 +237,23 @@ CreateEsrtEntry ( }
/**
- Notify function for every Firmware Management Protocol being installed.
- Get the descriptors from FMP Instance and create ESRT entries (ESRE)
+ Function to create ESRT based on FMP Instances.
+ Create ESRT table, get the descriptors from FMP Instance and
+ create ESRT entries (ESRE).
- @param[in] Event The Event that is being processed.
- @param[in] Context The Event Context.
+ @return Pointer to the ESRT created.
**/
-VOID
-EFIAPI
-FmpInstallProtocolNotify (
- IN EFI_EVENT Event,
- IN VOID *Context
+EFI_SYSTEM_RESOURCE_TABLE *
+CreateFmpBasedEsrt (
+ VOID
)
{
EFI_STATUS Status;
- EFI_HANDLE Handle;
- UINTN BufferSize;
+ EFI_SYSTEM_RESOURCE_TABLE *Table;
+ UINTN NoProtocols;
+ VOID **Buffer;
+ UINTN Index;
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
UINTN DescriptorSize;
EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
@@ -292,29 +265,43 @@ FmpInstallProtocolNotify ( CHAR16 *PackageVersionName;
Status = EFI_SUCCESS;
- Handle = 0;
- BufferSize = 0;
+ Table = NULL;
+ NoProtocols = 0;
+ Buffer = NULL;
PackageVersionName = NULL;
FmpImageInfoBuf = NULL;
FmpImageInfoBufOrg = NULL;
Fmp = NULL;
- DEBUG ((DEBUG_INFO, "FMP Installed Notify\n"));
- while (TRUE) {
- BufferSize = sizeof (EFI_HANDLE);
- Status = gBS->LocateHandle (ByRegisterNotify, NULL, mFmpInstallEventRegistration, &BufferSize, &Handle);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_WARN, "EsrtFmpDxe: Failed to Locate handle from notify value. Status: %r\n", Status));
- return;
- }
+ Status = EfiLocateProtocolBuffer (
+ &gEfiFirmwareManagementProtocolGuid,
+ &NoProtocols,
+ &Buffer
+ );
+ if (EFI_ERROR(Status) || (Buffer == NULL)) {
+ return NULL;
+ }
- Status = gBS->HandleProtocol (Handle, &gEfiFirmwareManagementProtocolGuid, (VOID **)&Fmp);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get FMP for a handle 0x%x\n", Handle));
- continue;
- }
- ImageInfoSize = 0;
+ //
+ // Allocate Memory for table
+ //
+ Table = AllocateZeroPool (
+ (GROWTH_STEP * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)
+ );
+ if (Table == NULL) {
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for ESRT.\n"));
+ gBS->FreePool (Buffer);
+ return NULL;
+ }
+
+ Table->FwResourceCount = 0;
+ Table->FwResourceCountMax = GROWTH_STEP;
+ Table->FwResourceVersion = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;
+ for (Index = 0; Index < NoProtocols; Index++) {
+ Fmp = (EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) Buffer[Index];
+
+ ImageInfoSize = 0;
Status = Fmp->GetImageInfo (
Fmp, // FMP Pointer
&ImageInfoSize, // Buffer Size (in this case 0)
@@ -331,7 +318,6 @@ FmpInstallProtocolNotify ( continue;
}
- FmpImageInfoBuf = NULL;
FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
if (FmpImageInfoBuf == NULL) {
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get memory for descriptors.\n"));
@@ -352,7 +338,9 @@ FmpInstallProtocolNotify ( );
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failure in GetImageInfo. Status = %r\n", Status));
- goto CleanUp;
+ FreePool (FmpImageInfoBufOrg);
+ FmpImageInfoBufOrg = NULL;
+ continue;
}
//
@@ -366,7 +354,7 @@ FmpInstallProtocolNotify ( //
// Create ESRT entry
//
- CreateEsrtEntry (FmpImageInfoBuf, FmpImageInfoDescriptorVer);
+ CreateEsrtEntry (&Table, FmpImageInfoBuf, FmpImageInfoDescriptorVer);
}
FmpImageInfoCount--;
//
@@ -379,17 +367,12 @@ FmpInstallProtocolNotify ( FreePool (PackageVersionName);
PackageVersionName = NULL;
}
- if (FmpImageInfoBufOrg != NULL) {
- FreePool (FmpImageInfoBufOrg);
- FmpImageInfoBufOrg = NULL;
- }
- }
-
-CleanUp:
- if (FmpImageInfoBufOrg != NULL) {
FreePool (FmpImageInfoBufOrg);
+ FmpImageInfoBufOrg = NULL;
}
- return;
+
+ gBS->FreePool (Buffer);
+ return Table;
}
/**
@@ -407,14 +390,30 @@ EsrtReadyToBootEventNotify ( IN VOID *Context
)
{
- InstallEfiSystemResourceTableInUefiConfigurationTable ();
+ 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);
+ if (EFI_ERROR (Status)) {
+ FreePool (Table);
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it is NULL. \n"));
+ }
//
- // Print table on debug builds
+ // Close the event to prevent it be signalled again.
//
- DEBUG_CODE_BEGIN ();
- PrintTable (mTable);
- DEBUG_CODE_END ();
+ gBS->CloseEvent (Event);
}
/**
@@ -435,39 +434,7 @@ EsrtFmpEntryPoint ( )
{
EFI_STATUS Status;
-
- //
- // Allocate Memory for table
- //
- mTable = AllocateZeroPool (
- (GROWTH_STEP * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)
- );
- ASSERT (mTable != NULL);
- if (mTable == NULL) {
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for ESRT.\n"));
- return EFI_OUT_OF_RESOURCES;
- }
-
- mTable->FwResourceCount = 0;
- mTable->FwResourceCountMax = GROWTH_STEP;
- mTable->FwResourceVersion = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;
-
- //
- // Register notify function for all FMP installed
- //
- mFmpInstallEvent = EfiCreateProtocolNotifyEvent (
- &gEfiFirmwareManagementProtocolGuid,
- TPL_CALLBACK,
- FmpInstallProtocolNotify,
- NULL,
- &mFmpInstallEventRegistration
- );
-
- ASSERT (mFmpInstallEvent != NULL);
-
- if (mFmpInstallEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to Create Protocol Notify Event for FMP.\n"));
- }
+ EFI_EVENT EsrtReadyToBootEvent;
//
// Register notify function to install ESRT on ReadyToBoot Event.
@@ -476,7 +443,7 @@ EsrtFmpEntryPoint ( TPL_CALLBACK,
EsrtReadyToBootEventNotify,
NULL,
- &mEsrtReadyToBootEvent
+ &EsrtReadyToBootEvent
);
ASSERT_EFI_ERROR (Status);
|