From acd32208b0de487aefa859665f66ce3b23dd91a4 Mon Sep 17 00:00:00 2001 From: Chao Zhang Date: Wed, 13 May 2015 08:30:45 +0000 Subject: [PATCH] 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 Reviewed-by: Gao Liming git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17426 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/MdeModulePkg.dsc | 1 + MdeModulePkg/Universal/EsrtDxe/EsrtDxe.c | 652 ++++++++++++++++++ MdeModulePkg/Universal/EsrtDxe/EsrtDxe.inf | 70 ++ MdeModulePkg/Universal/EsrtDxe/EsrtDxe.uni | Bin 0 -> 2510 bytes .../Universal/EsrtDxe/EsrtDxeExtra.uni | Bin 0 -> 1314 bytes MdeModulePkg/Universal/EsrtDxe/EsrtImpl.c | 438 ++++++++++++ MdeModulePkg/Universal/EsrtDxe/EsrtImpl.h | 245 +++++++ 7 files changed, 1406 insertions(+) create mode 100644 MdeModulePkg/Universal/EsrtDxe/EsrtDxe.c create mode 100644 MdeModulePkg/Universal/EsrtDxe/EsrtDxe.inf create mode 100644 MdeModulePkg/Universal/EsrtDxe/EsrtDxe.uni create mode 100644 MdeModulePkg/Universal/EsrtDxe/EsrtDxeExtra.uni create mode 100644 MdeModulePkg/Universal/EsrtDxe/EsrtImpl.c create mode 100644 MdeModulePkg/Universal/EsrtDxe/EsrtImpl.h diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 16a6eb5774..d0832bc215 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -354,6 +354,7 @@ } MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf + MdeModulePkg/Universal/EsrtDxe/EsrtDxe.inf [Components.IA32, Components.X64, Components.IPF] MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf 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.
+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.
+# 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 0000000000000000000000000000000000000000..029041531d47685014f49c780bad05595e5590b4 GIT binary patch literal 2510 zcmdUxUuzRV6vgke;CC2O5S2Dj!50y+FYdG&W@vY8~L z=u1Hf+xd6r+%xCiJJVl38`dz#_ne=z_cpT3uIVU70k?RicQA8DdRh4pYYA>#s>J$SkpeC z#C;`rT8-=?%P#iXwaIP<`V{{+Fsbmud5%`tPFTzR8G^l74f(FYQ{UO@*;Y@s%5VF* zM(meP2XDA)tbw zC@B`Pc7zptO+bn)m4C8SjRbwPIwfAA=CrR#O|@tb*SJJ2zWb_B4GMStv>6`58zq(Ra_kT5L6qn5@ICQKd{a%(ZacMI zX4~l8qnCKCdsJ|Xeu_8ttyIJ7Zm_9q-ZE z8CI!hcFcSmRAF?y_mq*iYfe79*vdv;gVh1H^8S_fGb>`QT1*yR!YLB&^$I7VxBY!} z=zX@fR=(bhhUYF#_3bS4C)82U?;NBKo_pkJV&^cDUQ%`+we%v~_uKK6Bdi;8MemC9 zIk5+pnAX7i_g<&kQj@>aL)mnS63VobWdyfr@@GBb?YI6)|DW$*b<0=nH|~R=?lyHE fa!#4{kS}qS$J^iE_&)2u2i?mfUaR;D22Fkgg#d{f literal 0 HcmV?d00001 diff --git a/MdeModulePkg/Universal/EsrtDxe/EsrtDxeExtra.uni b/MdeModulePkg/Universal/EsrtDxe/EsrtDxeExtra.uni new file mode 100644 index 0000000000000000000000000000000000000000..dc762dd93a7e250e5fa1a1282f8f9b5f9da7fcd8 GIT binary patch literal 1314 zcmZXUTW=Ck6ovP*iT~k*zNl$IO?)xN2r}x#mLU{keQE}1=_Fj50o&q_SHHFA)?&z< z%f76=&N`d(_fN+<7WiKA3--ybEwiOv*>ih_Rldl!mfOzy_JBRuscmd#DN&jI#xlot zjz4F=wgu4v@7nF3iCyEn^0C6K=3w&Q+TL>)c0**a7ofjnervDojlHvD)^UllWUZW> zER87{nb&CJ>B317Vp5=qOHTDIUv78KwrwA*XCwPqpRwUHhC}8jxFvoAifXJtsZO*b zLMo)NoDs2tiG2I=^Z|=lsb0ov30i}nVpX=Zo3UCuGbvc%D|=p6xMQu`NNvifykBI< zo3pN%6tz~)x3c8`=*@9emX_ujSYszP1G=dN{| z^XJ@X=Ro}}mMPrlc5>ipgL1=HX;RHP&o}-T!G`ovVqY1%cE&zN(}1d)$5>-JZNe&Y zr6)FEj<7cf%`L=qc0|OvBPXoX(HdLK!WC+Zx#xTBj%#kge&83c#4BpwrIMHpu*aYZ zBk}4ZcH%CZYL1CgjH(tU;KEWl}38)kBBVq=yJYy9c?T8!He_+9_r;O@3^}z}8 a;-_jYqKg+zH+A8;eeYYn4>^8CRo_1l?8*TE literal 0 HcmV?d00001 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.
+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.
+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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// +// 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_ + -- 2.39.2