summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Universal/EsrtFmpDxe
diff options
context:
space:
mode:
authorMichael D Kinney <michael.d.kinney@intel.com>2018-01-04 15:25:35 -0800
committerMichael D Kinney <michael.d.kinney@intel.com>2018-02-11 15:32:29 -0800
commit4184aabda2e9fd95ef564d4e97ee65af945911d2 (patch)
treeb7cd848bd0078a679c92940544d715d84f495c7b /MdeModulePkg/Universal/EsrtFmpDxe
parent7aaa7e67c4077dd2a6101a0087d173691fb40c99 (diff)
downloadedk2-4184aabda2e9fd95ef564d4e97ee65af945911d2.tar.gz
edk2-4184aabda2e9fd95ef564d4e97ee65af945911d2.tar.bz2
edk2-4184aabda2e9fd95ef564d4e97ee65af945911d2.zip
MdeModulePkg/EsrtFmpDxe: Add EsrtFmpDxe module
https://bugzilla.tianocore.org/show_bug.cgi?id=802 Based on content from the following branch/commits: https://github.com/Microsoft/MS_UEFI/tree/share/MsCapsuleSupport The EsrtFmpDxe module is a lightweight version of the EsrtDxe module that produces ESRT entries based only on FMP Protocol instances. Cc: Sean Brogan <sean.brogan@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Eric Dong <eric.dong@intel.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Bret Barkelew <Bret.Barkelew@microsoft.com>
Diffstat (limited to 'MdeModulePkg/Universal/EsrtFmpDxe')
-rw-r--r--MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c482
-rw-r--r--MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDebugPrint.c161
-rw-r--r--MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf74
-rw-r--r--MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.uni19
-rw-r--r--MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxeExtra.uni18
5 files changed, 754 insertions, 0 deletions
diff --git a/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c
new file mode 100644
index 0000000000..b98430edbf
--- /dev/null
+++ b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c
@@ -0,0 +1,482 @@
+/** @file
+ Publishes ESRT table from Firmware Management Protocol instances
+
+ Copyright (c) 2016, Microsoft Corporation
+ Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+**/
+
+#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>
+
+//
+// Print ESRT to debug console
+//
+VOID
+EFIAPI
+PrintTable (
+ IN EFI_SYSTEM_RESOURCE_TABLE *Table
+ );
+
+//
+// Number of ESRT entries to grow by each time we run out of room
+//
+#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
+
+ @return Status code.
+
+**/
+EFI_STATUS
+InstallEfiSystemResourceTableInUefiConfigurationTable (
+ VOID
+ )
+{
+ 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;
+ } 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;
+ }
+ }
+ }
+ 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
+ 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.
+
+ @return Status code.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateEsrtEntry (
+ IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf,
+ IN UINT32 FmpVersion
+ )
+{
+ UINTN Index;
+ EFI_SYSTEM_RESOURCE_ENTRY *Entry;
+ UINTN NewSize;
+ EFI_SYSTEM_RESOURCE_TABLE *NewTable;
+
+ 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);
+ //
+ // Make sure Guid isn't already in the list
+ //
+ for (Index = 0; Index < mTable->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;
+ }
+ Entry++;
+ }
+
+ //
+ // 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);
+ NewTable = AllocateRuntimeZeroPool (NewSize);
+ if (NewTable == NULL) {
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory larger table for ESRT. \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Copy the whole old table into new table buffer
+ //
+ CopyMem (
+ NewTable,
+ mTable,
+ ((mTable->FwResourceCountMax) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)
+ );
+ //
+ // Update max
+ //
+ NewTable->FwResourceCountMax = NewTable->FwResourceCountMax + GROWTH_STEP;
+ //
+ // Free old table
+ //
+ FreePool (mTable);
+ //
+ // Reassign pointer to new table.
+ //
+ mTable = 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));
+ //
+ // Move to the location of new entry
+ //
+ Entry = Entry + mTable->FwResourceCount;
+ //
+ // Increment resource count
+ //
+ mTable->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;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Notify function for every Firmware Management Protocol being installed.
+ 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.
+
+**/
+VOID
+EFIAPI
+FmpInstallProtocolNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ UINTN BufferSize;
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
+ UINTN DescriptorSize;
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBufOrg;
+ UINT8 FmpImageInfoCount;
+ UINT32 FmpImageInfoDescriptorVer;
+ UINTN ImageInfoSize;
+ UINT32 PackageVersion;
+ CHAR16 *PackageVersionName;
+
+ Status = EFI_SUCCESS;
+ Handle = 0;
+ BufferSize = 0;
+ 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 = 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;
+
+ 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));
+ continue;
+ }
+
+ FmpImageInfoBuf = NULL;
+ FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
+ if (FmpImageInfoBuf == NULL) {
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get memory for descriptors.\n"));
+ continue;
+ }
+
+ FmpImageInfoBufOrg = FmpImageInfoBuf;
+ PackageVersionName = NULL;
+ Status = Fmp->GetImageInfo (
+ Fmp,
+ &ImageInfoSize, // ImageInfoSize
+ FmpImageInfoBuf, // ImageInfo
+ &FmpImageInfoDescriptorVer, // DescriptorVersion
+ &FmpImageInfoCount, // DescriptorCount
+ &DescriptorSize, // DescriptorSize
+ &PackageVersion, // PackageVersion
+ &PackageVersionName // PackageVersionName
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failure in GetImageInfo. Status = %r\n", Status));
+ goto CleanUp;
+ }
+
+ //
+ // Check each descriptor and read from the one specified
+ //
+ 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 (FmpImageInfoBuf, FmpImageInfoDescriptorVer);
+ }
+ FmpImageInfoCount--;
+ //
+ // Increment the buffer pointer ahead by the size of the descriptor
+ //
+ FmpImageInfoBuf = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)(((UINT8 *)FmpImageInfoBuf) + DescriptorSize);
+ }
+
+ if (PackageVersionName != NULL) {
+ FreePool (PackageVersionName);
+ PackageVersionName = NULL;
+ }
+ if (FmpImageInfoBufOrg != NULL) {
+ FreePool (FmpImageInfoBufOrg);
+ FmpImageInfoBufOrg = NULL;
+ }
+ }
+
+CleanUp:
+ if (FmpImageInfoBufOrg != NULL) {
+ FreePool (FmpImageInfoBufOrg);
+ }
+ return;
+}
+
+/**
+ 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
+ )
+{
+ InstallEfiSystemResourceTableInUefiConfigurationTable ();
+
+ //
+ // Print table on debug builds
+ //
+ DEBUG_CODE_BEGIN ();
+ PrintTable (mTable);
+ DEBUG_CODE_END ();
+}
+
+/**
+ 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;
+
+ //
+ // Allocate Memory for table
+ //
+ mTable = AllocateRuntimeZeroPool (
+ (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"));
+ }
+
+ //
+ // Register notify function to install ESRT on ReadyToBoot Event.
+ //
+ Status = EfiCreateEventReadyToBootEx (
+ TPL_CALLBACK,
+ EsrtReadyToBootEventNotify,
+ NULL,
+ &mEsrtReadyToBootEvent
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to register for ready to boot\n"));
+ }
+
+ return Status;
+}
diff --git a/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDebugPrint.c b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDebugPrint.c
new file mode 100644
index 0000000000..b4e5135e05
--- /dev/null
+++ b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDebugPrint.c
@@ -0,0 +1,161 @@
+/** @file
+ Publishes ESRT table from Firmware Management Protocol instances
+
+ Copyright (c) 2016, Microsoft Corporation
+ Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/FirmwareManagement.h>
+#include <Guid/SystemResourceTable.h>
+
+/**
+ Function to print a single ESRT Entry (ESRE) to the debug console
+
+ Print Format:
+ | 00000000-0000-0000-0000-000000000000 | SSSSSSSSSSSS | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 |
+
+ @param[in] Entry - Pointer to an ESRE entry
+ @retval EFI_SUCCESS
+ EFI_INVALID_PARAMETER
+**/
+EFI_STATUS
+EFIAPI
+PrintOutEsrtEntry (
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry
+ )
+{
+ if (Entry == NULL) {
+ DEBUG ((DEBUG_INFO, "| ERROR: Invalid resource entry pointer "));
+ DEBUG ((DEBUG_INFO, " |\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // GUID FW Class (36 chars plus table formatting)
+ //
+ DEBUG ((DEBUG_INFO, "| %g |", &Entry->FwClass));
+
+ //
+ // Entry Type (12 chars plus table formatting)
+ //
+ switch (Entry->FwType) {
+ case (ESRT_FW_TYPE_SYSTEMFIRMWARE) :
+ DEBUG ((DEBUG_INFO, " System FW |"));
+ break;
+ case (ESRT_FW_TYPE_DEVICEFIRMWARE) :
+ DEBUG ((DEBUG_INFO, " Device FW |"));
+ break;
+ case (ESRT_FW_TYPE_UEFIDRIVER) :
+ DEBUG ((DEBUG_INFO, " Uefi Driver |"));
+ break;
+ case (ESRT_FW_TYPE_UNKNOWN) :
+ DEBUG ((DEBUG_INFO, " Unknown Type |"));
+ break;
+ default:
+ DEBUG ((DEBUG_INFO, " ? 0x%8X |", Entry->FwType));
+ break;
+ }
+
+ //
+ // FW Version (10 char UINT32 string plus table formatting)
+ // Lowest Supported Version (10 char UINT32 string plus table formatting)
+ // Capsule Flags (10 char UINT32 string plus table formatting)
+ // Last Attempt Version (10 char UINT32 string plus table formatting)
+ // Last Attempt Status (10 char UINT32 string plus table formatting)
+ //
+ DEBUG ((DEBUG_INFO,
+ " 0x%8X | 0x%8X | 0x%8X | 0x%8X | 0x%8X |\n",
+ Entry->FwVersion,
+ Entry->LowestSupportedFwVersion,
+ Entry->CapsuleFlags,
+ Entry->LastAttemptVersion,
+ Entry->LastAttemptStatus
+ ));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to print the ESRT table to the debug console
+
+ @param[in] Table - Pointer to the ESRT table
+**/
+VOID
+EFIAPI
+PrintTable (
+ IN EFI_SYSTEM_RESOURCE_TABLE *Table
+ )
+{
+ EFI_SYSTEM_RESOURCE_ENTRY *Entry;
+ UINTN Index;
+
+ Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(((UINT8 *)Table) + sizeof (EFI_SYSTEM_RESOURCE_TABLE));
+
+ //
+ // Print ESRT table information
+ //
+ DEBUG ((DEBUG_INFO, "ESRT Table Information:\n"));
+ if (Table == NULL) {
+ DEBUG ((DEBUG_INFO, "ERROR: Invalid table pointer\n"));
+ return;
+ }
+
+ DEBUG ((DEBUG_INFO, "+--------------------------------------------------------+\n"));
+ DEBUG ((DEBUG_INFO, "| Firmware Resource Count : 0x%08x |\n", Table->FwResourceCount));
+ DEBUG ((DEBUG_INFO, "| Firmware Resource Count Max : 0x%08x |\n", Table->FwResourceCountMax));
+ DEBUG ((DEBUG_INFO, "| Firmware Resource Entry Version : 0x%016x |\n", Table->FwResourceVersion));
+ DEBUG ((DEBUG_INFO, "+--------------------------------------------------------+\n"));
+
+ //
+ // Print table entry information
+ //
+ DEBUG ((DEBUG_INFO, "ESRT Table Entries:\n"));
+ if (Table->FwResourceVersion != EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION) {
+ DEBUG ((DEBUG_INFO, "ERROR: Unsupported Resource Entry Version\n"));
+ return;
+ }
+
+ DEBUG ((DEBUG_INFO, "+--------------------------------------+--------------+------------"));
+ DEBUG ((DEBUG_INFO, "+------------+------------+------------+------------+\n"));
+ DEBUG ((DEBUG_INFO, "| | | "));
+ DEBUG ((DEBUG_INFO, "| Lowest | | Last | Last |\n"));
+ DEBUG ((DEBUG_INFO, "| | Firmware | "));
+ DEBUG ((DEBUG_INFO, "| Supported | Capsule | Attempted | Attempted |\n"));
+ DEBUG ((DEBUG_INFO, "| CLASS GUID | Type | Version "));
+ DEBUG ((DEBUG_INFO, "| Version | Flags | Version | Status |\n"));
+ DEBUG ((DEBUG_INFO, "+--------------------------------------+--------------+------------"));
+ DEBUG ((DEBUG_INFO, "+------------+------------+------------+------------+\n"));
+
+ for (Index = 0; Index < Table->FwResourceCount; Index++) {
+ PrintOutEsrtEntry (&(Entry[Index]));
+ }
+
+ DEBUG ((DEBUG_INFO, "+--------------------------------------+--------------+------------"));
+ DEBUG ((DEBUG_INFO, "+------------+------------+------------+------------+\n"));
+}
+
diff --git a/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
new file mode 100644
index 0000000000..6da5ce5b04
--- /dev/null
+++ b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf
@@ -0,0 +1,74 @@
+## @file
+# Publishes ESRT table from Firmware Management Protocol instances
+#
+# Copyright (c) 2016, Microsoft Corporation
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EsrtFmpDxe
+ MODULE_UNI_FILE = EsrtFmpDxe.uni
+ FILE_GUID = FF626DA9-17EE-4949-A8B8-B10FA0044E9F
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = EsrtFmpEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ EsrtFmp.c
+ EsrtFmpDebugPrint.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiLib
+ UefiBootServicesTableLib
+ DebugLib
+ PcdLib
+
+[Protocols]
+ gEfiFirmwareManagementProtocolGuid ## CONSUMES
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid ## CONSUMES
+
+[Guids]
+ gEfiSystemResourceTableGuid ## PRODUCES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ EsrtFmpDxeExtra.uni
diff --git a/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.uni b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.uni
new file mode 100644
index 0000000000..fdad5b5bd9
--- /dev/null
+++ b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.uni
@@ -0,0 +1,19 @@
+// /** @file
+// Publishes ESRT table from Firmware Management Protocol instances
+//
+// Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Publishes ESRT table from Firmware Management Protocol instances"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This driver publishes the ESRT table from Firmware Management Protocol instances.<BR><BR>\n"
+ "The ESRT table is published when the Ready To Boot event is signaled.<BR>"
diff --git a/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxeExtra.uni b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxeExtra.uni
new file mode 100644
index 0000000000..2c6f6dab9c
--- /dev/null
+++ b/MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxeExtra.uni
@@ -0,0 +1,18 @@
+// /** @file
+// EsrtFmpDxe Localized Strings and Content
+//
+// Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"ESRT FMP DXE Driver"