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