--- /dev/null
+/** @file\r
+ 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
+\r
+ All rights reserved.\r
+ Redistribution and use in source and binary forms, with or without\r
+ modification, are permitted provided that the following conditions are met:\r
+ 1. Redistributions of source code must retain the above copyright notice,\r
+ this list of conditions and the following disclaimer.\r
+ 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ this list of conditions and the following disclaimer in the documentation\r
+ and/or other materials provided with the distribution.\r
+\r
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Protocol/FirmwareManagement.h>\r
+#include <Guid/EventGroup.h>\r
+#include <Guid/SystemResourceTable.h>\r
+\r
+//\r
+// Print ESRT to debug console\r
+//\r
+VOID\r
+EFIAPI\r
+PrintTable (\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
+// 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
+ @return Status code.\r
+\r
+**/\r
+EFI_STATUS\r
+InstallEfiSystemResourceTableInUefiConfigurationTable (\r
+ VOID\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
+ } 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
+ }\r
+ }\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo.\r
+\r
+ @param[in] FmpImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR\r
+\r
+ @return TRUE It is a system FMP.\r
+ @return FALSE It is a device FMP.\r
+**/\r
+BOOLEAN\r
+IsSystemFmp (\r
+ IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo\r
+ )\r
+{\r
+ GUID *Guid;\r
+ UINTN Count;\r
+ UINTN Index;\r
+\r
+ Guid = PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid);\r
+ Count = PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof(GUID);\r
+\r
+ for (Index = 0; Index < Count; Index++, Guid++) {\r
+ if (CompareGuid (&FmpImageInfo->ImageTypeId, Guid)) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\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
+ @return Status code.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateEsrtEntry (\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
+\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
+ //\r
+ // Make sure Guid isn't already in the list\r
+ //\r
+ for (Index = 0; Index < mTable->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
+ Entry++;\r
+ }\r
+\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 (NewTable == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory larger table for ESRT. \n"));\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // Copy the whole old table into new table buffer\r
+ //\r
+ CopyMem (\r
+ NewTable,\r
+ mTable,\r
+ ((mTable->FwResourceCountMax) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
+ );\r
+ //\r
+ // Update max\r
+ //\r
+ NewTable->FwResourceCountMax = NewTable->FwResourceCountMax + GROWTH_STEP;\r
+ //\r
+ // Free old table\r
+ //\r
+ FreePool (mTable);\r
+ //\r
+ // Reassign pointer to new table.\r
+ //\r
+ mTable = 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
+ //\r
+ // Move to the location of new entry\r
+ //\r
+ Entry = Entry + mTable->FwResourceCount;\r
+ //\r
+ // Increment resource count\r
+ //\r
+ mTable->FwResourceCount++;\r
+\r
+ CopyGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId);\r
+\r
+ if (IsSystemFmp (FmpImageInfoBuf)) {\r
+ DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Found an ESRT entry for a System Device.\n"));\r
+ Entry->FwType = (UINT32)(ESRT_FW_TYPE_SYSTEMFIRMWARE);\r
+ } else {\r
+ Entry->FwType = (UINT32)(ESRT_FW_TYPE_DEVICEFIRMWARE);\r
+ }\r
+\r
+ Entry->FwVersion = FmpImageInfoBuf->Version;\r
+ Entry->LowestSupportedFwVersion = 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 >= 2) {\r
+ Entry->LowestSupportedFwVersion = FmpImageInfoBuf->LowestSupportedImageVersion;\r
+ }\r
+\r
+ //\r
+ // VERSION 3 supports last attempt values\r
+ //\r
+ if (FmpVersion >= 3) {\r
+ Entry->LastAttemptVersion = FmpImageInfoBuf->LastAttemptVersion;\r
+ Entry->LastAttemptStatus = FmpImageInfoBuf->LastAttemptStatus;\r
+ }\r
+\r
+ return EFI_SUCCESS;\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
+\r
+ @param[in] Event The Event that is being processed.\r
+ @param[in] Context The Event Context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+FmpInstallProtocolNotify (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE Handle;\r
+ UINTN BufferSize;\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
+\r
+ Status = EFI_SUCCESS;\r
+ Handle = 0;\r
+ BufferSize = 0;\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
+\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
+ 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 = NULL;\r
+ FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\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
+ goto CleanUp;\r
+ }\r
+\r
+ //\r
+ // Check each descriptor and read from the one specified\r
+ //\r
+ while (FmpImageInfoCount > 0) {\r
+ //\r
+ // If the descriptor has the IN USE bit set, create ESRT entry otherwise ignore.\r
+ //\r
+ if ((FmpImageInfoBuf->AttributesSetting & FmpImageInfoBuf->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE) == IMAGE_ATTRIBUTE_IN_USE) {\r
+ //\r
+ // Create ESRT entry\r
+ //\r
+ CreateEsrtEntry (FmpImageInfoBuf, FmpImageInfoDescriptorVer);\r
+ }\r
+ FmpImageInfoCount--;\r
+ //\r
+ // Increment the buffer pointer ahead by the size of the descriptor\r
+ //\r
+ FmpImageInfoBuf = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)(((UINT8 *)FmpImageInfoBuf) + DescriptorSize);\r
+ }\r
+\r
+ if (PackageVersionName != NULL) {\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
+ }\r
+ return;\r
+}\r
+\r
+/**\r
+ Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to\r
+ install the Efi System Resource Table.\r
+\r
+ @param[in] Event The Event that is being processed.\r
+ @param[in] Context The Event Context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EsrtReadyToBootEventNotify (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ InstallEfiSystemResourceTableInUefiConfigurationTable ();\r
+\r
+ //\r
+ // Print table on debug builds\r
+ //\r
+ DEBUG_CODE_BEGIN ();\r
+ PrintTable (mTable);\r
+ DEBUG_CODE_END ();\r
+}\r
+\r
+/**\r
+ The module Entry Point of the Efi System Resource Table DXE driver.\r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The entry point is executed successfully.\r
+ @retval Other Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EsrtFmpEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\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
+\r
+ //\r
+ // Register notify function to install ESRT on ReadyToBoot Event.\r
+ //\r
+ Status = EfiCreateEventReadyToBootEx (\r
+ TPL_CALLBACK,\r
+ EsrtReadyToBootEventNotify,\r
+ NULL,\r
+ &mEsrtReadyToBootEvent\r
+ );\r
+\r
+ ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to register for ready to boot\n"));\r
+ }\r
+\r
+ return Status;\r
+}\r
--- /dev/null
+/** @file\r
+ 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
+\r
+ All rights reserved.\r
+ Redistribution and use in source and binary forms, with or without\r
+ modification, are permitted provided that the following conditions are met:\r
+ 1. Redistributions of source code must retain the above copyright notice,\r
+ this list of conditions and the following disclaimer.\r
+ 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ this list of conditions and the following disclaimer in the documentation\r
+ and/or other materials provided with the distribution.\r
+\r
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\r
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Protocol/FirmwareManagement.h>\r
+#include <Guid/SystemResourceTable.h>\r
+\r
+/**\r
+ Function to print a single ESRT Entry (ESRE) to the debug console\r
+\r
+ Print Format:\r
+ | 00000000-0000-0000-0000-000000000000 | SSSSSSSSSSSS | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 |\r
+\r
+ @param[in] Entry - Pointer to an ESRE entry\r
+ @retval EFI_SUCCESS\r
+ EFI_INVALID_PARAMETER\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PrintOutEsrtEntry (\r
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry\r
+ )\r
+{\r
+ if (Entry == NULL) {\r
+ DEBUG ((DEBUG_INFO, "| ERROR: Invalid resource entry pointer "));\r
+ DEBUG ((DEBUG_INFO, " |\n"));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // GUID FW Class (36 chars plus table formatting)\r
+ //\r
+ DEBUG ((DEBUG_INFO, "| %g |", &Entry->FwClass));\r
+\r
+ //\r
+ // Entry Type (12 chars plus table formatting)\r
+ //\r
+ switch (Entry->FwType) {\r
+ case (ESRT_FW_TYPE_SYSTEMFIRMWARE) :\r
+ DEBUG ((DEBUG_INFO, " System FW |"));\r
+ break;\r
+ case (ESRT_FW_TYPE_DEVICEFIRMWARE) :\r
+ DEBUG ((DEBUG_INFO, " Device FW |"));\r
+ break;\r
+ case (ESRT_FW_TYPE_UEFIDRIVER) :\r
+ DEBUG ((DEBUG_INFO, " Uefi Driver |"));\r
+ break;\r
+ case (ESRT_FW_TYPE_UNKNOWN) :\r
+ DEBUG ((DEBUG_INFO, " Unknown Type |"));\r
+ break;\r
+ default:\r
+ DEBUG ((DEBUG_INFO, " ? 0x%8X |", Entry->FwType));\r
+ break;\r
+ }\r
+\r
+ //\r
+ // FW Version (10 char UINT32 string plus table formatting)\r
+ // Lowest Supported Version (10 char UINT32 string plus table formatting)\r
+ // Capsule Flags (10 char UINT32 string plus table formatting)\r
+ // Last Attempt Version (10 char UINT32 string plus table formatting)\r
+ // Last Attempt Status (10 char UINT32 string plus table formatting)\r
+ //\r
+ DEBUG ((DEBUG_INFO,\r
+ " 0x%8X | 0x%8X | 0x%8X | 0x%8X | 0x%8X |\n",\r
+ Entry->FwVersion,\r
+ Entry->LowestSupportedFwVersion,\r
+ Entry->CapsuleFlags,\r
+ Entry->LastAttemptVersion,\r
+ Entry->LastAttemptStatus\r
+ ));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Function to print the ESRT table to the debug console\r
+\r
+ @param[in] Table - Pointer to the ESRT table\r
+**/\r
+VOID\r
+EFIAPI\r
+PrintTable (\r
+ IN EFI_SYSTEM_RESOURCE_TABLE *Table\r
+ )\r
+{\r
+ EFI_SYSTEM_RESOURCE_ENTRY *Entry;\r
+ UINTN Index;\r
+\r
+ Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(((UINT8 *)Table) + sizeof (EFI_SYSTEM_RESOURCE_TABLE));\r
+\r
+ //\r
+ // Print ESRT table information\r
+ //\r
+ DEBUG ((DEBUG_INFO, "ESRT Table Information:\n"));\r
+ if (Table == NULL) {\r
+ DEBUG ((DEBUG_INFO, "ERROR: Invalid table pointer\n"));\r
+ return;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "+--------------------------------------------------------+\n"));\r
+ DEBUG ((DEBUG_INFO, "| Firmware Resource Count : 0x%08x |\n", Table->FwResourceCount));\r
+ DEBUG ((DEBUG_INFO, "| Firmware Resource Count Max : 0x%08x |\n", Table->FwResourceCountMax));\r
+ DEBUG ((DEBUG_INFO, "| Firmware Resource Entry Version : 0x%016x |\n", Table->FwResourceVersion));\r
+ DEBUG ((DEBUG_INFO, "+--------------------------------------------------------+\n"));\r
+\r
+ //\r
+ // Print table entry information\r
+ //\r
+ DEBUG ((DEBUG_INFO, "ESRT Table Entries:\n"));\r
+ if (Table->FwResourceVersion != EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION) {\r
+ DEBUG ((DEBUG_INFO, "ERROR: Unsupported Resource Entry Version\n"));\r
+ return;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "+--------------------------------------+--------------+------------"));\r
+ DEBUG ((DEBUG_INFO, "+------------+------------+------------+------------+\n"));\r
+ DEBUG ((DEBUG_INFO, "| | | "));\r
+ DEBUG ((DEBUG_INFO, "| Lowest | | Last | Last |\n"));\r
+ DEBUG ((DEBUG_INFO, "| | Firmware | "));\r
+ DEBUG ((DEBUG_INFO, "| Supported | Capsule | Attempted | Attempted |\n"));\r
+ DEBUG ((DEBUG_INFO, "| CLASS GUID | Type | Version "));\r
+ DEBUG ((DEBUG_INFO, "| Version | Flags | Version | Status |\n"));\r
+ DEBUG ((DEBUG_INFO, "+--------------------------------------+--------------+------------"));\r
+ DEBUG ((DEBUG_INFO, "+------------+------------+------------+------------+\n"));\r
+\r
+ for (Index = 0; Index < Table->FwResourceCount; Index++) {\r
+ PrintOutEsrtEntry (&(Entry[Index]));\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "+--------------------------------------+--------------+------------"));\r
+ DEBUG ((DEBUG_INFO, "+------------+------------+------------+------------+\n"));\r
+}\r
+\r