summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Universal/EsrtDxe
diff options
context:
space:
mode:
authorChao Zhang <chao.b.zhang@intel.com>2015-05-13 08:30:45 +0000
committerczhang46 <czhang46@Edk2>2015-05-13 08:30:45 +0000
commitacd32208b0de487aefa859665f66ce3b23dd91a4 (patch)
tree05d0dee858d092586232b6497900436eff5d2b73 /MdeModulePkg/Universal/EsrtDxe
parent8d51e87ddc18767f49e39cee6fd2d4f7fdc15dda (diff)
downloadedk2-acd32208b0de487aefa859665f66ce3b23dd91a4.tar.gz
edk2-acd32208b0de487aefa859665f66ce3b23dd91a4.tar.bz2
edk2-acd32208b0de487aefa859665f66ce3b23dd91a4.zip
MdeModulePkg: Add ESRT management module.
It provides a repository to cache ESRT info for FMP or Non-FMP instance. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Chao Zhang <chao.b.zhang@intel.com> Reviewed-by: Gao Liming <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17426 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal/EsrtDxe')
-rw-r--r--MdeModulePkg/Universal/EsrtDxe/EsrtDxe.c652
-rw-r--r--MdeModulePkg/Universal/EsrtDxe/EsrtDxe.inf70
-rw-r--r--MdeModulePkg/Universal/EsrtDxe/EsrtDxe.unibin0 -> 2510 bytes
-rw-r--r--MdeModulePkg/Universal/EsrtDxe/EsrtDxeExtra.unibin0 -> 1314 bytes
-rw-r--r--MdeModulePkg/Universal/EsrtDxe/EsrtImpl.c438
-rw-r--r--MdeModulePkg/Universal/EsrtDxe/EsrtImpl.h245
6 files changed, 1405 insertions, 0 deletions
diff --git a/MdeModulePkg/Universal/EsrtDxe/EsrtDxe.c b/MdeModulePkg/Universal/EsrtDxe/EsrtDxe.c
new file mode 100644
index 0000000000..742abde4a6
--- /dev/null
+++ b/MdeModulePkg/Universal/EsrtDxe/EsrtDxe.c
@@ -0,0 +1,652 @@
+/** @file
+ Esrt management module.
+
+Copyright (c) 2015, 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.
+
+**/
+#include "EsrtImpl.h"
+
+
+//
+// Module globals.
+//
+
+ESRT_PRIVATE_DATA mPrivate;
+
+ESRT_MANAGEMENT_PROTOCOL mEsrtManagementProtocolTemplate = {
+ EsrtDxeGetEsrtEntry,
+ EsrtDxeUpdateEsrtEntry,
+ EsrtDxeRegisterEsrtEntry,
+ EsrtDxeUnRegisterEsrtEntry,
+ EsrtDxeSyncFmp,
+ EsrtDxeLockEsrtRepository
+ };
+
+/**
+ Get ESRT entry from ESRT Cache by FwClass Guid
+
+ @param[in] FwClass FwClass of Esrt entry to get
+ @param[in out] Entry Esrt entry returned
+
+ @retval EFI_SUCCESS The variable saving this Esrt Entry exists.
+ @retval EF_NOT_FOUND No correct variable found.
+ @retval EFI_WRITE_PROTECTED ESRT Cache repository is locked
+
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeGetEsrtEntry(
+ IN EFI_GUID *FwClass,
+ IN OUT EFI_SYSTEM_RESOURCE_ENTRY *Entry
+ )
+{
+ EFI_STATUS Status;
+
+ if (FwClass == NULL || Entry == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Find in Non-FMP Cached Esrt Repository
+ //
+ Status = GetEsrtEntry(
+ FwClass,
+ ESRT_FROM_NONFMP,
+ Entry
+ );
+
+ EfiReleaseLock(&mPrivate.NonFmpLock);
+
+ if (EFI_ERROR(Status)) {
+ Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Find in FMP Cached Esrt NV Variable
+ //
+ Status = GetEsrtEntry(
+ FwClass,
+ ESRT_FROM_FMP,
+ Entry
+ );
+
+ EfiReleaseLock(&mPrivate.FmpLock);
+ }
+
+ return Status;
+}
+
+/**
+ Update one ESRT entry in ESRT Cache.
+
+ @param[in] Entry Esrt entry to be updated
+
+ @retval EFI_SUCCESS Successfully update an ESRT entry in cache.
+ @retval EFI_INVALID_PARAMETER Entry does't exist in ESRT Cache
+ @retval EFI_WRITE_PROTECTED ESRT Cache repositoy is locked
+
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeUpdateEsrtEntry(
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry
+ )
+{
+ EFI_STATUS Status;
+
+ if (Entry == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = UpdateEsrtEntry(Entry, ESRT_FROM_FMP);
+
+ if (!EFI_ERROR(Status)) {
+ EfiReleaseLock(&mPrivate.FmpLock);
+ return Status;
+ }
+ EfiReleaseLock(&mPrivate.FmpLock);
+
+
+ Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = UpdateEsrtEntry(Entry, ESRT_FROM_NONFMP);
+
+ EfiReleaseLock(&mPrivate.NonFmpLock);
+
+ return Status;
+}
+
+/**
+ Non-FMP instance to unregister Esrt Entry from ESRT Cache.
+
+ @param[in] FwClass FwClass of Esrt entry to Unregister
+
+ @retval EFI_SUCCESS Insert all entries Successfully
+ @retval EFI_NOT_FOUND Entry of FwClass does not exsit
+
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeUnRegisterEsrtEntry(
+ IN EFI_GUID *FwClass
+ )
+{
+ EFI_STATUS Status;
+
+ if (FwClass == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = DeleteEsrtEntry(FwClass, ESRT_FROM_NONFMP);
+
+ EfiReleaseLock(&mPrivate.NonFmpLock);
+
+ return Status;
+}
+
+/**
+ Non-FMP instance to register one ESRT entry into ESRT Cache.
+
+ @param[in] Entry Esrt entry to be set
+
+ @retval EFI_SUCCESS Successfully set a variable.
+ @retval EFI_INVALID_PARAMETER ESRT Entry is already exist
+ @retval EFI_OUT_OF_RESOURCES Non-FMP ESRT repository is full
+
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeRegisterEsrtEntry(
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry
+ )
+{
+ EFI_STATUS Status;
+ EFI_SYSTEM_RESOURCE_ENTRY EsrtEntryTmp;
+
+ if (Entry == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = GetEsrtEntry(
+ &Entry->FwClass,
+ ESRT_FROM_NONFMP,
+ &EsrtEntryTmp
+ );
+
+ if (Status == EFI_NOT_FOUND) {
+ Status = InsertEsrtEntry(Entry, ESRT_FROM_NONFMP);
+ }
+
+ EfiReleaseLock(&mPrivate.NonFmpLock);
+
+ return Status;
+}
+
+/**
+ This function syn up Cached ESRT with data from FMP instances
+ Function should be called after Connect All in order to locate all FMP protocols
+ installed
+
+ @retval EFI_SUCCESS Successfully sync cache repository from FMP instances
+ @retval EFI_NOT_FOUND No FMP Instance are found
+ @retval EFI_OUT_OF_RESOURCES Resource allocaton fail
+
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeSyncFmp(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index1;
+ UINTN Index2;
+ UINTN Index3;
+ EFI_HANDLE *HandleBuffer;
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL **FmpBuf;
+ UINTN NumberOfHandles;
+ UINTN *DescriptorSizeBuf;
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR **FmpImageInfoBuf;
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR *TempFmpImageInfo;
+ UINT8 *FmpImageInfoCountBuf;
+ UINT32 *FmpImageInfoDescriptorVerBuf;
+ UINTN ImageInfoSize;
+ UINT32 PackageVersion;
+ CHAR16 *PackageVersionName;
+ EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepositoryNew;
+ UINTN EntryNumNew;
+
+ NumberOfHandles = 0;
+ EntryNumNew = 0;
+ FmpBuf = NULL;
+ HandleBuffer = NULL;
+ FmpImageInfoBuf = NULL;
+ FmpImageInfoCountBuf = NULL;
+ PackageVersionName = NULL;
+ DescriptorSizeBuf = NULL;
+ FmpImageInfoDescriptorVerBuf = NULL;
+ EsrtRepositoryNew = NULL;
+
+ //
+ // Get image information from all FMP protocol
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareManagementProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+
+
+ if (Status == EFI_NOT_FOUND) {
+ EntryNumNew = 0;
+ goto UPDATE_REPOSITORY;
+ } else if (EFI_ERROR(Status)){
+ goto END;
+ }
+
+ //
+ // Allocate buffer to hold new FMP ESRT Cache repository
+ //
+ EsrtRepositoryNew = AllocateZeroPool(PcdGet32(PcdMaxFmpEsrtCacheNum) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
+ if (EsrtRepositoryNew == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+
+ FmpBuf = AllocatePool(sizeof(EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) * NumberOfHandles);
+ if (FmpBuf == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+
+ FmpImageInfoBuf = AllocateZeroPool(sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfHandles);
+ if (FmpImageInfoBuf == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+
+ FmpImageInfoCountBuf = AllocateZeroPool(sizeof(UINT8) * NumberOfHandles);
+ if (FmpImageInfoCountBuf == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+
+ DescriptorSizeBuf = AllocateZeroPool(sizeof(UINTN) * NumberOfHandles);
+ if (DescriptorSizeBuf == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+
+ FmpImageInfoDescriptorVerBuf = AllocateZeroPool(sizeof(UINT32) * NumberOfHandles);
+ if (FmpImageInfoDescriptorVerBuf == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+
+ //
+ // Get all FmpImageInfo Descriptor into FmpImageInfoBuf
+ //
+ for (Index1 = 0; Index1 < NumberOfHandles; Index1++){
+ Status = gBS->HandleProtocol(
+ HandleBuffer[Index1],
+ &gEfiFirmwareManagementProtocolGuid,
+ (VOID **)&FmpBuf[Index1]
+ );
+
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ ImageInfoSize = 0;
+ Status = FmpBuf[Index1]->GetImageInfo (
+ FmpBuf[Index1],
+ &ImageInfoSize,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FmpImageInfoBuf[Index1] = AllocateZeroPool(ImageInfoSize);
+ if (FmpImageInfoBuf[Index1] == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+ } else {
+ continue;
+ }
+
+ PackageVersionName = NULL;
+ Status = FmpBuf[Index1]->GetImageInfo (
+ FmpBuf[Index1],
+ &ImageInfoSize,
+ FmpImageInfoBuf[Index1],
+ &FmpImageInfoDescriptorVerBuf[Index1],
+ &FmpImageInfoCountBuf[Index1],
+ &DescriptorSizeBuf[Index1],
+ &PackageVersion,
+ &PackageVersionName
+ );
+
+ //
+ // If FMP GetInformation interface failed, skip this resource
+ //
+ if (EFI_ERROR(Status)){
+ FmpImageInfoCountBuf[Index1] = 0;
+ continue;
+ }
+
+ if (PackageVersionName != NULL) {
+ FreePool(PackageVersionName);
+ }
+ }
+
+ //
+ // Create new FMP cache repository based on FmpImageInfoBuf
+ //
+ for (Index2 = 0; Index2 < NumberOfHandles; Index2++){
+ TempFmpImageInfo = FmpImageInfoBuf[Index2];
+ for (Index3 = 0; Index3 < FmpImageInfoCountBuf[Index2]; Index3++){
+ if ((TempFmpImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE) != 0
+ && (TempFmpImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IN_USE) != 0){
+ //
+ // Always put the first smallest version of Image info into ESRT cache
+ //
+ for(Index1 = 0; Index1 < EntryNumNew; Index1++) {
+ if (CompareGuid(&EsrtRepositoryNew[Index1].FwClass, &TempFmpImageInfo->ImageTypeId)) {
+ if(EsrtRepositoryNew[Index1].FwVersion > TempFmpImageInfo->Version) {
+ SetEsrtEntryFromFmpInfo(&EsrtRepositoryNew[Index1], TempFmpImageInfo, FmpImageInfoDescriptorVerBuf[Index2]);
+ }
+ break;
+ }
+ }
+ //
+ // New ImageTypeId can't be found in EsrtRepositoryNew. Create a new one
+ //
+ if (Index1 == EntryNumNew){
+ SetEsrtEntryFromFmpInfo(&EsrtRepositoryNew[EntryNumNew], TempFmpImageInfo, FmpImageInfoDescriptorVerBuf[Index2]);
+ EntryNumNew++;
+ if (EntryNumNew >= PcdGet32(PcdMaxFmpEsrtCacheNum)) {
+ break;
+ }
+ }
+ }
+
+ //
+ // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version
+ //
+ TempFmpImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)TempFmpImageInfo + DescriptorSizeBuf[Index2]);
+ }
+ }
+
+UPDATE_REPOSITORY:
+
+ Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable(
+ EFI_ESRT_FMP_VARIABLE_NAME,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ EntryNumNew * sizeof(EFI_SYSTEM_RESOURCE_ENTRY),
+ EsrtRepositoryNew
+ );
+
+ EfiReleaseLock(&mPrivate.FmpLock);
+
+END:
+ if (EsrtRepositoryNew != NULL) {
+ FreePool(EsrtRepositoryNew);
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool(HandleBuffer);
+ }
+
+ if (FmpBuf != NULL) {
+ FreePool(FmpBuf);
+ }
+
+ if (FmpImageInfoCountBuf != NULL) {
+ FreePool(FmpImageInfoCountBuf);
+ }
+
+ if (DescriptorSizeBuf != NULL) {
+ FreePool(DescriptorSizeBuf);
+ }
+
+ if (FmpImageInfoDescriptorVerBuf != NULL) {
+ FreePool(FmpImageInfoDescriptorVerBuf);
+ }
+
+ if (FmpImageInfoBuf != NULL) {
+ for (Index1 = 0; Index1 < NumberOfHandles; Index1++){
+ if (FmpImageInfoBuf[Index1] != NULL) {
+ FreePool(FmpImageInfoBuf[Index1]);
+ }
+ }
+ FreePool(FmpImageInfoBuf);
+ }
+
+ return Status;
+}
+
+/**
+ This function locks up Esrt repository to be readonly. It should be called
+ before gEfiEndOfDxeEventGroupGuid event signaled
+
+ @retval EFI_SUCCESS Locks up FMP Non-FMP repository successfully
+
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeLockEsrtRepository(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;
+ //
+ // Mark ACPI_GLOBAL_VARIABLE variable to read-only if the Variable Lock protocol exists
+ //
+ Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);
+ if (!EFI_ERROR (Status)) {
+ Status = VariableLock->RequestToLock (VariableLock, EFI_ESRT_FMP_VARIABLE_NAME, &gEfiCallerIdGuid);
+ DEBUG((EFI_D_INFO, "EsrtDxe Lock EsrtFmp Variable Status 0x%x", Status));
+
+ Status = VariableLock->RequestToLock (VariableLock, EFI_ESRT_NONFMP_VARIABLE_NAME, &gEfiCallerIdGuid);
+ DEBUG((EFI_D_INFO, "EsrtDxe Lock EsrtNonFmp Variable Status 0x%x", Status));
+ }
+
+ return Status;
+}
+
+/**
+ Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to
+ install the Esrt Table into system configuration 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
+ )
+{
+ EFI_STATUS Status;
+ EFI_SYSTEM_RESOURCE_TABLE *EsrtTable;
+ EFI_SYSTEM_RESOURCE_ENTRY *FmpEsrtRepository;
+ EFI_SYSTEM_RESOURCE_ENTRY *NonFmpEsrtRepository;
+ UINTN FmpRepositorySize;
+ UINTN NonFmpRepositorySize;
+
+
+ FmpEsrtRepository = NULL;
+ NonFmpEsrtRepository = NULL;
+ FmpRepositorySize = 0;
+ NonFmpRepositorySize = 0;
+
+ Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ Status = GetVariable2 (
+ EFI_ESRT_NONFMP_VARIABLE_NAME,
+ &gEfiCallerIdGuid,
+ (VOID **) &NonFmpEsrtRepository,
+ &NonFmpRepositorySize
+ );
+
+ if (EFI_ERROR(Status)) {
+ NonFmpRepositorySize = 0;
+ }
+
+ if (NonFmpRepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
+ DEBUG((EFI_D_ERROR, "NonFmp Repository Corrupt. Need to rebuild NonFmp Repository.\n"));
+ NonFmpRepositorySize = 0;
+ }
+
+ EfiReleaseLock(&mPrivate.NonFmpLock);
+
+ Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);
+ Status = GetVariable2 (
+ EFI_ESRT_FMP_VARIABLE_NAME,
+ &gEfiCallerIdGuid,
+ (VOID **) &FmpEsrtRepository,
+ &FmpRepositorySize
+ );
+
+ if (EFI_ERROR(Status)) {
+ FmpRepositorySize = 0;
+ }
+
+ if (FmpRepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
+ DEBUG((EFI_D_ERROR, "Fmp Repository Corrupt. Need to rebuild Fmp Repository.\n"));
+ FmpRepositorySize = 0;
+ }
+
+ EfiReleaseLock(&mPrivate.FmpLock);
+
+ //
+ // Skip ESRT table publish if no ESRT entry exists
+ //
+ if (NonFmpRepositorySize + FmpRepositorySize == 0) {
+ goto EXIT;
+ }
+
+ EsrtTable = AllocatePool(sizeof(EFI_SYSTEM_RESOURCE_TABLE) + NonFmpRepositorySize + FmpRepositorySize);
+ if (EsrtTable == NULL) {
+ DEBUG ((EFI_D_ERROR, "Esrt table memory allocation failure\n"));
+ goto EXIT;
+ }
+
+ EsrtTable->FwResourceVersion = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;
+ EsrtTable->FwResourceCount = (UINT32)((NonFmpRepositorySize + FmpRepositorySize) / sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
+ EsrtTable->FwResourceCountMax = PcdGet32(PcdMaxNonFmpEsrtCacheNum) + PcdGet32(PcdMaxFmpEsrtCacheNum);
+
+ CopyMem(EsrtTable + 1, NonFmpEsrtRepository, NonFmpRepositorySize);
+ CopyMem((UINT8 *)(EsrtTable + 1) + NonFmpRepositorySize, FmpEsrtRepository, FmpRepositorySize);
+
+ //
+ // Publish Esrt to system config table
+ //
+ Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, EsrtTable);
+
+ //
+ // Only one successful install
+ //
+ gBS->CloseEvent(Event);
+
+EXIT:
+
+ if (FmpEsrtRepository != NULL) {
+ FreePool(FmpEsrtRepository);
+ }
+
+ if (NonFmpEsrtRepository != NULL) {
+ FreePool(NonFmpEsrtRepository);
+ }
+}
+
+
+EFI_STATUS
+EFIAPI
+EsrtDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ EfiInitializeLock (&mPrivate.FmpLock, TPL_CALLBACK);
+ EfiInitializeLock (&mPrivate.NonFmpLock, TPL_CALLBACK);
+
+ //
+ // Install Esrt management Protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mPrivate.Handle,
+ &gEsrtManagementProtocolGuid,
+ &mEsrtManagementProtocolTemplate,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register notify function to install Esrt Table on ReadyToBoot Event.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ EsrtReadyToBootEventNotify,
+ NULL,
+ &gEfiEventReadyToBootGuid,
+ &mPrivate.Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Universal/EsrtDxe/EsrtDxe.inf b/MdeModulePkg/Universal/EsrtDxe/EsrtDxe.inf
new file mode 100644
index 0000000000..573f8cd32b
--- /dev/null
+++ b/MdeModulePkg/Universal/EsrtDxe/EsrtDxe.inf
@@ -0,0 +1,70 @@
+## @file
+# Esrt DXE driver that manages cached ESRT repository & publishes ESRT table
+#
+# This driver produces EsrtManagement protocol to manage cache ESRT repository for FMP/Non-FMP instances.
+# ESRT table based on repository is published on gEfiEventReadyToBootGuid.
+#
+# Copyright (c) 2015, 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EsrtDxe
+ FILE_GUID = 999BD818-7DF7-4A9A-A502-9B75033E6A0F
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = EsrtDxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ EsrtImpl.c
+ EsrtDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseMemoryLib
+ UefiLib
+ PcdLib
+ DebugLib
+ MemoryAllocationLib
+ DxeServicesTableLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ PrintLib
+
+[Guids]
+ gEfiSystemResourceTableGuid ## PRODUCES
+ gEfiEventReadyToBootGuid ## CONSUMES
+
+[Protocols]
+ gEfiFirmwareManagementProtocolGuid ## SOMETIMES_CONSUMES
+ gEsrtManagementProtocolGuid ## PRODUCES
+ gEdkiiVariableLockProtocolGuid ## CONSUMES
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxFmpEsrtCacheNum ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxNonFmpEsrtCacheNum ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSystemRebootAfterCapsuleProcessFlag ## CONSUMES
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ EsrtDxeExtra.uni
diff --git a/MdeModulePkg/Universal/EsrtDxe/EsrtDxe.uni b/MdeModulePkg/Universal/EsrtDxe/EsrtDxe.uni
new file mode 100644
index 0000000000..029041531d
--- /dev/null
+++ b/MdeModulePkg/Universal/EsrtDxe/EsrtDxe.uni
Binary files differ
diff --git a/MdeModulePkg/Universal/EsrtDxe/EsrtDxeExtra.uni b/MdeModulePkg/Universal/EsrtDxe/EsrtDxeExtra.uni
new file mode 100644
index 0000000000..dc762dd93a
--- /dev/null
+++ b/MdeModulePkg/Universal/EsrtDxe/EsrtDxeExtra.uni
Binary files differ
diff --git a/MdeModulePkg/Universal/EsrtDxe/EsrtImpl.c b/MdeModulePkg/Universal/EsrtDxe/EsrtImpl.c
new file mode 100644
index 0000000000..09255bd632
--- /dev/null
+++ b/MdeModulePkg/Universal/EsrtDxe/EsrtImpl.c
@@ -0,0 +1,438 @@
+/** @file
+ Esrt management implementation.
+
+Copyright (c) 2015, 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.
+
+**/
+
+#include "EsrtImpl.h"
+
+/**
+ Find Esrt Entry stored in ESRT repository.
+
+ @param[in] FwClass Firmware class guid in Esrt entry
+ @param[in] Attribute Esrt from Non FMP or FMP instance
+ @param[out] Entry Esrt entry returned
+
+ @retval EFI_SUCCESS Successfully find an Esrt entry
+ @retval EF_NOT_FOUND No Esrt entry found
+
+**/
+EFI_STATUS
+GetEsrtEntry (
+ IN EFI_GUID *FwClass,
+ IN UINTN Attribute,
+ OUT EFI_SYSTEM_RESOURCE_ENTRY *Entry
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *VariableName;
+ EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;
+ UINTN RepositorySize;
+ UINTN Index;
+ UINTN EsrtNum;
+
+ EsrtRepository = NULL;
+
+ //
+ // Get Esrt index buffer
+ //
+ if (Attribute == ESRT_FROM_FMP) {
+ VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
+ } else {
+ VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
+ }
+
+ Status = GetVariable2 (
+ VariableName,
+ &gEfiCallerIdGuid,
+ (VOID **) &EsrtRepository,
+ &RepositorySize
+ );
+
+ if (EFI_ERROR(Status)) {
+ goto EXIT;
+ }
+
+ if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
+ DEBUG((EFI_D_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
+ Status = EFI_ABORTED;
+ goto EXIT;
+ }
+
+ Status = EFI_NOT_FOUND;
+ EsrtNum = RepositorySize/sizeof(EFI_SYSTEM_RESOURCE_ENTRY);
+ for (Index = 0; Index < EsrtNum; Index++) {
+ if (CompareGuid(FwClass, &EsrtRepository[Index].FwClass)) {
+ CopyMem(Entry, &EsrtRepository[Index], sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+
+EXIT:
+ if (EsrtRepository != NULL) {
+ FreePool(EsrtRepository);
+ }
+
+ return Status;
+}
+
+/**
+ Insert a new ESRT entry into ESRT Cache repository.
+
+ @param[in] Entry Esrt entry to be set
+ @param[in] Attribute Esrt from Esrt private protocol or FMP instance
+
+ @retval EFI_SUCCESS Successfully set a variable.
+
+**/
+EFI_STATUS
+InsertEsrtEntry(
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry,
+ UINTN Attribute
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *VariableName;
+ EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;
+ UINTN RepositorySize;
+ EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepositoryNew;
+
+ EsrtRepository = NULL;
+ EsrtRepositoryNew = NULL;
+
+ //
+ // Get Esrt index buffer
+ //
+ if (Attribute == ESRT_FROM_FMP) {
+ VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
+ } else {
+ VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
+ }
+
+ Status = GetVariable2 (
+ VariableName,
+ &gEfiCallerIdGuid,
+ (VOID **) &EsrtRepository,
+ &RepositorySize
+ );
+
+ if (Status == EFI_NOT_FOUND) {
+ //
+ // If not exist, create new Esrt cache repository
+ //
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(EFI_SYSTEM_RESOURCE_ENTRY),
+ Entry
+ );
+ return Status;
+
+ } else if (Status == EFI_SUCCESS) {
+ //
+ // if exist, update Esrt cache repository
+ //
+ if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
+ DEBUG((EFI_D_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
+ //
+ // Repository is corrupt. Clear Repository before insert new entry
+ //
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0,
+ EsrtRepository
+ );
+ FreePool(EsrtRepository);
+ RepositorySize = 0;
+ EsrtRepository = NULL;
+ }
+
+ //
+ // Check Repository size constraint
+ //
+ if ((Attribute == ESRT_FROM_FMP && RepositorySize >= PcdGet32(PcdMaxFmpEsrtCacheNum) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY))
+ ||(Attribute == ESRT_FROM_NONFMP && RepositorySize >= PcdGet32(PcdMaxNonFmpEsrtCacheNum) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY)) ) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ EsrtRepositoryNew = AllocatePool(RepositorySize + sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
+ if (EsrtRepositoryNew == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ if (RepositorySize != 0) {
+ CopyMem(EsrtRepositoryNew, EsrtRepository, RepositorySize);
+ }
+ CopyMem((UINT8 *)EsrtRepositoryNew + RepositorySize, Entry, sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
+
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ RepositorySize + sizeof(EFI_SYSTEM_RESOURCE_ENTRY),
+ EsrtRepositoryNew
+ );
+ }
+
+EXIT:
+ if (EsrtRepository != NULL) {
+ FreePool(EsrtRepository);
+ }
+
+ if (EsrtRepositoryNew != NULL) {
+ FreePool(EsrtRepositoryNew);
+ }
+
+ return Status;
+}
+
+/**
+ Delete ESRT Entry from ESRT repository.
+
+ @param[in] FwClass FwClass of Esrt entry to delete
+ @param[in] Attribute Esrt from Esrt private protocol or FMP instance
+
+ @retval EFI_SUCCESS Insert all entries Successfully
+ @retval EFI_NOT_FOUND ESRT entry with FwClass doesn't exsit
+
+**/
+EFI_STATUS
+DeleteEsrtEntry(
+ IN EFI_GUID *FwClass,
+ IN UINTN Attribute
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *VariableName;
+ EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;
+ UINTN RepositorySize;
+ UINTN Index;
+ UINTN EsrtNum;
+
+ EsrtRepository = NULL;
+
+ //
+ // Get Esrt index buffer
+ //
+ if (Attribute == ESRT_FROM_FMP) {
+ VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
+ } else {
+ VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
+ }
+
+ Status = GetVariable2 (
+ VariableName,
+ &gEfiCallerIdGuid,
+ (VOID **) &EsrtRepository,
+ &RepositorySize
+ );
+
+ if (EFI_ERROR(Status)) {
+ goto EXIT;
+ }
+
+ if ((RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY)) != 0) {
+ DEBUG((EFI_D_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
+ //
+ // Repository is corrupt. Clear Repository before insert new entry
+ //
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0,
+ EsrtRepository
+ );
+ goto EXIT;
+ }
+
+ Status = EFI_NOT_FOUND;
+ EsrtNum = RepositorySize/sizeof(EFI_SYSTEM_RESOURCE_ENTRY);
+ for (Index = 0; Index < EsrtNum; Index++) {
+ //
+ // Delete Esrt entry if it is found in repository
+ //
+ if (CompareGuid(FwClass, &EsrtRepository[Index].FwClass)) {
+ //
+ // If delete Esrt entry is not at the rail
+ //
+ if (Index < EsrtNum - 1) {
+ CopyMem(&EsrtRepository[Index], &EsrtRepository[Index + 1], (EsrtNum - Index - 1) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
+ }
+
+ //
+ // Update New Repository
+ //
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ (EsrtNum - 1) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY),
+ EsrtRepository
+ );
+ break;
+ }
+ }
+
+EXIT:
+ if (EsrtRepository != NULL) {
+ FreePool(EsrtRepository);
+ }
+
+ return Status;
+
+}
+
+/**
+ Update one ESRT entry in ESRT repository
+
+ @param[in] Entry Esrt entry to be set
+ @param[in] Attribute Esrt from Non Esrt or FMP instance
+
+ @retval EFI_SUCCESS Successfully Update a variable.
+ @retval EFI_NOT_FOUND The Esrt enry doesn't exist
+
+**/
+EFI_STATUS
+UpdateEsrtEntry(
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry,
+ UINTN Attribute
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *VariableName;
+ EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;
+ UINTN RepositorySize;
+ UINTN Index;
+ UINTN EsrtNum;
+
+ EsrtRepository = NULL;
+
+ //
+ // Get Esrt index buffer
+ //
+ if (Attribute == ESRT_FROM_FMP) {
+ VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
+ } else {
+ VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
+ }
+
+ Status = GetVariable2 (
+ VariableName,
+ &gEfiCallerIdGuid,
+ (VOID **) &EsrtRepository,
+ &RepositorySize
+ );
+
+ if (!EFI_ERROR(Status)) {
+ //
+ // if exist, update Esrt cache repository
+ //
+ if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
+ DEBUG((EFI_D_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
+ //
+ // Repository is corrupt. Clear Repository before insert new entry
+ //
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0,
+ EsrtRepository
+ );
+ Status = EFI_NOT_FOUND;
+ goto EXIT;
+ }
+
+ Status = EFI_NOT_FOUND;
+ EsrtNum = RepositorySize/sizeof(EFI_SYSTEM_RESOURCE_ENTRY);
+ for (Index = 0; Index < EsrtNum; Index++) {
+ //
+ // Update Esrt entry if it is found in repository
+ //
+ if (CompareGuid(&Entry->FwClass, &EsrtRepository[Index].FwClass)) {
+
+ CopyMem(&EsrtRepository[Index], Entry, sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
+ //
+ // Update New Repository
+ //
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ RepositorySize,
+ EsrtRepository
+ );
+ break;
+ }
+ }
+ }
+
+EXIT:
+ if (EsrtRepository != NULL) {
+ FreePool(EsrtRepository);
+ }
+
+ return Status;
+}
+
+/**
+ Init one ESRT entry according to input FmpImageInfo (V1, V2, V3) .
+
+ @param[in] EsrtEntry Esrt entry to be Init
+ @param[in] FmpImageInfo FMP image info descriptor
+ @param[in] DescriptorVersion FMP Image info descriptor version
+
+**/
+VOID
+SetEsrtEntryFromFmpInfo (
+ IN OUT EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry,
+ IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo,
+ IN UINT32 DescriptorVersion
+ )
+{
+ EsrtEntry->FwVersion = FmpImageInfo->Version;
+ EsrtEntry->FwClass = FmpImageInfo->ImageTypeId;
+ EsrtEntry->FwType = ESRT_FW_TYPE_DEVICEFIRMWARE;
+ EsrtEntry->LowestSupportedFwVersion = 0;
+ EsrtEntry->CapsuleFlags = 0;
+ EsrtEntry->LastAttemptVersion = 0;
+ EsrtEntry->LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
+
+ if (DescriptorVersion >= 2) {
+ //
+ // LowestSupportedImageVersion only available in FMP V2 or higher
+ //
+ EsrtEntry->LowestSupportedFwVersion = FmpImageInfo->LowestSupportedImageVersion;
+ }
+
+ if (DescriptorVersion >= 3) {
+ //
+ // LastAttemptVersion & LastAttemptStatus only available in FMP V3 or higher
+ //
+ EsrtEntry->LastAttemptVersion = FmpImageInfo->LastAttemptVersion;
+ EsrtEntry->LastAttemptStatus = FmpImageInfo->LastAttemptStatus;
+ }
+
+ //
+ // Set capsule customized flag
+ //
+ if ((FmpImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0
+ && (FmpImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0) {
+ EsrtEntry->CapsuleFlags = PcdGet16(PcdSystemRebootAfterCapsuleProcessFlag);
+ }
+}
diff --git a/MdeModulePkg/Universal/EsrtDxe/EsrtImpl.h b/MdeModulePkg/Universal/EsrtDxe/EsrtImpl.h
new file mode 100644
index 0000000000..b26cbd2590
--- /dev/null
+++ b/MdeModulePkg/Universal/EsrtDxe/EsrtImpl.h
@@ -0,0 +1,245 @@
+/** @file
+ Esrt management implementation head file.
+
+Copyright (c) 2015, 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.
+
+**/
+
+#ifndef _DXE_ESRT_IMPL_H_
+#define _DXE_ESRT_IMPL_H_
+
+#include <Guid/EventGroup.h>
+#include <Guid/SystemResourceTable.h>
+
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/CapsuleLib.h>
+#include <Library/PrintLib.h>
+
+#include <Protocol/FirmwareManagement.h>
+#include <Protocol/EsrtManagement.h>
+#include <Protocol/VariableLock.h>
+
+//
+// Name of Variable for Non-FMP ESRT Repository
+//
+#define EFI_ESRT_NONFMP_VARIABLE_NAME L"EsrtNonFmp"
+
+//
+// Name of Variable for FMP
+//
+#define EFI_ESRT_FMP_VARIABLE_NAME L"EsrtFmp"
+
+//
+// Attribute of Cached ESRT entry
+//
+#define ESRT_FROM_FMP 0x00000001
+#define ESRT_FROM_NONFMP 0x00000002
+
+typedef struct {
+ EFI_HANDLE Handle;
+ //
+ // Ready to boot event
+ //
+ EFI_EVENT Event;
+
+ //
+ // Updates to Fmp storage must be locked.
+ //
+ EFI_LOCK FmpLock;
+
+ //
+ // Update to Non-Fmp storage must be locked
+ //
+ EFI_LOCK NonFmpLock;
+} ESRT_PRIVATE_DATA;
+
+
+/**
+ Find Esrt Entry stored in ESRT repository.
+
+ @param[in] FwClass Firmware class guid in Esrt entry
+ @param[in] Attribute Esrt from Non FMP or FMP instance
+ @param[out] Entry Esrt entry returned
+
+ @retval EFI_SUCCESS Successfully find an Esrt entry
+ @retval EF_NOT_FOUND No Esrt entry found
+
+**/
+EFI_STATUS
+GetEsrtEntry (
+ IN EFI_GUID *FwClass,
+ IN UINTN Attribute,
+ OUT EFI_SYSTEM_RESOURCE_ENTRY *Entry
+ );
+
+/**
+ Insert a new ESRT entry into ESRT Cache repository.
+
+ @param[in] Entry Esrt entry to be set
+ @param[in] Attribute Esrt from Esrt private protocol or FMP instance
+
+ @retval EFI_SUCCESS Successfully set a variable.
+
+**/
+EFI_STATUS
+InsertEsrtEntry(
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry,
+ UINTN Attribute
+ );
+
+/**
+ Delete ESRT Entry from ESRT repository.
+
+ @param[in] FwClass FwClass of Esrt entry to delete
+ @param[in] Attribute Esrt from Esrt private protocol or FMP instance
+
+ @retval EFI_SUCCESS Insert all entries Successfully
+ @retval EFI_NOT_FOUND ESRT entry with FwClass doesn't exsit
+
+**/
+EFI_STATUS
+DeleteEsrtEntry(
+ IN EFI_GUID *FwClass,
+ IN UINTN Attribute
+ );
+
+/**
+ Update one ESRT entry in ESRT repository
+
+ @param[in] Entry Esrt entry to be set
+ @param[in] Attribute Esrt from Non Esrt or FMP instance
+
+ @retval EFI_SUCCESS Successfully Update a variable.
+ @retval EFI_NOT_FOUND The Esrt enry doesn't exist
+
+**/
+EFI_STATUS
+UpdateEsrtEntry(
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry,
+ UINTN Attribute
+ );
+
+/**
+ Init one ESRT entry according to input FmpImageInfo (V1, V2, V3) .
+
+ @param[in] EsrtEntry Esrt entry to be Init
+ @param[in] FmpImageInfo FMP image info descriptor
+ @param[in] DescriptorVersion FMP Image info descriptor version
+
+**/
+VOID
+SetEsrtEntryFromFmpInfo (
+ IN OUT EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry,
+ IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo,
+ IN UINT32 DescriptorVersion
+ );
+
+/**
+ Get ESRT entry from ESRT Cache by FwClass Guid
+
+ @param[in] FwClass FwClass of Esrt entry to get
+ @param[in out] Entry Esrt entry returned
+
+ @retval EFI_SUCCESS The variable saving this Esrt Entry exists.
+ @retval EF_NOT_FOUND No correct variable found.
+ @retval EFI_WRITE_PROTECTED ESRT Cache repository is locked
+
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeGetEsrtEntry(
+ IN EFI_GUID *FwClass,
+ IN OUT EFI_SYSTEM_RESOURCE_ENTRY *Entry
+ );
+
+/**
+ Update one ESRT entry in ESRT Cache.
+
+ @param[in] Entry Esrt entry to be updated
+
+ @retval EFI_SUCCESS Successfully update an ESRT entry in cache.
+ @retval EFI_INVALID_PARAMETER Entry does't exist in ESRT Cache
+ @retval EFI_WRITE_PROTECTED ESRT Cache is locked
+
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeUpdateEsrtEntry(
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry
+ );
+
+/**
+ Non-FMP instance to unregister Esrt Entry from ESRT Cache.
+
+ @param[in] FwClass FwClass of Esrt entry to Unregister
+
+ @retval EFI_SUCCESS Insert all entries Successfully
+ @retval EFI_NOT_FOUND Entry of FwClass does not exsit
+
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeUnRegisterEsrtEntry(
+ IN EFI_GUID *FwClass
+ );
+
+/**
+ Non-FMP instance to register one ESRT entry into ESRT Cache.
+
+ @param[in] Entry Esrt entry to be set
+
+ @retval EFI_SUCCESS Successfully set a variable.
+ @retval EFI_INVALID_PARAMETER ESRT Entry is already exist
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeRegisterEsrtEntry(
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry
+ );
+
+/**
+ This function syn up Cached ESRT with data from FMP instances
+ Function should be called after Connect All in order to locate all FMP protocols
+ installed
+
+ @retval EFI_SUCCESS Successfully sync cache repository from FMP instances
+ @retval EFI_NOT_FOUND No FMP Instance are found
+ @retval EFI_OUT_OF_RESOURCES Resource allocaton fail
+
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeSyncFmp(
+ VOID
+ );
+
+/**
+ This function locks up Esrt repository to be readonly. It should be called
+ before gEfiEndOfDxeEventGroupGuid event signaled
+
+ @retval EFI_SUCCESS Locks up FMP Non-FMP repository successfully
+
+**/
+EFI_STATUS
+EFIAPI
+EsrtDxeLockEsrtRepository(
+ VOID
+ );
+
+#endif // #ifndef _EFI_ESRT_IMPL_H_
+