Publishes ESRT table from Firmware Management Protocol instances\r
\r
Copyright (c) 2016, Microsoft Corporation\r
- Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>\r
\r
All rights reserved.\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
#include <Guid/EventGroup.h>\r
#include <Guid/SystemResourceTable.h>\r
\r
+///\r
+/// Structure for array of unique GUID/HardwareInstance pairs from the\r
+/// current set of EFI_FIRMWARE_IMAGE_DESCRIPTORs from all FMP Protocols.\r
+///\r
+typedef struct {\r
+ ///\r
+ /// A unique GUID identifying the firmware image type.\r
+ ///\r
+ EFI_GUID ImageTypeGuid;\r
+ ///\r
+ /// An optional number to identify the unique hardware instance within the\r
+ /// system for devices that may have multiple instances whenever possible.\r
+ ///\r
+ UINT64 HardwareInstance;\r
+} GUID_HARDWAREINSTANCE_PAIR;\r
+\r
/**\r
Print ESRT to debug console.\r
\r
IN EFI_SYSTEM_RESOURCE_TABLE *Table\r
);\r
\r
-//\r
-// Number of ESRT entries to grow by each time we run out of room\r
-//\r
-#define GROWTH_STEP 10\r
-\r
/**\r
Install EFI System Resource Table into the UEFI Configuration Table\r
\r
}\r
\r
/**\r
- Function to create a single ESRT Entry and add it to the ESRT\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, 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
+ Function to create a single ESRT Entry and add it to the ESRT with\r
+ a given FMP descriptor. If the GUID is already in the ESRT, then the ESRT\r
+ entry is updated.\r
+\r
+ @param[in,out] Table Pointer to the ESRT Table.\r
+ @param[in,out] HardwareInstances Pointer to the GUID_HARDWAREINSTANCE_PAIR.\r
+ @param[in,out] NumberOfDescriptors The number of EFI_FIRMWARE_IMAGE_DESCRIPTORs.\r
+ @param[in] FmpImageInfoBuf Pointer to the EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+ @param[in] FmpVersion FMP Version.\r
+\r
+ @retval EFI_SUCCESS FmpImageInfoBuf was use to fill in a new ESRT entry\r
+ in Table.\r
+ @retval EFI_SUCCESS The ImageTypeId GUID in FmpImageInfoBuf matches an\r
+ existing ESRT entry in Table, and the information\r
+ from FmpImageInfoBuf was merged into the the existing\r
+ ESRT entry.\r
+ @retval EFI_UNSPOORTED The GUID/HardareInstance in FmpImageInfoBuf has is a\r
+ duplicate.\r
\r
**/\r
EFI_STATUS\r
CreateEsrtEntry (\r
- IN OUT EFI_SYSTEM_RESOURCE_TABLE **Table,\r
- IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf,\r
- IN UINT32 FmpVersion\r
+ IN OUT EFI_SYSTEM_RESOURCE_TABLE *Table,\r
+ IN OUT GUID_HARDWAREINSTANCE_PAIR *HardwareInstances,\r
+ IN OUT UINT32 *NumberOfDescriptors,\r
+ IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf,\r
+ IN UINT32 FmpVersion\r
)\r
{\r
UINTN Index;\r
EFI_SYSTEM_RESOURCE_ENTRY *Entry;\r
- UINTN NewSize;\r
- EFI_SYSTEM_RESOURCE_TABLE *NewTable;\r
+ UINT64 FmpHardwareInstance;\r
\r
- Index = 0;\r
- Entry = NULL;\r
+ FmpHardwareInstance = 0;\r
+ if (FmpVersion >= 3) {\r
+ FmpHardwareInstance = FmpImageInfoBuf->HardwareInstance;\r
+ }\r
\r
- Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)((*Table) + 1);\r
//\r
- // Make sure Guid isn't already in the list\r
+ // Check to see of FmpImageInfoBuf GUID/HardwareInstance is unique\r
//\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
+ for (Index = 0; Index < *NumberOfDescriptors; Index++) {\r
+ if (CompareGuid (&HardwareInstances[Index].ImageTypeGuid, &FmpImageInfoBuf->ImageTypeId)) {\r
+ if (HardwareInstances[Index].HardwareInstance == FmpHardwareInstance) {\r
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Duplicate firmware image descriptor with GUID %g HardwareInstance:0x%x\n", &FmpImageInfoBuf->ImageTypeId, FmpHardwareInstance));\r
+ ASSERT (\r
+ !CompareGuid (&HardwareInstances[Index].ImageTypeGuid, &FmpImageInfoBuf->ImageTypeId) ||\r
+ HardwareInstances[Index].HardwareInstance != FmpHardwareInstance\r
+ );\r
+ return EFI_UNSUPPORTED;\r
+ }\r
}\r
- Entry++;\r
}\r
\r
//\r
- // Grow table if needed\r
+ // Record new GUID/HardwareInstance pair\r
//\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
+ CopyGuid (&HardwareInstances[*NumberOfDescriptors].ImageTypeGuid, &FmpImageInfoBuf->ImageTypeId);\r
+ HardwareInstances[*NumberOfDescriptors].HardwareInstance = FmpHardwareInstance;\r
+ *NumberOfDescriptors = *NumberOfDescriptors + 1;\r
+\r
+ DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Add new image descriptor with GUID %g HardwareInstance:0x%x\n", &FmpImageInfoBuf->ImageTypeId, FmpHardwareInstance));\r
+\r
+ //\r
+ // Check to see if GUID is already in the ESRT table\r
+ //\r
+ Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(Table + 1);\r
+ for (Index = 0; Index < Table->FwResourceCount; Index++, Entry++) {\r
+ if (!CompareGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId)) {\r
+ continue;\r
}\r
+ DEBUG ((DEBUG_INFO, "EsrtFmpDxe: ESRT Entry already exists for FMP Instance with GUID %g\n", &Entry->FwClass));\r
+\r
//\r
- // Copy the whole old table into new table buffer\r
- //\r
- CopyMem (\r
- NewTable,\r
- (*Table),\r
- (((*Table)->FwResourceCountMax) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
- );\r
- //\r
- // Update max\r
+ // Set ESRT FwVersion to the smaller of the two values\r
//\r
- NewTable->FwResourceCountMax = NewTable->FwResourceCountMax + GROWTH_STEP;\r
+ Entry->FwVersion = MIN (FmpImageInfoBuf->Version, Entry->FwVersion);\r
+\r
//\r
- // Free old table\r
+ // VERSION 2 has Lowest Supported\r
//\r
- FreePool ((*Table));\r
+ if (FmpVersion >= 2) {\r
+ //\r
+ // Set ESRT LowestSupportedFwVersion to the smaller of the two values\r
+ //\r
+ Entry->LowestSupportedFwVersion =\r
+ MIN (\r
+ FmpImageInfoBuf->LowestSupportedImageVersion,\r
+ Entry->LowestSupportedFwVersion\r
+ );\r
+ }\r
+\r
//\r
- // Reassign pointer to new table.\r
+ // VERSION 3 supports last attempt values\r
//\r
- (*Table) = NewTable;\r
+ if (FmpVersion >= 3) {\r
+ //\r
+ // Update the ESRT entry with the last attempt status and last attempt\r
+ // version from the first FMP instance whose last attempt status is not\r
+ // SUCCESS. If all FMP instances are SUCCESS, then set version to the\r
+ // smallest value from all FMP instances.\r
+ //\r
+ if (Entry->LastAttemptStatus == LAST_ATTEMPT_STATUS_SUCCESS) {\r
+ if (FmpImageInfoBuf->LastAttemptStatus != LAST_ATTEMPT_STATUS_SUCCESS) {\r
+ Entry->LastAttemptStatus = FmpImageInfoBuf->LastAttemptStatus;\r
+ Entry->LastAttemptVersion = FmpImageInfoBuf->LastAttemptVersion;\r
+ } else {\r
+ Entry->LastAttemptVersion =\r
+ MIN (\r
+ FmpImageInfoBuf->LastAttemptVersion,\r
+ Entry->LastAttemptVersion\r
+ );\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\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 *)(*Table)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE));\r
- //\r
- // Move to the location of new entry\r
- //\r
- Entry = Entry + (*Table)->FwResourceCount;\r
+ // Add a new ESRT Table Entry\r
//\r
- // Increment resource count\r
- //\r
- (*Table)->FwResourceCount++;\r
+ Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(Table + 1) + Table->FwResourceCount;\r
\r
CopyGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId);\r
\r
Entry->FwType = (UINT32)(ESRT_FW_TYPE_DEVICEFIRMWARE);\r
}\r
\r
- Entry->FwVersion = FmpImageInfoBuf->Version;\r
+ Entry->FwVersion = FmpImageInfoBuf->Version;\r
Entry->LowestSupportedFwVersion = 0;\r
- Entry->CapsuleFlags = 0;\r
- Entry->LastAttemptVersion = 0;\r
- Entry->LastAttemptStatus = 0;\r
+ Entry->CapsuleFlags = 0;\r
+ Entry->LastAttemptVersion = 0;\r
+ Entry->LastAttemptStatus = 0;\r
\r
//\r
// VERSION 2 has Lowest Supported\r
//\r
if (FmpVersion >= 3) {\r
Entry->LastAttemptVersion = FmpImageInfoBuf->LastAttemptVersion;\r
- Entry->LastAttemptStatus = FmpImageInfoBuf->LastAttemptStatus;\r
+ Entry->LastAttemptStatus = FmpImageInfoBuf->LastAttemptStatus;\r
}\r
\r
+ //\r
+ // Increment the number of active ESRT Table Entries\r
+ //\r
+ Table->FwResourceCount++;\r
+\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Function to retrieve the EFI_FIRMWARE_IMAGE_DESCRIPTOR from an FMP Instance.\r
+ The returned buffer is allocated using AllocatePool() and must be freed by the\r
+ caller using FreePool().\r
+\r
+ @param[in] Fmp Pointer to an EFI_FIRMWARE_MANAGEMENT_PROTOCOL.\r
+ @param[out] FmpImageInfoDescriptorVer Pointer to the version number associated\r
+ with the returned EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+ @param[out] FmpImageInfoCount Pointer to the number of the returned\r
+ EFI_FIRMWARE_IMAGE_DESCRIPTORs.\r
+ @param[out] DescriptorSize Pointer to the size, in bytes, of each\r
+ returned EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+\r
+ @return Pointer to the retrieved EFI_FIRMWARE_IMAGE_DESCRIPTOR. If the\r
+ descriptor can not be retrieved, then NULL is returned.\r
+\r
+**/\r
+EFI_FIRMWARE_IMAGE_DESCRIPTOR *\r
+FmpGetFirmwareImageDescriptor (\r
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp,\r
+ OUT UINT32 *FmpImageInfoDescriptorVer,\r
+ OUT UINT8 *FmpImageInfoCount,\r
+ OUT UINTN *DescriptorSize\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ImageInfoSize;\r
+ UINT32 PackageVersion;\r
+ CHAR16 *PackageVersionName;\r
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
+\r
+ ImageInfoSize = 0;\r
+ Status = Fmp->GetImageInfo (\r
+ Fmp, // FMP Pointer\r
+ &ImageInfoSize, // Buffer Size (in this case 0)\r
+ NULL, // NULL so we can get size\r
+ FmpImageInfoDescriptorVer, // DescriptorVersion\r
+ FmpImageInfoCount, // DescriptorCount\r
+ DescriptorSize, // DescriptorSize\r
+ &PackageVersion, // PackageVersion\r
+ &PackageVersionName // PackageVersionName\r
+ );\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Unexpected Failure in GetImageInfo. Status = %r\n", Status));\r
+ return NULL;\r
+ }\r
+\r
+ FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
+ if (FmpImageInfoBuf == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get memory for FMP descriptor.\n"));\r
+ return NULL;\r
+ }\r
+\r
+ PackageVersionName = NULL;\r
+ Status = Fmp->GetImageInfo (\r
+ Fmp, // FMP Pointer\r
+ &ImageInfoSize, // ImageInfoSize\r
+ FmpImageInfoBuf, // ImageInfo\r
+ FmpImageInfoDescriptorVer, // DescriptorVersion\r
+ FmpImageInfoCount, // DescriptorCount\r
+ DescriptorSize, // DescriptorSize\r
+ &PackageVersion, // PackageVersion\r
+ &PackageVersionName // PackageVersionName\r
+ );\r
+ if (PackageVersionName != NULL) {\r
+ FreePool (PackageVersionName);\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failure in GetImageInfo. Status = %r\n", Status));\r
+ FreePool (FmpImageInfoBuf);\r
+ return NULL;\r
+ }\r
+\r
+ return FmpImageInfoBuf;\r
+}\r
+\r
/**\r
Function to create ESRT based on FMP Instances.\r
Create ESRT table, get the descriptors from FMP Instance and\r
VOID\r
)\r
{\r
- EFI_STATUS Status;\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
- EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBufOrg;\r
- UINT8 FmpImageInfoCount;\r
- UINT32 FmpImageInfoDescriptorVer;\r
- UINTN ImageInfoSize;\r
- UINT32 PackageVersion;\r
- CHAR16 *PackageVersionName;\r
+ EFI_STATUS Status;\r
+ UINTN NoProtocols;\r
+ VOID **Buffer;\r
+ UINTN Index;\r
+ UINT32 FmpImageInfoDescriptorVer;\r
+ UINT8 FmpImageInfoCount;\r
+ UINTN DescriptorSize;\r
+ UINT32 NumberOfDescriptors;\r
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR *OrgFmpImageInfoBuf;\r
+ EFI_SYSTEM_RESOURCE_TABLE *Table;\r
+ GUID_HARDWAREINSTANCE_PAIR *HardwareInstances;\r
\r
Status = EFI_SUCCESS;\r
- Table = NULL;\r
NoProtocols = 0;\r
Buffer = NULL;\r
- PackageVersionName = NULL;\r
FmpImageInfoBuf = NULL;\r
- FmpImageInfoBufOrg = NULL;\r
- Fmp = NULL;\r
+ OrgFmpImageInfoBuf = NULL;\r
+ Table = NULL;\r
+ HardwareInstances = NULL;\r
\r
Status = EfiLocateProtocolBuffer (\r
&gEfiFirmwareManagementProtocolGuid,\r
}\r
\r
//\r
- // Allocate Memory for table\r
+ // Count the total number of EFI_FIRMWARE_IMAGE_DESCRIPTORs\r
+ //\r
+ for (Index = 0, NumberOfDescriptors = 0; Index < NoProtocols; Index++) {\r
+ FmpImageInfoBuf = FmpGetFirmwareImageDescriptor (\r
+ (EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) Buffer[Index],\r
+ &FmpImageInfoDescriptorVer,\r
+ &FmpImageInfoCount,\r
+ &DescriptorSize\r
+ );\r
+ if (FmpImageInfoBuf != NULL) {\r
+ NumberOfDescriptors += FmpImageInfoCount;\r
+ FreePool (FmpImageInfoBuf);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Allocate ESRT Table and GUID/HardwareInstance table\r
//\r
Table = AllocateZeroPool (\r
- (GROWTH_STEP * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
+ (NumberOfDescriptors * 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
+ FreePool (Buffer);\r
return NULL;\r
}\r
\r
+ HardwareInstances = AllocateZeroPool (NumberOfDescriptors * sizeof (GUID_HARDWAREINSTANCE_PAIR));\r
+ if (HardwareInstances == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for HW Instance Table.\n"));\r
+ FreePool (Table);\r
+ FreePool (Buffer);\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Initialize ESRT Table\r
+ //\r
Table->FwResourceCount = 0;\r
- Table->FwResourceCountMax = GROWTH_STEP;\r
+ Table->FwResourceCountMax = NumberOfDescriptors;\r
Table->FwResourceVersion = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;\r
\r
+ NumberOfDescriptors = 0;\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
- NULL, // NULL so we can get size\r
- &FmpImageInfoDescriptorVer, // DescriptorVersion\r
- &FmpImageInfoCount, // DescriptorCount\r
- &DescriptorSize, // DescriptorSize\r
- &PackageVersion, // PackageVersion\r
- &PackageVersionName // PackageVersionName\r
- );\r
-\r
- if (Status != EFI_BUFFER_TOO_SMALL) {\r
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Unexpected Failure in GetImageInfo. Status = %r\n", Status));\r
- continue;\r
- }\r
-\r
- FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
+ FmpImageInfoBuf = FmpGetFirmwareImageDescriptor (\r
+ (EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) Buffer[Index],\r
+ &FmpImageInfoDescriptorVer,\r
+ &FmpImageInfoCount,\r
+ &DescriptorSize\r
+ );\r
if (FmpImageInfoBuf == NULL) {\r
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get memory for descriptors.\n"));\r
- continue;\r
- }\r
-\r
- FmpImageInfoBufOrg = FmpImageInfoBuf;\r
- PackageVersionName = NULL;\r
- Status = Fmp->GetImageInfo (\r
- Fmp,\r
- &ImageInfoSize, // ImageInfoSize\r
- FmpImageInfoBuf, // ImageInfo\r
- &FmpImageInfoDescriptorVer, // DescriptorVersion\r
- &FmpImageInfoCount, // DescriptorCount\r
- &DescriptorSize, // DescriptorSize\r
- &PackageVersion, // PackageVersion\r
- &PackageVersionName // PackageVersionName\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failure in GetImageInfo. Status = %r\n", Status));\r
- FreePool (FmpImageInfoBufOrg);\r
- FmpImageInfoBufOrg = NULL;\r
continue;\r
}\r
\r
//\r
// Check each descriptor and read from the one specified\r
//\r
+ OrgFmpImageInfoBuf = FmpImageInfoBuf;\r
while (FmpImageInfoCount > 0) {\r
//\r
// If the descriptor has the IN USE bit set, create ESRT entry otherwise ignore.\r
//\r
// Create ESRT entry\r
//\r
- CreateEsrtEntry (&Table, FmpImageInfoBuf, FmpImageInfoDescriptorVer);\r
+ CreateEsrtEntry (Table, HardwareInstances, &NumberOfDescriptors, FmpImageInfoBuf, FmpImageInfoDescriptorVer);\r
}\r
FmpImageInfoCount--;\r
//\r
FmpImageInfoBuf = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)(((UINT8 *)FmpImageInfoBuf) + DescriptorSize);\r
}\r
\r
- if (PackageVersionName != NULL) {\r
- FreePool (PackageVersionName);\r
- PackageVersionName = NULL;\r
- }\r
- FreePool (FmpImageInfoBufOrg);\r
- FmpImageInfoBufOrg = NULL;\r
+ FreePool (OrgFmpImageInfoBuf);\r
+ OrgFmpImageInfoBuf = NULL;\r
}\r
\r
- gBS->FreePool (Buffer);\r
+ FreePool (Buffer);\r
+ FreePool (HardwareInstances);\r
return Table;\r
}\r
\r