//\r
#define GROWTH_STEP 10\r
\r
-//\r
-// Module globals.\r
-//\r
-EFI_EVENT mEsrtReadyToBootEvent;\r
-EFI_SYSTEM_RESOURCE_TABLE *mTable = NULL;\r
-BOOLEAN mEsrtInstalled = FALSE;\r
-EFI_EVENT mFmpInstallEvent;\r
-VOID *mFmpInstallEventRegistration = NULL;\r
-\r
/**\r
Install EFI System Resource Table into the UEFI Configuration Table\r
\r
+ @param[in] Table Pointer to the ESRT.\r
+\r
@return Status code.\r
\r
**/\r
EFI_STATUS\r
InstallEfiSystemResourceTableInUefiConfigurationTable (\r
- VOID\r
+ IN EFI_SYSTEM_RESOURCE_TABLE *Table\r
)\r
{\r
EFI_STATUS Status;\r
\r
Status = EFI_SUCCESS;\r
- if (!mEsrtInstalled) {\r
- if (mTable == NULL) {\r
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it is NULL. \n"));\r
- Status = EFI_OUT_OF_RESOURCES;\r
- } else if (mTable->FwResourceCount == 0) {\r
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it has zero Entries. \n"));\r
- Status = EFI_UNSUPPORTED;\r
+ if (Table->FwResourceCount == 0) {\r
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it has zero Entries. \n"));\r
+ Status = EFI_UNSUPPORTED;\r
+ } else {\r
+ //\r
+ // Install the pointer into config table\r
+ //\r
+ Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, Table);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table. Status: %r. \n", Status));\r
} else {\r
- //\r
- // Install the pointer into config table\r
- //\r
- Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, mTable);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table. Status: %r. \n", Status));\r
- } else {\r
- DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Installed ESRT table. \n"));\r
- mEsrtInstalled = TRUE;\r
- }\r
+ DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Installed ESRT table. \n"));\r
}\r
}\r
return Status;\r
given a FMP descriptor. If the guid is already in the ESRT it\r
will be ignored. The ESRT will grow if it does not have enough room.\r
\r
- @param[in] FmpImageInfoBuf Pointer to the EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
- @param[in] FmpVersion FMP Version.\r
+ @param[in, out] Table On input, pointer to the pointer to the ESRT.\r
+ On output, same as input or pointer to the pointer\r
+ to new enlarged ESRT.\r
+ @param[in] FmpImageInfoBuf Pointer to the EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+ @param[in] FmpVersion FMP Version.\r
\r
@return Status code.\r
\r
**/\r
EFI_STATUS\r
-EFIAPI\r
CreateEsrtEntry (\r
+ IN OUT EFI_SYSTEM_RESOURCE_TABLE **Table,\r
IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf,\r
IN UINT32 FmpVersion\r
)\r
Index = 0;\r
Entry = NULL;\r
\r
- //\r
- // Get our ESRT table. This should never be null at this point\r
- //\r
- if (mTable == NULL) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mTable + 1);\r
+ Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)((*Table) + 1);\r
//\r
// Make sure Guid isn't already in the list\r
//\r
- for (Index = 0; Index < mTable->FwResourceCount; Index++) {\r
+ for (Index = 0; Index < (*Table)->FwResourceCount; Index++) {\r
if (CompareGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId)) {\r
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: ESRT Entry already exists for FMP Instance with GUID %g\n", &Entry->FwClass));\r
return EFI_INVALID_PARAMETER;\r
//\r
// Grow table if needed\r
//\r
- if (mTable->FwResourceCount >= mTable->FwResourceCountMax) {\r
- //\r
- // Can't grow table after installed.\r
- // Only because didn't add support for this.\r
- // Would need to re-install ESRT in system table if wanted to support\r
- //\r
- if (mEsrtInstalled) {\r
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to install entry because ESRT table needed to grow after table already installed. \n"));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- NewSize = ((mTable->FwResourceCountMax + GROWTH_STEP) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE);\r
- NewTable = AllocateRuntimeZeroPool (NewSize);\r
+ if ((*Table)->FwResourceCount >= (*Table)->FwResourceCountMax) {\r
+ NewSize = (((*Table)->FwResourceCountMax + GROWTH_STEP) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE);\r
+ NewTable = AllocateZeroPool (NewSize);\r
if (NewTable == NULL) {\r
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory larger table for ESRT. \n"));\r
return EFI_OUT_OF_RESOURCES;\r
//\r
CopyMem (\r
NewTable,\r
- mTable,\r
- ((mTable->FwResourceCountMax) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
+ (*Table),\r
+ (((*Table)->FwResourceCountMax) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
);\r
//\r
// Update max\r
//\r
// Free old table\r
//\r
- FreePool (mTable);\r
+ FreePool ((*Table));\r
//\r
// Reassign pointer to new table.\r
//\r
- mTable = NewTable;\r
+ (*Table) = NewTable;\r
}\r
\r
//\r
// ESRT table has enough room for the new entry so add new entry\r
//\r
- Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(((UINT8 *)mTable) + sizeof (EFI_SYSTEM_RESOURCE_TABLE));\r
+ Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(((UINT8 *)(*Table)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE));\r
//\r
// Move to the location of new entry\r
//\r
- Entry = Entry + mTable->FwResourceCount;\r
+ Entry = Entry + (*Table)->FwResourceCount;\r
//\r
// Increment resource count\r
//\r
- mTable->FwResourceCount++;\r
+ (*Table)->FwResourceCount++;\r
\r
CopyGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId);\r
\r
}\r
\r
/**\r
- Notify function for every Firmware Management Protocol being installed.\r
- Get the descriptors from FMP Instance and create ESRT entries (ESRE)\r
+ Function to create ESRT based on FMP Instances.\r
+ Create ESRT table, get the descriptors from FMP Instance and\r
+ create ESRT entries (ESRE).\r
\r
- @param[in] Event The Event that is being processed.\r
- @param[in] Context The Event Context.\r
+ @return Pointer to the ESRT created.\r
\r
**/\r
-VOID\r
-EFIAPI\r
-FmpInstallProtocolNotify (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
+EFI_SYSTEM_RESOURCE_TABLE *\r
+CreateFmpBasedEsrt (\r
+ VOID\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_HANDLE Handle;\r
- UINTN BufferSize;\r
+ EFI_SYSTEM_RESOURCE_TABLE *Table;\r
+ UINTN NoProtocols;\r
+ VOID **Buffer;\r
+ UINTN Index;\r
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
UINTN DescriptorSize;\r
EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
CHAR16 *PackageVersionName;\r
\r
Status = EFI_SUCCESS;\r
- Handle = 0;\r
- BufferSize = 0;\r
+ Table = NULL;\r
+ NoProtocols = 0;\r
+ Buffer = NULL;\r
PackageVersionName = NULL;\r
FmpImageInfoBuf = NULL;\r
FmpImageInfoBufOrg = NULL;\r
Fmp = NULL;\r
\r
- DEBUG ((DEBUG_INFO, "FMP Installed Notify\n"));\r
- while (TRUE) {\r
- BufferSize = sizeof (EFI_HANDLE);\r
- Status = gBS->LocateHandle (ByRegisterNotify, NULL, mFmpInstallEventRegistration, &BufferSize, &Handle);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_WARN, "EsrtFmpDxe: Failed to Locate handle from notify value. Status: %r\n", Status));\r
- return;\r
- }\r
+ Status = EfiLocateProtocolBuffer (\r
+ &gEfiFirmwareManagementProtocolGuid,\r
+ &NoProtocols,\r
+ &Buffer\r
+ );\r
+ if (EFI_ERROR(Status) || (Buffer == NULL)) {\r
+ return NULL;\r
+ }\r
\r
- Status = gBS->HandleProtocol (Handle, &gEfiFirmwareManagementProtocolGuid, (VOID **)&Fmp);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get FMP for a handle 0x%x\n", Handle));\r
- continue;\r
- }\r
- ImageInfoSize = 0;\r
+ //\r
+ // Allocate Memory for table\r
+ //\r
+ Table = AllocateZeroPool (\r
+ (GROWTH_STEP * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
+ );\r
+ if (Table == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for ESRT.\n"));\r
+ gBS->FreePool (Buffer);\r
+ return NULL;\r
+ }\r
+\r
+ Table->FwResourceCount = 0;\r
+ Table->FwResourceCountMax = GROWTH_STEP;\r
+ Table->FwResourceVersion = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;\r
\r
+ for (Index = 0; Index < NoProtocols; Index++) {\r
+ Fmp = (EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) Buffer[Index];\r
+\r
+ ImageInfoSize = 0;\r
Status = Fmp->GetImageInfo (\r
Fmp, // FMP Pointer\r
&ImageInfoSize, // Buffer Size (in this case 0)\r
continue;\r
}\r
\r
- FmpImageInfoBuf = NULL;\r
FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
if (FmpImageInfoBuf == NULL) {\r
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get memory for descriptors.\n"));\r
);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failure in GetImageInfo. Status = %r\n", Status));\r
- goto CleanUp;\r
+ FreePool (FmpImageInfoBufOrg);\r
+ FmpImageInfoBufOrg = NULL;\r
+ continue;\r
}\r
\r
//\r
//\r
// Create ESRT entry\r
//\r
- CreateEsrtEntry (FmpImageInfoBuf, FmpImageInfoDescriptorVer);\r
+ CreateEsrtEntry (&Table, FmpImageInfoBuf, FmpImageInfoDescriptorVer);\r
}\r
FmpImageInfoCount--;\r
//\r
FreePool (PackageVersionName);\r
PackageVersionName = NULL;\r
}\r
- if (FmpImageInfoBufOrg != NULL) {\r
- FreePool (FmpImageInfoBufOrg);\r
- FmpImageInfoBufOrg = NULL;\r
- }\r
- }\r
-\r
-CleanUp:\r
- if (FmpImageInfoBufOrg != NULL) {\r
FreePool (FmpImageInfoBufOrg);\r
+ FmpImageInfoBufOrg = NULL;\r
}\r
- return;\r
+\r
+ gBS->FreePool (Buffer);\r
+ return Table;\r
}\r
\r
/**\r
IN VOID *Context\r
)\r
{\r
- InstallEfiSystemResourceTableInUefiConfigurationTable ();\r
+ EFI_STATUS Status;\r
+ EFI_SYSTEM_RESOURCE_TABLE *Table;\r
+\r
+ Table = CreateFmpBasedEsrt ();\r
+ if (Table != NULL) {\r
+ //\r
+ // Print table on debug builds\r
+ //\r
+ DEBUG_CODE_BEGIN ();\r
+ PrintTable (Table);\r
+ DEBUG_CODE_END ();\r
+\r
+ Status = InstallEfiSystemResourceTableInUefiConfigurationTable (Table);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (Table);\r
+ }\r
+ } else {\r
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it is NULL. \n"));\r
+ }\r
\r
//\r
- // Print table on debug builds\r
+ // Close the event to prevent it be signalled again.\r
//\r
- DEBUG_CODE_BEGIN ();\r
- PrintTable (mTable);\r
- DEBUG_CODE_END ();\r
+ gBS->CloseEvent (Event);\r
}\r
\r
/**\r
)\r
{\r
EFI_STATUS Status;\r
-\r
- //\r
- // Allocate Memory for table\r
- //\r
- mTable = AllocateRuntimeZeroPool (\r
- (GROWTH_STEP * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
- );\r
- ASSERT (mTable != NULL);\r
- if (mTable == NULL) {\r
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for ESRT.\n"));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- mTable->FwResourceCount = 0;\r
- mTable->FwResourceCountMax = GROWTH_STEP;\r
- mTable->FwResourceVersion = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;\r
-\r
- //\r
- // Register notify function for all FMP installed\r
- //\r
- mFmpInstallEvent = EfiCreateProtocolNotifyEvent (\r
- &gEfiFirmwareManagementProtocolGuid,\r
- TPL_CALLBACK,\r
- FmpInstallProtocolNotify,\r
- NULL,\r
- &mFmpInstallEventRegistration\r
- );\r
-\r
- ASSERT (mFmpInstallEvent != NULL);\r
-\r
- if (mFmpInstallEvent == NULL) {\r
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to Create Protocol Notify Event for FMP.\n"));\r
- }\r
+ EFI_EVENT EsrtReadyToBootEvent;\r
\r
//\r
// Register notify function to install ESRT on ReadyToBoot Event.\r
TPL_CALLBACK,\r
EsrtReadyToBootEventNotify,\r
NULL,\r
- &mEsrtReadyToBootEvent\r
+ &EsrtReadyToBootEvent\r
);\r
\r
ASSERT_EFI_ERROR (Status);\r