+/** @file\r
+ Esrt management module.\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#include "EsrtImpl.h"\r
+\r
+\r
+//\r
+// Module globals.\r
+//\r
+\r
+ESRT_PRIVATE_DATA mPrivate;\r
+\r
+ESRT_MANAGEMENT_PROTOCOL mEsrtManagementProtocolTemplate = { \r
+ EsrtDxeGetEsrtEntry,\r
+ EsrtDxeUpdateEsrtEntry,\r
+ EsrtDxeRegisterEsrtEntry,\r
+ EsrtDxeUnRegisterEsrtEntry,\r
+ EsrtDxeSyncFmp,\r
+ EsrtDxeLockEsrtRepository\r
+ };\r
+\r
+/**\r
+ Get ESRT entry from ESRT Cache by FwClass Guid \r
+\r
+ @param[in] FwClass FwClass of Esrt entry to get \r
+ @param[in out] Entry Esrt entry returned \r
+ \r
+ @retval EFI_SUCCESS The variable saving this Esrt Entry exists.\r
+ @retval EF_NOT_FOUND No correct variable found.\r
+ @retval EFI_WRITE_PROTECTED ESRT Cache repository is locked\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EsrtDxeGetEsrtEntry(\r
+ IN EFI_GUID *FwClass,\r
+ IN OUT EFI_SYSTEM_RESOURCE_ENTRY *Entry\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if (FwClass == NULL || Entry == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Find in Non-FMP Cached Esrt Repository\r
+ //\r
+ Status = GetEsrtEntry(\r
+ FwClass,\r
+ ESRT_FROM_NONFMP,\r
+ Entry\r
+ );\r
+\r
+ EfiReleaseLock(&mPrivate.NonFmpLock);\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Find in FMP Cached Esrt NV Variable\r
+ //\r
+ Status = GetEsrtEntry(\r
+ FwClass,\r
+ ESRT_FROM_FMP,\r
+ Entry\r
+ );\r
+\r
+ EfiReleaseLock(&mPrivate.FmpLock);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Update one ESRT entry in ESRT Cache.\r
+\r
+ @param[in] Entry Esrt entry to be updated\r
+ \r
+ @retval EFI_SUCCESS Successfully update an ESRT entry in cache.\r
+ @retval EFI_INVALID_PARAMETER Entry does't exist in ESRT Cache\r
+ @retval EFI_WRITE_PROTECTED ESRT Cache repositoy is locked\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EsrtDxeUpdateEsrtEntry(\r
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ \r
+ if (Entry == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = UpdateEsrtEntry(Entry, ESRT_FROM_FMP);\r
+\r
+ if (!EFI_ERROR(Status)) {\r
+ EfiReleaseLock(&mPrivate.FmpLock);\r
+ return Status;\r
+ }\r
+ EfiReleaseLock(&mPrivate.FmpLock);\r
+\r
+\r
+ Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = UpdateEsrtEntry(Entry, ESRT_FROM_NONFMP);\r
+\r
+ EfiReleaseLock(&mPrivate.NonFmpLock);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Non-FMP instance to unregister Esrt Entry from ESRT Cache. \r
+\r
+ @param[in] FwClass FwClass of Esrt entry to Unregister \r
+ \r
+ @retval EFI_SUCCESS Insert all entries Successfully \r
+ @retval EFI_NOT_FOUND Entry of FwClass does not exsit\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EsrtDxeUnRegisterEsrtEntry(\r
+ IN EFI_GUID *FwClass\r
+ )\r
+{\r
+ EFI_STATUS Status; \r
+\r
+ if (FwClass == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = DeleteEsrtEntry(FwClass, ESRT_FROM_NONFMP);\r
+\r
+ EfiReleaseLock(&mPrivate.NonFmpLock);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Non-FMP instance to register one ESRT entry into ESRT Cache.\r
+\r
+ @param[in] Entry Esrt entry to be set\r
+\r
+ @retval EFI_SUCCESS Successfully set a variable.\r
+ @retval EFI_INVALID_PARAMETER ESRT Entry is already exist\r
+ @retval EFI_OUT_OF_RESOURCES Non-FMP ESRT repository is full\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EsrtDxeRegisterEsrtEntry(\r
+ IN EFI_SYSTEM_RESOURCE_ENTRY *Entry\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_SYSTEM_RESOURCE_ENTRY EsrtEntryTmp;\r
+\r
+ if (Entry == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = GetEsrtEntry(\r
+ &Entry->FwClass,\r
+ ESRT_FROM_NONFMP,\r
+ &EsrtEntryTmp\r
+ );\r
+\r
+ if (Status == EFI_NOT_FOUND) {\r
+ Status = InsertEsrtEntry(Entry, ESRT_FROM_NONFMP);\r
+ }\r
+\r
+ EfiReleaseLock(&mPrivate.NonFmpLock);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function syn up Cached ESRT with data from FMP instances\r
+ Function should be called after Connect All in order to locate all FMP protocols\r
+ installed\r
+\r
+ @retval EFI_SUCCESS Successfully sync cache repository from FMP instances\r
+ @retval EFI_NOT_FOUND No FMP Instance are found\r
+ @retval EFI_OUT_OF_RESOURCES Resource allocaton fail\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EsrtDxeSyncFmp(\r
+ VOID\r
+ ) \r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index1;\r
+ UINTN Index2;\r
+ UINTN Index3;\r
+ EFI_HANDLE *HandleBuffer;\r
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL **FmpBuf;\r
+ UINTN NumberOfHandles;\r
+ UINTN *DescriptorSizeBuf;\r
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR **FmpImageInfoBuf; \r
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR *TempFmpImageInfo; \r
+ UINT8 *FmpImageInfoCountBuf;\r
+ UINT32 *FmpImageInfoDescriptorVerBuf;\r
+ UINTN ImageInfoSize;\r
+ UINT32 PackageVersion;\r
+ CHAR16 *PackageVersionName;\r
+ EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepositoryNew;\r
+ UINTN EntryNumNew;\r
+\r
+ NumberOfHandles = 0;\r
+ EntryNumNew = 0;\r
+ FmpBuf = NULL;\r
+ HandleBuffer = NULL;\r
+ FmpImageInfoBuf = NULL;\r
+ FmpImageInfoCountBuf = NULL;\r
+ PackageVersionName = NULL;\r
+ DescriptorSizeBuf = NULL;\r
+ FmpImageInfoDescriptorVerBuf = NULL;\r
+ EsrtRepositoryNew = NULL;\r
+\r
+ //\r
+ // Get image information from all FMP protocol\r
+ //\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiFirmwareManagementProtocolGuid,\r
+ NULL,\r
+ &NumberOfHandles,\r
+ &HandleBuffer\r
+ );\r
+\r
+ \r
+ if (Status == EFI_NOT_FOUND) { \r
+ EntryNumNew = 0;\r
+ goto UPDATE_REPOSITORY;\r
+ } else if (EFI_ERROR(Status)){ \r
+ goto END;\r
+ }\r
+\r
+ //\r
+ // Allocate buffer to hold new FMP ESRT Cache repository\r
+ //\r
+ EsrtRepositoryNew = AllocateZeroPool(PcdGet32(PcdMaxFmpEsrtCacheNum) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY));\r
+ if (EsrtRepositoryNew == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto END;\r
+ }\r
+\r
+ FmpBuf = AllocatePool(sizeof(EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) * NumberOfHandles);\r
+ if (FmpBuf == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto END;\r
+ }\r
+\r
+ FmpImageInfoBuf = AllocateZeroPool(sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfHandles);\r
+ if (FmpImageInfoBuf == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES; \r
+ goto END;\r
+ }\r
+\r
+ FmpImageInfoCountBuf = AllocateZeroPool(sizeof(UINT8) * NumberOfHandles);\r
+ if (FmpImageInfoCountBuf == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto END;\r
+ }\r
+\r
+ DescriptorSizeBuf = AllocateZeroPool(sizeof(UINTN) * NumberOfHandles);\r
+ if (DescriptorSizeBuf == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto END;\r
+ }\r
+\r
+ FmpImageInfoDescriptorVerBuf = AllocateZeroPool(sizeof(UINT32) * NumberOfHandles);\r
+ if (FmpImageInfoDescriptorVerBuf == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto END;\r
+ }\r
+\r
+ //\r
+ // Get all FmpImageInfo Descriptor into FmpImageInfoBuf\r
+ //\r
+ for (Index1 = 0; Index1 < NumberOfHandles; Index1++){\r
+ Status = gBS->HandleProtocol(\r
+ HandleBuffer[Index1],\r
+ &gEfiFirmwareManagementProtocolGuid,\r
+ (VOID **)&FmpBuf[Index1]\r
+ );\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ continue;\r
+ }\r
+\r
+ ImageInfoSize = 0;\r
+ Status = FmpBuf[Index1]->GetImageInfo (\r
+ FmpBuf[Index1],\r
+ &ImageInfoSize,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL\r
+ );\r
+\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ FmpImageInfoBuf[Index1] = AllocateZeroPool(ImageInfoSize);\r
+ if (FmpImageInfoBuf[Index1] == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto END;\r
+ }\r
+ } else {\r
+ continue;\r
+ }\r
+\r
+ PackageVersionName = NULL;\r
+ Status = FmpBuf[Index1]->GetImageInfo (\r
+ FmpBuf[Index1],\r
+ &ImageInfoSize,\r
+ FmpImageInfoBuf[Index1],\r
+ &FmpImageInfoDescriptorVerBuf[Index1],\r
+ &FmpImageInfoCountBuf[Index1],\r
+ &DescriptorSizeBuf[Index1],\r
+ &PackageVersion,\r
+ &PackageVersionName\r
+ );\r
+\r
+ //\r
+ // If FMP GetInformation interface failed, skip this resource\r
+ //\r
+ if (EFI_ERROR(Status)){\r
+ FmpImageInfoCountBuf[Index1] = 0;\r
+ continue;\r
+ }\r
+\r
+ if (PackageVersionName != NULL) {\r
+ FreePool(PackageVersionName);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Create new FMP cache repository based on FmpImageInfoBuf\r
+ // \r
+ for (Index2 = 0; Index2 < NumberOfHandles; Index2++){\r
+ TempFmpImageInfo = FmpImageInfoBuf[Index2];\r
+ for (Index3 = 0; Index3 < FmpImageInfoCountBuf[Index2]; Index3++){\r
+ if ((TempFmpImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE) != 0 \r
+ && (TempFmpImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IN_USE) != 0){\r
+ //\r
+ // Always put the first smallest version of Image info into ESRT cache \r
+ //\r
+ for(Index1 = 0; Index1 < EntryNumNew; Index1++) {\r
+ if (CompareGuid(&EsrtRepositoryNew[Index1].FwClass, &TempFmpImageInfo->ImageTypeId)) {\r
+ if(EsrtRepositoryNew[Index1].FwVersion > TempFmpImageInfo->Version) {\r
+ SetEsrtEntryFromFmpInfo(&EsrtRepositoryNew[Index1], TempFmpImageInfo, FmpImageInfoDescriptorVerBuf[Index2]);\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ //\r
+ // New ImageTypeId can't be found in EsrtRepositoryNew. Create a new one\r
+ //\r
+ if (Index1 == EntryNumNew){\r
+ SetEsrtEntryFromFmpInfo(&EsrtRepositoryNew[EntryNumNew], TempFmpImageInfo, FmpImageInfoDescriptorVerBuf[Index2]);\r
+ EntryNumNew++; \r
+ if (EntryNumNew >= PcdGet32(PcdMaxFmpEsrtCacheNum)) {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version\r
+ //\r
+ TempFmpImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)TempFmpImageInfo + DescriptorSizeBuf[Index2]);\r
+ }\r
+ }\r
+\r
+UPDATE_REPOSITORY:\r
+\r
+ Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = gRT->SetVariable(\r
+ EFI_ESRT_FMP_VARIABLE_NAME,\r
+ &gEfiCallerIdGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+ EntryNumNew * sizeof(EFI_SYSTEM_RESOURCE_ENTRY),\r
+ EsrtRepositoryNew\r
+ );\r
+\r
+ EfiReleaseLock(&mPrivate.FmpLock);\r
+\r
+END:\r
+ if (EsrtRepositoryNew != NULL) {\r
+ FreePool(EsrtRepositoryNew);\r
+ }\r
+\r
+ if (HandleBuffer != NULL) {\r
+ FreePool(HandleBuffer);\r
+ }\r
+\r
+ if (FmpBuf != NULL) {\r
+ FreePool(FmpBuf);\r
+ }\r
+\r
+ if (FmpImageInfoCountBuf != NULL) {\r
+ FreePool(FmpImageInfoCountBuf);\r
+ }\r
+\r
+ if (DescriptorSizeBuf != NULL) {\r
+ FreePool(DescriptorSizeBuf);\r
+ }\r
+\r
+ if (FmpImageInfoDescriptorVerBuf != NULL) {\r
+ FreePool(FmpImageInfoDescriptorVerBuf);\r
+ }\r
+\r
+ if (FmpImageInfoBuf != NULL) {\r
+ for (Index1 = 0; Index1 < NumberOfHandles; Index1++){\r
+ if (FmpImageInfoBuf[Index1] != NULL) {\r
+ FreePool(FmpImageInfoBuf[Index1]);\r
+ }\r
+ }\r
+ FreePool(FmpImageInfoBuf);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function locks up Esrt repository to be readonly. It should be called \r
+ before gEfiEndOfDxeEventGroupGuid event signaled\r
+\r
+ @retval EFI_SUCCESS Locks up FMP Non-FMP repository successfully \r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EsrtDxeLockEsrtRepository(\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;\r
+ //\r
+ // Mark ACPI_GLOBAL_VARIABLE variable to read-only if the Variable Lock protocol exists\r
+ //\r
+ Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = VariableLock->RequestToLock (VariableLock, EFI_ESRT_FMP_VARIABLE_NAME, &gEfiCallerIdGuid);\r
+ DEBUG((EFI_D_INFO, "EsrtDxe Lock EsrtFmp Variable Status 0x%x", Status));\r
+\r
+ Status = VariableLock->RequestToLock (VariableLock, EFI_ESRT_NONFMP_VARIABLE_NAME, &gEfiCallerIdGuid);\r
+ DEBUG((EFI_D_INFO, "EsrtDxe Lock EsrtNonFmp Variable Status 0x%x", Status));\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to\r
+ install the Esrt Table into system configuration table\r
+\r
+ @param[in] Event The Event that is being processed.\r
+ @param[in] Context The Event Context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EsrtReadyToBootEventNotify (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{ \r
+ EFI_STATUS Status;\r
+ EFI_SYSTEM_RESOURCE_TABLE *EsrtTable;\r
+ EFI_SYSTEM_RESOURCE_ENTRY *FmpEsrtRepository;\r
+ EFI_SYSTEM_RESOURCE_ENTRY *NonFmpEsrtRepository;\r
+ UINTN FmpRepositorySize;\r
+ UINTN NonFmpRepositorySize;\r
+ \r
+\r
+ FmpEsrtRepository = NULL;\r
+ NonFmpEsrtRepository = NULL;\r
+ FmpRepositorySize = 0;\r
+ NonFmpRepositorySize = 0;\r
+\r
+ Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);\r
+ if (EFI_ERROR (Status)) {\r
+ return;\r
+ }\r
+\r
+ Status = GetVariable2 (\r
+ EFI_ESRT_NONFMP_VARIABLE_NAME,\r
+ &gEfiCallerIdGuid,\r
+ (VOID **) &NonFmpEsrtRepository,\r
+ &NonFmpRepositorySize\r
+ );\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ NonFmpRepositorySize = 0;\r
+ }\r
+\r
+ if (NonFmpRepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {\r
+ DEBUG((EFI_D_ERROR, "NonFmp Repository Corrupt. Need to rebuild NonFmp Repository.\n"));\r
+ NonFmpRepositorySize = 0;\r
+ }\r
+\r
+ EfiReleaseLock(&mPrivate.NonFmpLock);\r
+\r
+ Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);\r
+ Status = GetVariable2 (\r
+ EFI_ESRT_FMP_VARIABLE_NAME,\r
+ &gEfiCallerIdGuid,\r
+ (VOID **) &FmpEsrtRepository,\r
+ &FmpRepositorySize\r
+ );\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ FmpRepositorySize = 0;\r
+ }\r
+\r
+ if (FmpRepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {\r
+ DEBUG((EFI_D_ERROR, "Fmp Repository Corrupt. Need to rebuild Fmp Repository.\n"));\r
+ FmpRepositorySize = 0;\r
+ }\r
+\r
+ EfiReleaseLock(&mPrivate.FmpLock);\r
+\r
+ //\r
+ // Skip ESRT table publish if no ESRT entry exists\r
+ //\r
+ if (NonFmpRepositorySize + FmpRepositorySize == 0) {\r
+ goto EXIT;\r
+ }\r
+\r
+ EsrtTable = AllocatePool(sizeof(EFI_SYSTEM_RESOURCE_TABLE) + NonFmpRepositorySize + FmpRepositorySize);\r
+ if (EsrtTable == NULL) {\r
+ DEBUG ((EFI_D_ERROR, "Esrt table memory allocation failure\n"));\r
+ goto EXIT;\r
+ }\r
+\r
+ EsrtTable->FwResourceVersion = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION; \r
+ EsrtTable->FwResourceCount = (UINT32)((NonFmpRepositorySize + FmpRepositorySize) / sizeof(EFI_SYSTEM_RESOURCE_ENTRY)); \r
+ EsrtTable->FwResourceCountMax = PcdGet32(PcdMaxNonFmpEsrtCacheNum) + PcdGet32(PcdMaxFmpEsrtCacheNum);\r
+\r
+ CopyMem(EsrtTable + 1, NonFmpEsrtRepository, NonFmpRepositorySize);\r
+ CopyMem((UINT8 *)(EsrtTable + 1) + NonFmpRepositorySize, FmpEsrtRepository, FmpRepositorySize);\r
+\r
+ //\r
+ // Publish Esrt to system config table\r
+ //\r
+ Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, EsrtTable);\r
+\r
+ //\r
+ // Only one successful install\r
+ //\r
+ gBS->CloseEvent(Event);\r
+\r
+EXIT:\r
+\r
+ if (FmpEsrtRepository != NULL) {\r
+ FreePool(FmpEsrtRepository);\r
+ }\r
+\r
+ if (NonFmpEsrtRepository != NULL) {\r
+ FreePool(NonFmpEsrtRepository);\r
+ }\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EsrtDxeEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{ \r
+ EFI_STATUS Status;\r
+\r
+ EfiInitializeLock (&mPrivate.FmpLock, TPL_CALLBACK);\r
+ EfiInitializeLock (&mPrivate.NonFmpLock, TPL_CALLBACK);\r
+\r
+ //\r
+ // Install Esrt management Protocol\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mPrivate.Handle,\r
+ &gEsrtManagementProtocolGuid,\r
+ &mEsrtManagementProtocolTemplate,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Register notify function to install Esrt Table on ReadyToBoot Event.\r
+ //\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ EsrtReadyToBootEventNotify,\r
+ NULL,\r
+ &gEfiEventReadyToBootGuid,\r
+ &mPrivate.Event\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return EFI_SUCCESS;\r
+}\r