Home | History | Annotate | Download | only in EsrtDxe
      1 /** @file
      2   Esrt management module.
      3 
      4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 #include "EsrtImpl.h"
     15 
     16 
     17 //
     18 // Module globals.
     19 //
     20 
     21 ESRT_PRIVATE_DATA mPrivate;
     22 
     23 ESRT_MANAGEMENT_PROTOCOL  mEsrtManagementProtocolTemplate = {
     24                             EsrtDxeGetEsrtEntry,
     25                             EsrtDxeUpdateEsrtEntry,
     26                             EsrtDxeRegisterEsrtEntry,
     27                             EsrtDxeUnRegisterEsrtEntry,
     28                             EsrtDxeSyncFmp,
     29                             EsrtDxeLockEsrtRepository
     30                             };
     31 
     32 /**
     33   Get ESRT entry from ESRT Cache by FwClass Guid
     34 
     35   @param[in]       FwClass                FwClass of Esrt entry to get
     36   @param[in, out]  Entry                  Esrt entry returned
     37 
     38   @retval EFI_SUCCESS                   The variable saving this Esrt Entry exists.
     39   @retval EF_NOT_FOUND                  No correct variable found.
     40   @retval EFI_WRITE_PROTECTED           ESRT Cache repository is locked
     41 
     42 **/
     43 EFI_STATUS
     44 EFIAPI
     45 EsrtDxeGetEsrtEntry(
     46   IN     EFI_GUID                  *FwClass,
     47   IN OUT EFI_SYSTEM_RESOURCE_ENTRY *Entry
     48   )
     49 {
     50   EFI_STATUS                Status;
     51 
     52   if (FwClass == NULL || Entry == NULL) {
     53     return EFI_INVALID_PARAMETER;
     54   }
     55 
     56   Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);
     57   if (EFI_ERROR (Status)) {
     58     return Status;
     59   }
     60 
     61   //
     62   // Find in Non-FMP Cached Esrt Repository
     63   //
     64   Status = GetEsrtEntry(
     65              FwClass,
     66              ESRT_FROM_NONFMP,
     67              Entry
     68              );
     69 
     70   EfiReleaseLock(&mPrivate.NonFmpLock);
     71 
     72   if (EFI_ERROR(Status)) {
     73     Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);
     74     if (EFI_ERROR (Status)) {
     75       return Status;
     76     }
     77 
     78     //
     79     // Find in FMP Cached Esrt NV Variable
     80     //
     81     Status = GetEsrtEntry(
     82                FwClass,
     83                ESRT_FROM_FMP,
     84                Entry
     85                );
     86 
     87     EfiReleaseLock(&mPrivate.FmpLock);
     88   }
     89 
     90   return Status;
     91 }
     92 
     93 /**
     94   Update one ESRT entry in ESRT Cache.
     95 
     96   @param[in]  Entry                         Esrt entry to be updated
     97 
     98   @retval EFI_SUCCESS                   Successfully update an ESRT entry in cache.
     99   @retval EFI_INVALID_PARAMETER         Entry does't exist in ESRT Cache
    100   @retval EFI_WRITE_PROTECTED           ESRT Cache repositoy is locked
    101 
    102 **/
    103 EFI_STATUS
    104 EFIAPI
    105 EsrtDxeUpdateEsrtEntry(
    106   IN EFI_SYSTEM_RESOURCE_ENTRY *Entry
    107   )
    108 {
    109   EFI_STATUS                Status;
    110 
    111   if (Entry == NULL) {
    112     return EFI_INVALID_PARAMETER;
    113   }
    114 
    115   Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);
    116   if (EFI_ERROR (Status)) {
    117     return Status;
    118   }
    119 
    120   Status = UpdateEsrtEntry(Entry, ESRT_FROM_FMP);
    121 
    122   if (!EFI_ERROR(Status)) {
    123     EfiReleaseLock(&mPrivate.FmpLock);
    124     return Status;
    125   }
    126   EfiReleaseLock(&mPrivate.FmpLock);
    127 
    128 
    129   Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);
    130   if (EFI_ERROR (Status)) {
    131     return Status;
    132   }
    133 
    134   Status = UpdateEsrtEntry(Entry, ESRT_FROM_NONFMP);
    135 
    136   EfiReleaseLock(&mPrivate.NonFmpLock);
    137 
    138   return Status;
    139 }
    140 
    141 /**
    142   Non-FMP instance to unregister Esrt Entry from ESRT Cache.
    143 
    144   @param[in]    FwClass                FwClass of Esrt entry to Unregister
    145 
    146   @retval EFI_SUCCESS             Insert all entries Successfully
    147   @retval EFI_NOT_FOUND           Entry of FwClass does not exsit
    148 
    149 **/
    150 EFI_STATUS
    151 EFIAPI
    152 EsrtDxeUnRegisterEsrtEntry(
    153   IN  EFI_GUID        *FwClass
    154   )
    155 {
    156   EFI_STATUS Status;
    157 
    158   if (FwClass == NULL) {
    159     return EFI_INVALID_PARAMETER;
    160   }
    161 
    162   Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);
    163   if (EFI_ERROR (Status)) {
    164     return Status;
    165   }
    166 
    167   Status = DeleteEsrtEntry(FwClass, ESRT_FROM_NONFMP);
    168 
    169   EfiReleaseLock(&mPrivate.NonFmpLock);
    170 
    171   return Status;
    172 }
    173 
    174 /**
    175   Non-FMP instance to register one ESRT entry into ESRT Cache.
    176 
    177   @param[in]  Entry                Esrt entry to be set
    178 
    179   @retval EFI_SUCCESS              Successfully set a variable.
    180   @retval EFI_INVALID_PARAMETER    ESRT Entry is already exist
    181   @retval EFI_OUT_OF_RESOURCES     Non-FMP ESRT repository is full
    182 
    183 **/
    184 EFI_STATUS
    185 EFIAPI
    186 EsrtDxeRegisterEsrtEntry(
    187   IN EFI_SYSTEM_RESOURCE_ENTRY *Entry
    188   )
    189 {
    190   EFI_STATUS                Status;
    191   EFI_SYSTEM_RESOURCE_ENTRY EsrtEntryTmp;
    192 
    193   if (Entry == NULL) {
    194     return EFI_INVALID_PARAMETER;
    195   }
    196 
    197   Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);
    198   if (EFI_ERROR (Status)) {
    199     return Status;
    200   }
    201 
    202   Status = GetEsrtEntry(
    203              &Entry->FwClass,
    204              ESRT_FROM_NONFMP,
    205              &EsrtEntryTmp
    206              );
    207 
    208   if (Status == EFI_NOT_FOUND) {
    209     Status = InsertEsrtEntry(Entry, ESRT_FROM_NONFMP);
    210   }
    211 
    212   EfiReleaseLock(&mPrivate.NonFmpLock);
    213 
    214   return Status;
    215 }
    216 
    217 /**
    218   This function syn up Cached ESRT with data from FMP instances
    219   Function should be called after Connect All in order to locate all FMP protocols
    220   installed.
    221 
    222   @retval EFI_SUCCESS                      Successfully sync cache repository from FMP instances
    223   @retval EFI_NOT_FOUND                   No FMP Instance are found
    224   @retval EFI_OUT_OF_RESOURCES     Resource allocaton fail
    225 
    226 **/
    227 EFI_STATUS
    228 EFIAPI
    229 EsrtDxeSyncFmp(
    230   VOID
    231   )
    232 {
    233   EFI_STATUS                                Status;
    234   UINTN                                     Index1;
    235   UINTN                                     Index2;
    236   UINTN                                     Index3;
    237   EFI_HANDLE                                *HandleBuffer;
    238   EFI_FIRMWARE_MANAGEMENT_PROTOCOL          **FmpBuf;
    239   UINTN                                     NumberOfHandles;
    240   UINTN                                     *DescriptorSizeBuf;
    241   EFI_FIRMWARE_IMAGE_DESCRIPTOR             **FmpImageInfoBuf;
    242   EFI_FIRMWARE_IMAGE_DESCRIPTOR             *TempFmpImageInfo;
    243   UINT8                                     *FmpImageInfoCountBuf;
    244   UINT32                                    *FmpImageInfoDescriptorVerBuf;
    245   UINTN                                     ImageInfoSize;
    246   UINT32                                    PackageVersion;
    247   CHAR16                                    *PackageVersionName;
    248   EFI_SYSTEM_RESOURCE_ENTRY                 *EsrtRepositoryNew;
    249   UINTN                                     EntryNumNew;
    250 
    251   NumberOfHandles              = 0;
    252   EntryNumNew                  = 0;
    253   FmpBuf                       = NULL;
    254   HandleBuffer                 = NULL;
    255   FmpImageInfoBuf              = NULL;
    256   FmpImageInfoCountBuf         = NULL;
    257   PackageVersionName           = NULL;
    258   DescriptorSizeBuf            = NULL;
    259   FmpImageInfoDescriptorVerBuf = NULL;
    260   EsrtRepositoryNew            = NULL;
    261 
    262   //
    263   // Get image information from all FMP protocol
    264   //
    265   Status = gBS->LocateHandleBuffer (
    266                   ByProtocol,
    267                   &gEfiFirmwareManagementProtocolGuid,
    268                   NULL,
    269                   &NumberOfHandles,
    270                   &HandleBuffer
    271                   );
    272 
    273 
    274   if (Status == EFI_NOT_FOUND) {
    275     EntryNumNew = 0;
    276     goto UPDATE_REPOSITORY;
    277   } else if (EFI_ERROR(Status)){
    278     goto END;
    279   }
    280 
    281   //
    282   // Allocate buffer to hold new FMP ESRT Cache repository
    283   //
    284   EsrtRepositoryNew = AllocateZeroPool(PcdGet32(PcdMaxFmpEsrtCacheNum) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
    285   if (EsrtRepositoryNew == NULL) {
    286     Status = EFI_OUT_OF_RESOURCES;
    287     goto END;
    288   }
    289 
    290   FmpBuf = AllocatePool(sizeof(EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) * NumberOfHandles);
    291   if (FmpBuf == NULL) {
    292     Status = EFI_OUT_OF_RESOURCES;
    293     goto END;
    294   }
    295 
    296   FmpImageInfoBuf = AllocateZeroPool(sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfHandles);
    297   if (FmpImageInfoBuf == NULL) {
    298     Status = EFI_OUT_OF_RESOURCES;
    299     goto END;
    300   }
    301 
    302   FmpImageInfoCountBuf = AllocateZeroPool(sizeof(UINT8) * NumberOfHandles);
    303   if (FmpImageInfoCountBuf == NULL) {
    304     Status = EFI_OUT_OF_RESOURCES;
    305     goto END;
    306   }
    307 
    308   DescriptorSizeBuf = AllocateZeroPool(sizeof(UINTN) * NumberOfHandles);
    309   if (DescriptorSizeBuf == NULL) {
    310     Status = EFI_OUT_OF_RESOURCES;
    311     goto END;
    312   }
    313 
    314   FmpImageInfoDescriptorVerBuf = AllocateZeroPool(sizeof(UINT32) * NumberOfHandles);
    315    if (FmpImageInfoDescriptorVerBuf == NULL) {
    316     Status = EFI_OUT_OF_RESOURCES;
    317     goto END;
    318   }
    319 
    320   //
    321   // Get all FmpImageInfo Descriptor into FmpImageInfoBuf
    322   //
    323   for (Index1 = 0; Index1 < NumberOfHandles; Index1++){
    324     Status = gBS->HandleProtocol(
    325                     HandleBuffer[Index1],
    326                     &gEfiFirmwareManagementProtocolGuid,
    327                     (VOID **)&FmpBuf[Index1]
    328                     );
    329 
    330     if (EFI_ERROR(Status)) {
    331       continue;
    332     }
    333 
    334     ImageInfoSize = 0;
    335     Status = FmpBuf[Index1]->GetImageInfo (
    336                                FmpBuf[Index1],
    337                                &ImageInfoSize,
    338                                NULL,
    339                                NULL,
    340                                NULL,
    341                                NULL,
    342                                NULL,
    343                                NULL
    344                                );
    345 
    346     if (Status == EFI_BUFFER_TOO_SMALL) {
    347       FmpImageInfoBuf[Index1] = AllocateZeroPool(ImageInfoSize);
    348       if (FmpImageInfoBuf[Index1] == NULL) {
    349         Status = EFI_OUT_OF_RESOURCES;
    350         goto END;
    351       }
    352     } else {
    353       continue;
    354     }
    355 
    356     PackageVersionName = NULL;
    357     Status = FmpBuf[Index1]->GetImageInfo (
    358                                FmpBuf[Index1],
    359                                &ImageInfoSize,
    360                                FmpImageInfoBuf[Index1],
    361                                &FmpImageInfoDescriptorVerBuf[Index1],
    362                                &FmpImageInfoCountBuf[Index1],
    363                                &DescriptorSizeBuf[Index1],
    364                                &PackageVersion,
    365                                &PackageVersionName
    366                                );
    367 
    368     //
    369     // If FMP GetInformation interface failed, skip this resource
    370     //
    371     if (EFI_ERROR(Status)){
    372       FmpImageInfoCountBuf[Index1] = 0;
    373       continue;
    374     }
    375 
    376     if (PackageVersionName != NULL) {
    377       FreePool(PackageVersionName);
    378     }
    379   }
    380 
    381   //
    382   // Create new FMP cache repository based on FmpImageInfoBuf
    383   //
    384   for (Index2 = 0; Index2 < NumberOfHandles; Index2++){
    385     TempFmpImageInfo = FmpImageInfoBuf[Index2];
    386     for (Index3 = 0; Index3 < FmpImageInfoCountBuf[Index2]; Index3++){
    387       if ((TempFmpImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE) != 0
    388       && (TempFmpImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IN_USE) != 0){
    389         //
    390         // Always put the first smallest version of Image info into ESRT cache
    391         //
    392         for(Index1 = 0; Index1 < EntryNumNew; Index1++) {
    393           if (CompareGuid(&EsrtRepositoryNew[Index1].FwClass, &TempFmpImageInfo->ImageTypeId)) {
    394             if(EsrtRepositoryNew[Index1].FwVersion > TempFmpImageInfo->Version) {
    395               SetEsrtEntryFromFmpInfo(&EsrtRepositoryNew[Index1], TempFmpImageInfo, FmpImageInfoDescriptorVerBuf[Index2]);
    396             }
    397             break;
    398           }
    399         }
    400         //
    401         // New ImageTypeId can't be found in EsrtRepositoryNew. Create a new one
    402         //
    403         if (Index1 == EntryNumNew){
    404           SetEsrtEntryFromFmpInfo(&EsrtRepositoryNew[EntryNumNew], TempFmpImageInfo, FmpImageInfoDescriptorVerBuf[Index2]);
    405           EntryNumNew++;
    406           if (EntryNumNew >= PcdGet32(PcdMaxFmpEsrtCacheNum)) {
    407             break;
    408           }
    409         }
    410       }
    411 
    412       //
    413       // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version
    414       //
    415       TempFmpImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)TempFmpImageInfo + DescriptorSizeBuf[Index2]);
    416     }
    417   }
    418 
    419 UPDATE_REPOSITORY:
    420 
    421   Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);
    422   if (EFI_ERROR (Status)) {
    423     return Status;
    424   }
    425 
    426   Status = gRT->SetVariable(
    427                   EFI_ESRT_FMP_VARIABLE_NAME,
    428                   &gEfiCallerIdGuid,
    429                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
    430                   EntryNumNew * sizeof(EFI_SYSTEM_RESOURCE_ENTRY),
    431                   EsrtRepositoryNew
    432                   );
    433 
    434   EfiReleaseLock(&mPrivate.FmpLock);
    435 
    436 END:
    437   if (EsrtRepositoryNew != NULL) {
    438     FreePool(EsrtRepositoryNew);
    439   }
    440 
    441   if (HandleBuffer != NULL) {
    442     FreePool(HandleBuffer);
    443   }
    444 
    445   if (FmpBuf != NULL) {
    446     FreePool(FmpBuf);
    447   }
    448 
    449   if (FmpImageInfoCountBuf != NULL) {
    450     FreePool(FmpImageInfoCountBuf);
    451   }
    452 
    453   if (DescriptorSizeBuf != NULL) {
    454     FreePool(DescriptorSizeBuf);
    455   }
    456 
    457   if (FmpImageInfoDescriptorVerBuf != NULL) {
    458     FreePool(FmpImageInfoDescriptorVerBuf);
    459   }
    460 
    461   if (FmpImageInfoBuf != NULL) {
    462     for (Index1 = 0; Index1 < NumberOfHandles; Index1++){
    463       if (FmpImageInfoBuf[Index1] != NULL) {
    464         FreePool(FmpImageInfoBuf[Index1]);
    465       }
    466     }
    467     FreePool(FmpImageInfoBuf);
    468   }
    469 
    470   return Status;
    471 }
    472 
    473 /**
    474   This function locks up Esrt repository to be readonly. It should be called
    475   before gEfiEndOfDxeEventGroupGuid event signaled
    476 
    477   @retval EFI_SUCCESS              Locks up FMP Non-FMP repository successfully
    478 
    479 **/
    480 EFI_STATUS
    481 EFIAPI
    482 EsrtDxeLockEsrtRepository(
    483   VOID
    484   )
    485 {
    486   EFI_STATUS                    Status;
    487   EDKII_VARIABLE_LOCK_PROTOCOL  *VariableLock;
    488   //
    489   // Mark ACPI_GLOBAL_VARIABLE variable to read-only if the Variable Lock protocol exists
    490   //
    491   Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);
    492   if (!EFI_ERROR (Status)) {
    493     Status = VariableLock->RequestToLock (VariableLock, EFI_ESRT_FMP_VARIABLE_NAME, &gEfiCallerIdGuid);
    494     DEBUG((EFI_D_INFO, "EsrtDxe Lock EsrtFmp Variable Status 0x%x", Status));
    495 
    496     Status = VariableLock->RequestToLock (VariableLock, EFI_ESRT_NONFMP_VARIABLE_NAME, &gEfiCallerIdGuid);
    497     DEBUG((EFI_D_INFO, "EsrtDxe Lock EsrtNonFmp Variable Status 0x%x", Status));
    498   }
    499 
    500   return Status;
    501 }
    502 
    503 /**
    504   Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to
    505   install the Esrt Table into system configuration table
    506 
    507   @param[in]  Event   The Event that is being processed.
    508   @param[in]  Context The Event Context.
    509 
    510 **/
    511 VOID
    512 EFIAPI
    513 EsrtReadyToBootEventNotify (
    514   IN EFI_EVENT        Event,
    515   IN VOID             *Context
    516   )
    517 {
    518   EFI_STATUS                 Status;
    519   EFI_SYSTEM_RESOURCE_TABLE  *EsrtTable;
    520   EFI_SYSTEM_RESOURCE_ENTRY  *FmpEsrtRepository;
    521   EFI_SYSTEM_RESOURCE_ENTRY  *NonFmpEsrtRepository;
    522   UINTN                      FmpRepositorySize;
    523   UINTN                      NonFmpRepositorySize;
    524 
    525 
    526   FmpEsrtRepository    = NULL;
    527   NonFmpEsrtRepository = NULL;
    528   FmpRepositorySize    = 0;
    529   NonFmpRepositorySize = 0;
    530 
    531   Status = EfiAcquireLockOrFail (&mPrivate.NonFmpLock);
    532   if (EFI_ERROR (Status)) {
    533     return;
    534   }
    535 
    536   Status = GetVariable2 (
    537              EFI_ESRT_NONFMP_VARIABLE_NAME,
    538              &gEfiCallerIdGuid,
    539              (VOID **) &NonFmpEsrtRepository,
    540              &NonFmpRepositorySize
    541              );
    542 
    543   if (EFI_ERROR(Status)) {
    544     NonFmpRepositorySize = 0;
    545   }
    546 
    547   if (NonFmpRepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
    548     DEBUG((EFI_D_ERROR, "NonFmp Repository Corrupt. Need to rebuild NonFmp Repository.\n"));
    549     NonFmpRepositorySize = 0;
    550   }
    551 
    552   EfiReleaseLock(&mPrivate.NonFmpLock);
    553 
    554   Status = EfiAcquireLockOrFail (&mPrivate.FmpLock);
    555   Status = GetVariable2 (
    556              EFI_ESRT_FMP_VARIABLE_NAME,
    557              &gEfiCallerIdGuid,
    558              (VOID **) &FmpEsrtRepository,
    559              &FmpRepositorySize
    560              );
    561 
    562   if (EFI_ERROR(Status)) {
    563     FmpRepositorySize = 0;
    564   }
    565 
    566   if (FmpRepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
    567     DEBUG((EFI_D_ERROR, "Fmp Repository Corrupt. Need to rebuild Fmp Repository.\n"));
    568     FmpRepositorySize = 0;
    569   }
    570 
    571   EfiReleaseLock(&mPrivate.FmpLock);
    572 
    573   //
    574   // Skip ESRT table publish if no ESRT entry exists
    575   //
    576   if (NonFmpRepositorySize + FmpRepositorySize == 0) {
    577     goto EXIT;
    578   }
    579 
    580   EsrtTable = AllocatePool(sizeof(EFI_SYSTEM_RESOURCE_TABLE) + NonFmpRepositorySize + FmpRepositorySize);
    581   if (EsrtTable == NULL) {
    582     DEBUG ((EFI_D_ERROR, "Esrt table memory allocation failure\n"));
    583     goto EXIT;
    584   }
    585 
    586   EsrtTable->FwResourceVersion  = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;
    587   EsrtTable->FwResourceCount    = (UINT32)((NonFmpRepositorySize + FmpRepositorySize) / sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
    588   EsrtTable->FwResourceCountMax = PcdGet32(PcdMaxNonFmpEsrtCacheNum) + PcdGet32(PcdMaxFmpEsrtCacheNum);
    589 
    590   if (NonFmpRepositorySize != 0 && NonFmpEsrtRepository != NULL) {
    591     CopyMem(EsrtTable + 1, NonFmpEsrtRepository, NonFmpRepositorySize);
    592   }
    593 
    594   if (FmpRepositorySize != 0 && FmpEsrtRepository != NULL) {
    595     CopyMem((UINT8 *)(EsrtTable + 1) + NonFmpRepositorySize, FmpEsrtRepository, FmpRepositorySize);
    596   }
    597 
    598   //
    599   // Publish Esrt to system config table
    600   //
    601   Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, EsrtTable);
    602 
    603   //
    604   // Only one successful install
    605   //
    606   gBS->CloseEvent(Event);
    607 
    608 EXIT:
    609 
    610   if (FmpEsrtRepository != NULL) {
    611     FreePool(FmpEsrtRepository);
    612   }
    613 
    614   if (NonFmpEsrtRepository != NULL) {
    615     FreePool(NonFmpEsrtRepository);
    616   }
    617 }
    618 
    619 /**
    620   The module Entry Point of the Esrt DXE driver that manages cached ESRT repository
    621   & publishes ESRT table
    622 
    623   @param[in]  ImageHandle    The firmware allocated handle for the EFI image.
    624   @param[in]  SystemTable    A pointer to the EFI System Table.
    625 
    626   @retval EFI_SUCCESS    The entry point is executed successfully.
    627   @retval Other          Some error occurs when executing this entry point.
    628 
    629 **/
    630 EFI_STATUS
    631 EFIAPI
    632 EsrtDxeEntryPoint (
    633   IN EFI_HANDLE         ImageHandle,
    634   IN EFI_SYSTEM_TABLE   *SystemTable
    635   )
    636 {
    637   EFI_STATUS                    Status;
    638 
    639   EfiInitializeLock (&mPrivate.FmpLock,    TPL_CALLBACK);
    640   EfiInitializeLock (&mPrivate.NonFmpLock, TPL_CALLBACK);
    641 
    642   //
    643   // Install Esrt management Protocol
    644   //
    645   Status = gBS->InstallMultipleProtocolInterfaces (
    646                   &mPrivate.Handle,
    647                   &gEsrtManagementProtocolGuid,
    648                   &mEsrtManagementProtocolTemplate,
    649                   NULL
    650                   );
    651   ASSERT_EFI_ERROR (Status);
    652 
    653   //
    654   // Register notify function to install Esrt Table on ReadyToBoot Event.
    655   //
    656   Status = gBS->CreateEventEx (
    657                   EVT_NOTIFY_SIGNAL,
    658                   TPL_CALLBACK,
    659                   EsrtReadyToBootEventNotify,
    660                   NULL,
    661                   &gEfiEventReadyToBootGuid,
    662                   &mPrivate.Event
    663                   );
    664   ASSERT_EFI_ERROR (Status);
    665 
    666   return EFI_SUCCESS;
    667 }
    668