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