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