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
EsrtDxeGetEsrtEntry(IN EFI_GUID * FwClass,IN OUT EFI_SYSTEM_RESOURCE_ENTRY * Entry)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
EsrtDxeUpdateEsrtEntry(IN EFI_SYSTEM_RESOURCE_ENTRY * Entry)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
EsrtDxeUnRegisterEsrtEntry(IN EFI_GUID * FwClass)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
EsrtDxeRegisterEsrtEntry(IN EFI_SYSTEM_RESOURCE_ENTRY * Entry)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
EsrtDxeSyncFmp(VOID)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
EsrtDxeLockEsrtRepository(VOID)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
EsrtReadyToBootEventNotify(IN EFI_EVENT Event,IN VOID * Context)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
EsrtDxeEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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