]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / EsrtFmpDxe / EsrtFmp.c
CommitLineData
4184aabd
MK
1/** @file\r
2 Publishes ESRT table from Firmware Management Protocol instances\r
3\r
4 Copyright (c) 2016, Microsoft Corporation\r
e314132f 5 Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>\r
4184aabd
MK
6\r
7 All rights reserved.\r
9d510e61 8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
4184aabd
MK
9\r
10**/\r
11\r
12#include <Uefi.h>\r
13#include <Library/BaseLib.h>\r
14#include <Library/BaseMemoryLib.h>\r
15#include <Library/MemoryAllocationLib.h>\r
16#include <Library/UefiBootServicesTableLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/PcdLib.h>\r
19#include <Library/UefiLib.h>\r
20#include <Protocol/FirmwareManagement.h>\r
21#include <Guid/EventGroup.h>\r
22#include <Guid/SystemResourceTable.h>\r
23\r
e314132f
JE
24///\r
25/// Structure for array of unique GUID/HardwareInstance pairs from the\r
26/// current set of EFI_FIRMWARE_IMAGE_DESCRIPTORs from all FMP Protocols.\r
27///\r
28typedef struct {\r
29 ///\r
30 /// A unique GUID identifying the firmware image type.\r
31 ///\r
1436aea4 32 EFI_GUID ImageTypeGuid;\r
e314132f
JE
33 ///\r
34 /// An optional number to identify the unique hardware instance within the\r
35 /// system for devices that may have multiple instances whenever possible.\r
36 ///\r
1436aea4 37 UINT64 HardwareInstance;\r
e314132f
JE
38} GUID_HARDWAREINSTANCE_PAIR;\r
39\r
ae38c976
DB
40/**\r
41 Print ESRT to debug console.\r
42\r
43 @param[in] Table Pointer to the ESRT table.\r
44\r
45**/\r
4184aabd
MK
46VOID\r
47EFIAPI\r
48PrintTable (\r
49 IN EFI_SYSTEM_RESOURCE_TABLE *Table\r
50 );\r
51\r
4184aabd
MK
52/**\r
53 Install EFI System Resource Table into the UEFI Configuration Table\r
54\r
6ec4d300
SZ
55 @param[in] Table Pointer to the ESRT.\r
56\r
4184aabd
MK
57 @return Status code.\r
58\r
59**/\r
60EFI_STATUS\r
61InstallEfiSystemResourceTableInUefiConfigurationTable (\r
1436aea4 62 IN EFI_SYSTEM_RESOURCE_TABLE *Table\r
4184aabd
MK
63 )\r
64{\r
1436aea4 65 EFI_STATUS Status;\r
4184aabd
MK
66\r
67 Status = EFI_SUCCESS;\r
6ec4d300
SZ
68 if (Table->FwResourceCount == 0) {\r
69 DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it has zero Entries. \n"));\r
70 Status = EFI_UNSUPPORTED;\r
71 } else {\r
72 //\r
73 // Install the pointer into config table\r
74 //\r
75 Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, Table);\r
76 if (EFI_ERROR (Status)) {\r
77 DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table. Status: %r. \n", Status));\r
4184aabd 78 } else {\r
6ec4d300 79 DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Installed ESRT table. \n"));\r
4184aabd
MK
80 }\r
81 }\r
1436aea4 82\r
4184aabd
MK
83 return Status;\r
84}\r
85\r
86/**\r
87 Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo.\r
88\r
89 @param[in] FmpImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR\r
90\r
91 @return TRUE It is a system FMP.\r
92 @return FALSE It is a device FMP.\r
93**/\r
94BOOLEAN\r
95IsSystemFmp (\r
96 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo\r
97 )\r
98{\r
99 GUID *Guid;\r
100 UINTN Count;\r
101 UINTN Index;\r
102\r
103 Guid = PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid);\r
1436aea4 104 Count = PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof (GUID);\r
4184aabd
MK
105\r
106 for (Index = 0; Index < Count; Index++, Guid++) {\r
107 if (CompareGuid (&FmpImageInfo->ImageTypeId, Guid)) {\r
108 return TRUE;\r
109 }\r
110 }\r
111\r
112 return FALSE;\r
113}\r
114\r
115/**\r
e314132f
JE
116 Function to create a single ESRT Entry and add it to the ESRT with\r
117 a given FMP descriptor. If the GUID is already in the ESRT, then the ESRT\r
118 entry is updated.\r
119\r
120 @param[in,out] Table Pointer to the ESRT Table.\r
121 @param[in,out] HardwareInstances Pointer to the GUID_HARDWAREINSTANCE_PAIR.\r
122 @param[in,out] NumberOfDescriptors The number of EFI_FIRMWARE_IMAGE_DESCRIPTORs.\r
123 @param[in] FmpImageInfoBuf Pointer to the EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
124 @param[in] FmpVersion FMP Version.\r
125\r
126 @retval EFI_SUCCESS FmpImageInfoBuf was use to fill in a new ESRT entry\r
127 in Table.\r
128 @retval EFI_SUCCESS The ImageTypeId GUID in FmpImageInfoBuf matches an\r
129 existing ESRT entry in Table, and the information\r
130 from FmpImageInfoBuf was merged into the the existing\r
131 ESRT entry.\r
132 @retval EFI_UNSPOORTED The GUID/HardareInstance in FmpImageInfoBuf has is a\r
133 duplicate.\r
4184aabd
MK
134\r
135**/\r
136EFI_STATUS\r
4184aabd 137CreateEsrtEntry (\r
e314132f
JE
138 IN OUT EFI_SYSTEM_RESOURCE_TABLE *Table,\r
139 IN OUT GUID_HARDWAREINSTANCE_PAIR *HardwareInstances,\r
140 IN OUT UINT32 *NumberOfDescriptors,\r
141 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf,\r
142 IN UINT32 FmpVersion\r
4184aabd
MK
143 )\r
144{\r
145 UINTN Index;\r
146 EFI_SYSTEM_RESOURCE_ENTRY *Entry;\r
e314132f 147 UINT64 FmpHardwareInstance;\r
4184aabd 148\r
e314132f
JE
149 FmpHardwareInstance = 0;\r
150 if (FmpVersion >= 3) {\r
151 FmpHardwareInstance = FmpImageInfoBuf->HardwareInstance;\r
152 }\r
4184aabd 153\r
4184aabd 154 //\r
e314132f 155 // Check to see of FmpImageInfoBuf GUID/HardwareInstance is unique\r
090642db 156 // Skip if HardwareInstance is 0 as this is the case if FmpVersion < 3\r
157 // or the device can not create a unique ID per UEFI specification\r
4184aabd 158 //\r
090642db 159 if (FmpHardwareInstance != 0) {\r
160 for (Index = 0; Index < *NumberOfDescriptors; Index++) {\r
161 if (CompareGuid (&HardwareInstances[Index].ImageTypeGuid, &FmpImageInfoBuf->ImageTypeId)) {\r
162 if (HardwareInstances[Index].HardwareInstance == FmpHardwareInstance) {\r
163 DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Duplicate firmware image descriptor with GUID %g HardwareInstance:0x%x\n", &FmpImageInfoBuf->ImageTypeId, FmpHardwareInstance));\r
164 ASSERT (\r
165 !CompareGuid (&HardwareInstances[Index].ImageTypeGuid, &FmpImageInfoBuf->ImageTypeId) ||\r
166 HardwareInstances[Index].HardwareInstance != FmpHardwareInstance\r
167 );\r
168 return EFI_UNSUPPORTED;\r
169 }\r
e314132f 170 }\r
4184aabd 171 }\r
4184aabd
MK
172 }\r
173\r
174 //\r
e314132f 175 // Record new GUID/HardwareInstance pair\r
4184aabd 176 //\r
e314132f
JE
177 CopyGuid (&HardwareInstances[*NumberOfDescriptors].ImageTypeGuid, &FmpImageInfoBuf->ImageTypeId);\r
178 HardwareInstances[*NumberOfDescriptors].HardwareInstance = FmpHardwareInstance;\r
1436aea4 179 *NumberOfDescriptors = *NumberOfDescriptors + 1;\r
e314132f
JE
180\r
181 DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Add new image descriptor with GUID %g HardwareInstance:0x%x\n", &FmpImageInfoBuf->ImageTypeId, FmpHardwareInstance));\r
182\r
183 //\r
184 // Check to see if GUID is already in the ESRT table\r
185 //\r
186 Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(Table + 1);\r
187 for (Index = 0; Index < Table->FwResourceCount; Index++, Entry++) {\r
188 if (!CompareGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId)) {\r
189 continue;\r
4184aabd 190 }\r
1436aea4 191\r
e314132f
JE
192 DEBUG ((DEBUG_INFO, "EsrtFmpDxe: ESRT Entry already exists for FMP Instance with GUID %g\n", &Entry->FwClass));\r
193\r
4184aabd 194 //\r
e314132f 195 // Set ESRT FwVersion to the smaller of the two values\r
4184aabd 196 //\r
e314132f
JE
197 Entry->FwVersion = MIN (FmpImageInfoBuf->Version, Entry->FwVersion);\r
198\r
4184aabd 199 //\r
e314132f 200 // VERSION 2 has Lowest Supported\r
4184aabd 201 //\r
e314132f
JE
202 if (FmpVersion >= 2) {\r
203 //\r
204 // Set ESRT LowestSupportedFwVersion to the smaller of the two values\r
205 //\r
206 Entry->LowestSupportedFwVersion =\r
207 MIN (\r
208 FmpImageInfoBuf->LowestSupportedImageVersion,\r
209 Entry->LowestSupportedFwVersion\r
210 );\r
211 }\r
212\r
4184aabd 213 //\r
e314132f 214 // VERSION 3 supports last attempt values\r
4184aabd 215 //\r
e314132f
JE
216 if (FmpVersion >= 3) {\r
217 //\r
218 // Update the ESRT entry with the last attempt status and last attempt\r
219 // version from the first FMP instance whose last attempt status is not\r
220 // SUCCESS. If all FMP instances are SUCCESS, then set version to the\r
221 // smallest value from all FMP instances.\r
222 //\r
223 if (Entry->LastAttemptStatus == LAST_ATTEMPT_STATUS_SUCCESS) {\r
224 if (FmpImageInfoBuf->LastAttemptStatus != LAST_ATTEMPT_STATUS_SUCCESS) {\r
1436aea4 225 Entry->LastAttemptStatus = FmpImageInfoBuf->LastAttemptStatus;\r
e314132f
JE
226 Entry->LastAttemptVersion = FmpImageInfoBuf->LastAttemptVersion;\r
227 } else {\r
228 Entry->LastAttemptVersion =\r
229 MIN (\r
230 FmpImageInfoBuf->LastAttemptVersion,\r
231 Entry->LastAttemptVersion\r
232 );\r
233 }\r
234 }\r
235 }\r
236\r
237 return EFI_SUCCESS;\r
4184aabd
MK
238 }\r
239\r
240 //\r
e314132f 241 // Add a new ESRT Table Entry\r
4184aabd 242 //\r
e314132f 243 Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(Table + 1) + Table->FwResourceCount;\r
4184aabd
MK
244\r
245 CopyGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId);\r
246\r
247 if (IsSystemFmp (FmpImageInfoBuf)) {\r
248 DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Found an ESRT entry for a System Device.\n"));\r
249 Entry->FwType = (UINT32)(ESRT_FW_TYPE_SYSTEMFIRMWARE);\r
250 } else {\r
251 Entry->FwType = (UINT32)(ESRT_FW_TYPE_DEVICEFIRMWARE);\r
252 }\r
253\r
e314132f 254 Entry->FwVersion = FmpImageInfoBuf->Version;\r
4184aabd 255 Entry->LowestSupportedFwVersion = 0;\r
e314132f
JE
256 Entry->CapsuleFlags = 0;\r
257 Entry->LastAttemptVersion = 0;\r
258 Entry->LastAttemptStatus = 0;\r
4184aabd
MK
259\r
260 //\r
261 // VERSION 2 has Lowest Supported\r
262 //\r
263 if (FmpVersion >= 2) {\r
264 Entry->LowestSupportedFwVersion = FmpImageInfoBuf->LowestSupportedImageVersion;\r
265 }\r
266\r
267 //\r
268 // VERSION 3 supports last attempt values\r
269 //\r
270 if (FmpVersion >= 3) {\r
271 Entry->LastAttemptVersion = FmpImageInfoBuf->LastAttemptVersion;\r
e314132f 272 Entry->LastAttemptStatus = FmpImageInfoBuf->LastAttemptStatus;\r
4184aabd
MK
273 }\r
274\r
e314132f
JE
275 //\r
276 // Increment the number of active ESRT Table Entries\r
277 //\r
278 Table->FwResourceCount++;\r
279\r
4184aabd
MK
280 return EFI_SUCCESS;\r
281}\r
282\r
e314132f
JE
283/**\r
284 Function to retrieve the EFI_FIRMWARE_IMAGE_DESCRIPTOR from an FMP Instance.\r
285 The returned buffer is allocated using AllocatePool() and must be freed by the\r
286 caller using FreePool().\r
287\r
288 @param[in] Fmp Pointer to an EFI_FIRMWARE_MANAGEMENT_PROTOCOL.\r
289 @param[out] FmpImageInfoDescriptorVer Pointer to the version number associated\r
290 with the returned EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
291 @param[out] FmpImageInfoCount Pointer to the number of the returned\r
292 EFI_FIRMWARE_IMAGE_DESCRIPTORs.\r
293 @param[out] DescriptorSize Pointer to the size, in bytes, of each\r
294 returned EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
295\r
296 @return Pointer to the retrieved EFI_FIRMWARE_IMAGE_DESCRIPTOR. If the\r
297 descriptor can not be retrieved, then NULL is returned.\r
298\r
299**/\r
300EFI_FIRMWARE_IMAGE_DESCRIPTOR *\r
301FmpGetFirmwareImageDescriptor (\r
302 IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp,\r
303 OUT UINT32 *FmpImageInfoDescriptorVer,\r
304 OUT UINT8 *FmpImageInfoCount,\r
305 OUT UINTN *DescriptorSize\r
306 )\r
307{\r
308 EFI_STATUS Status;\r
309 UINTN ImageInfoSize;\r
310 UINT32 PackageVersion;\r
311 CHAR16 *PackageVersionName;\r
312 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
313\r
314 ImageInfoSize = 0;\r
1436aea4
MK
315 Status = Fmp->GetImageInfo (\r
316 Fmp, // FMP Pointer\r
317 &ImageInfoSize, // Buffer Size (in this case 0)\r
318 NULL, // NULL so we can get size\r
319 FmpImageInfoDescriptorVer, // DescriptorVersion\r
320 FmpImageInfoCount, // DescriptorCount\r
321 DescriptorSize, // DescriptorSize\r
322 &PackageVersion, // PackageVersion\r
323 &PackageVersionName // PackageVersionName\r
324 );\r
e314132f
JE
325 if (Status != EFI_BUFFER_TOO_SMALL) {\r
326 DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Unexpected Failure in GetImageInfo. Status = %r\n", Status));\r
327 return NULL;\r
328 }\r
329\r
330 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
331 if (FmpImageInfoBuf == NULL) {\r
332 DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get memory for FMP descriptor.\n"));\r
333 return NULL;\r
334 }\r
335\r
336 PackageVersionName = NULL;\r
1436aea4
MK
337 Status = Fmp->GetImageInfo (\r
338 Fmp, // FMP Pointer\r
339 &ImageInfoSize, // ImageInfoSize\r
340 FmpImageInfoBuf, // ImageInfo\r
341 FmpImageInfoDescriptorVer, // DescriptorVersion\r
342 FmpImageInfoCount, // DescriptorCount\r
343 DescriptorSize, // DescriptorSize\r
344 &PackageVersion, // PackageVersion\r
345 &PackageVersionName // PackageVersionName\r
346 );\r
e314132f
JE
347 if (PackageVersionName != NULL) {\r
348 FreePool (PackageVersionName);\r
349 }\r
1436aea4 350\r
e314132f
JE
351 if (EFI_ERROR (Status)) {\r
352 DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failure in GetImageInfo. Status = %r\n", Status));\r
353 FreePool (FmpImageInfoBuf);\r
354 return NULL;\r
355 }\r
356\r
357 return FmpImageInfoBuf;\r
358}\r
359\r
4184aabd 360/**\r
6ec4d300
SZ
361 Function to create ESRT based on FMP Instances.\r
362 Create ESRT table, get the descriptors from FMP Instance and\r
363 create ESRT entries (ESRE).\r
4184aabd 364\r
6ec4d300 365 @return Pointer to the ESRT created.\r
4184aabd
MK
366\r
367**/\r
6ec4d300
SZ
368EFI_SYSTEM_RESOURCE_TABLE *\r
369CreateFmpBasedEsrt (\r
370 VOID\r
4184aabd
MK
371 )\r
372{\r
e314132f
JE
373 EFI_STATUS Status;\r
374 UINTN NoProtocols;\r
375 VOID **Buffer;\r
376 UINTN Index;\r
377 UINT32 FmpImageInfoDescriptorVer;\r
378 UINT8 FmpImageInfoCount;\r
379 UINTN DescriptorSize;\r
380 UINT32 NumberOfDescriptors;\r
381 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
382 EFI_FIRMWARE_IMAGE_DESCRIPTOR *OrgFmpImageInfoBuf;\r
383 EFI_SYSTEM_RESOURCE_TABLE *Table;\r
384 GUID_HARDWAREINSTANCE_PAIR *HardwareInstances;\r
4184aabd
MK
385\r
386 Status = EFI_SUCCESS;\r
6ec4d300
SZ
387 NoProtocols = 0;\r
388 Buffer = NULL;\r
4184aabd 389 FmpImageInfoBuf = NULL;\r
e314132f
JE
390 OrgFmpImageInfoBuf = NULL;\r
391 Table = NULL;\r
392 HardwareInstances = NULL;\r
4184aabd 393\r
6ec4d300
SZ
394 Status = EfiLocateProtocolBuffer (\r
395 &gEfiFirmwareManagementProtocolGuid,\r
396 &NoProtocols,\r
397 &Buffer\r
398 );\r
1436aea4 399 if (EFI_ERROR (Status) || (Buffer == NULL)) {\r
6ec4d300
SZ
400 return NULL;\r
401 }\r
4184aabd 402\r
6ec4d300 403 //\r
e314132f
JE
404 // Count the total number of EFI_FIRMWARE_IMAGE_DESCRIPTORs\r
405 //\r
406 for (Index = 0, NumberOfDescriptors = 0; Index < NoProtocols; Index++) {\r
407 FmpImageInfoBuf = FmpGetFirmwareImageDescriptor (\r
1436aea4 408 (EFI_FIRMWARE_MANAGEMENT_PROTOCOL *)Buffer[Index],\r
e314132f
JE
409 &FmpImageInfoDescriptorVer,\r
410 &FmpImageInfoCount,\r
411 &DescriptorSize\r
412 );\r
413 if (FmpImageInfoBuf != NULL) {\r
414 NumberOfDescriptors += FmpImageInfoCount;\r
415 FreePool (FmpImageInfoBuf);\r
416 }\r
417 }\r
418\r
419 //\r
420 // Allocate ESRT Table and GUID/HardwareInstance table\r
6ec4d300
SZ
421 //\r
422 Table = AllocateZeroPool (\r
1436aea4
MK
423 (NumberOfDescriptors * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
424 );\r
6ec4d300
SZ
425 if (Table == NULL) {\r
426 DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for ESRT.\n"));\r
e314132f 427 FreePool (Buffer);\r
6ec4d300
SZ
428 return NULL;\r
429 }\r
430\r
e314132f
JE
431 HardwareInstances = AllocateZeroPool (NumberOfDescriptors * sizeof (GUID_HARDWAREINSTANCE_PAIR));\r
432 if (HardwareInstances == NULL) {\r
433 DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for HW Instance Table.\n"));\r
434 FreePool (Table);\r
435 FreePool (Buffer);\r
436 return NULL;\r
437 }\r
438\r
439 //\r
440 // Initialize ESRT Table\r
441 //\r
6ec4d300 442 Table->FwResourceCount = 0;\r
e314132f 443 Table->FwResourceCountMax = NumberOfDescriptors;\r
4a76d9b9 444 Table->FwResourceVersion = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;\r
4184aabd 445\r
e314132f 446 NumberOfDescriptors = 0;\r
6ec4d300 447 for (Index = 0; Index < NoProtocols; Index++) {\r
e314132f 448 FmpImageInfoBuf = FmpGetFirmwareImageDescriptor (\r
1436aea4 449 (EFI_FIRMWARE_MANAGEMENT_PROTOCOL *)Buffer[Index],\r
e314132f
JE
450 &FmpImageInfoDescriptorVer,\r
451 &FmpImageInfoCount,\r
452 &DescriptorSize\r
453 );\r
4184aabd 454 if (FmpImageInfoBuf == NULL) {\r
6ec4d300 455 continue;\r
4184aabd
MK
456 }\r
457\r
458 //\r
459 // Check each descriptor and read from the one specified\r
460 //\r
e314132f 461 OrgFmpImageInfoBuf = FmpImageInfoBuf;\r
4184aabd
MK
462 while (FmpImageInfoCount > 0) {\r
463 //\r
464 // If the descriptor has the IN USE bit set, create ESRT entry otherwise ignore.\r
465 //\r
466 if ((FmpImageInfoBuf->AttributesSetting & FmpImageInfoBuf->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE) == IMAGE_ATTRIBUTE_IN_USE) {\r
467 //\r
468 // Create ESRT entry\r
469 //\r
e314132f 470 CreateEsrtEntry (Table, HardwareInstances, &NumberOfDescriptors, FmpImageInfoBuf, FmpImageInfoDescriptorVer);\r
4184aabd 471 }\r
1436aea4 472\r
4184aabd
MK
473 FmpImageInfoCount--;\r
474 //\r
475 // Increment the buffer pointer ahead by the size of the descriptor\r
476 //\r
477 FmpImageInfoBuf = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)(((UINT8 *)FmpImageInfoBuf) + DescriptorSize);\r
478 }\r
479\r
e314132f
JE
480 FreePool (OrgFmpImageInfoBuf);\r
481 OrgFmpImageInfoBuf = NULL;\r
4184aabd 482 }\r
6ec4d300 483\r
e314132f
JE
484 FreePool (Buffer);\r
485 FreePool (HardwareInstances);\r
6ec4d300 486 return Table;\r
4184aabd
MK
487}\r
488\r
489/**\r
490 Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to\r
491 install the Efi System Resource Table.\r
492\r
493 @param[in] Event The Event that is being processed.\r
494 @param[in] Context The Event Context.\r
495\r
496**/\r
497VOID\r
498EFIAPI\r
499EsrtReadyToBootEventNotify (\r
500 IN EFI_EVENT Event,\r
501 IN VOID *Context\r
502 )\r
503{\r
6ec4d300
SZ
504 EFI_STATUS Status;\r
505 EFI_SYSTEM_RESOURCE_TABLE *Table;\r
506\r
507 Table = CreateFmpBasedEsrt ();\r
508 if (Table != NULL) {\r
509 //\r
510 // Print table on debug builds\r
511 //\r
512 DEBUG_CODE_BEGIN ();\r
513 PrintTable (Table);\r
514 DEBUG_CODE_END ();\r
515\r
516 Status = InstallEfiSystemResourceTableInUefiConfigurationTable (Table);\r
517 if (EFI_ERROR (Status)) {\r
518 FreePool (Table);\r
519 }\r
520 } else {\r
521 DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it is NULL. \n"));\r
522 }\r
4184aabd
MK
523\r
524 //\r
6ec4d300 525 // Close the event to prevent it be signalled again.\r
4184aabd 526 //\r
6ec4d300 527 gBS->CloseEvent (Event);\r
4184aabd
MK
528}\r
529\r
530/**\r
531 The module Entry Point of the Efi System Resource Table DXE driver.\r
532\r
533 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
534 @param[in] SystemTable A pointer to the EFI System Table.\r
535\r
536 @retval EFI_SUCCESS The entry point is executed successfully.\r
537 @retval Other Some error occurs when executing this entry point.\r
538\r
539**/\r
540EFI_STATUS\r
541EFIAPI\r
542EsrtFmpEntryPoint (\r
543 IN EFI_HANDLE ImageHandle,\r
544 IN EFI_SYSTEM_TABLE *SystemTable\r
545 )\r
546{\r
547 EFI_STATUS Status;\r
6ec4d300 548 EFI_EVENT EsrtReadyToBootEvent;\r
4184aabd
MK
549\r
550 //\r
551 // Register notify function to install ESRT on ReadyToBoot Event.\r
552 //\r
553 Status = EfiCreateEventReadyToBootEx (\r
554 TPL_CALLBACK,\r
555 EsrtReadyToBootEventNotify,\r
556 NULL,\r
6ec4d300 557 &EsrtReadyToBootEvent\r
4184aabd
MK
558 );\r
559\r
560 ASSERT_EFI_ERROR (Status);\r
561 if (EFI_ERROR (Status)) {\r
562 DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to register for ready to boot\n"));\r
563 }\r
564\r
565 return Status;\r
566}\r