]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Application/CapsuleApp/CapsuleDump.c
MdeModulePkg CapsuleApp: ASSERT to ensure 'CapsuleIndex' is not NULL
[mirror_edk2.git] / MdeModulePkg / Application / CapsuleApp / CapsuleDump.c
1 /** @file
2 Dump Capsule image information.
3
4 Copyright (c) 2016, 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
15 #include <PiDxe.h>
16 #include <Library/BaseLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/UefiBootServicesTableLib.h>
21 #include <Library/UefiRuntimeServicesTableLib.h>
22 #include <Library/UefiLib.h>
23 #include <Library/PrintLib.h>
24 #include <Protocol/FirmwareManagement.h>
25 #include <Guid/ImageAuthentication.h>
26 #include <Guid/CapsuleReport.h>
27 #include <Guid/SystemResourceTable.h>
28 #include <Guid/FmpCapsule.h>
29 #include <IndustryStandard/WindowsUxCapsule.h>
30
31 /**
32 Read a file.
33
34 @param[in] FileName The file to be read.
35 @param[in] BufferSize The file buffer size
36 @param[in] Buffer The file buffer
37
38 @retval EFI_SUCCESS Read file successfully
39 @retval EFI_NOT_FOUND File not found
40 **/
41 EFI_STATUS
42 ReadFileToBuffer (
43 IN CHAR16 *FileName,
44 OUT UINTN *BufferSize,
45 OUT VOID **Buffer
46 );
47
48 /**
49 Dump UX capsule information.
50
51 @param[in] CapsuleHeader The UX capsule header
52 **/
53 VOID
54 DumpUxCapsule (
55 IN EFI_CAPSULE_HEADER *CapsuleHeader
56 )
57 {
58 EFI_DISPLAY_CAPSULE *DisplayCapsule;
59 DisplayCapsule = (EFI_DISPLAY_CAPSULE *)CapsuleHeader;
60 Print(L"[UxCapusule]\n");
61 Print(L"CapsuleHeader:\n");
62 Print(L" CapsuleGuid - %g\n", &DisplayCapsule->CapsuleHeader.CapsuleGuid);
63 Print(L" HeaderSize - 0x%x\n", DisplayCapsule->CapsuleHeader.HeaderSize);
64 Print(L" Flags - 0x%x\n", DisplayCapsule->CapsuleHeader.Flags);
65 Print(L" CapsuleImageSize - 0x%x\n", DisplayCapsule->CapsuleHeader.CapsuleImageSize);
66 Print(L"ImagePayload:\n");
67 Print(L" Version - 0x%x\n", DisplayCapsule->ImagePayload.Version);
68 Print(L" Checksum - 0x%x\n", DisplayCapsule->ImagePayload.Checksum);
69 Print(L" ImageType - 0x%x\n", DisplayCapsule->ImagePayload.ImageType);
70 Print(L" Mode - 0x%x\n", DisplayCapsule->ImagePayload.Mode);
71 Print(L" OffsetX - 0x%x\n", DisplayCapsule->ImagePayload.OffsetX);
72 Print(L" OffsetY - 0x%x\n", DisplayCapsule->ImagePayload.OffsetY);
73 }
74
75 /**
76 Dump FMP image authentication information.
77
78 @param[in] Image The FMP capsule image
79 @param[in] ImageSize The size of the FMP capsule image in bytes.
80
81 @return the size of FMP authentication.
82 **/
83 UINTN
84 DumpImageAuthentication (
85 IN VOID *Image,
86 IN UINTN ImageSize
87 )
88 {
89 EFI_FIRMWARE_IMAGE_AUTHENTICATION *ImageAuthentication;
90
91 ImageAuthentication = Image;
92 if (CompareGuid(&ImageAuthentication->AuthInfo.CertType, &gEfiCertPkcs7Guid) ||
93 CompareGuid(&ImageAuthentication->AuthInfo.CertType, &gEfiCertTypeRsa2048Sha256Guid)) {
94 Print(L"[ImageAuthentication]\n");
95 Print(L" MonotonicCount - 0x%lx\n", ImageAuthentication->MonotonicCount);
96 Print(L"WIN_CERTIFICATE:\n");
97 Print(L" dwLength - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.dwLength);
98 Print(L" wRevision - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.wRevision);
99 Print(L" wCertificateType - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.wCertificateType);
100 Print(L" CertType - %g\n", &ImageAuthentication->AuthInfo.CertType);
101 return sizeof(ImageAuthentication->MonotonicCount) + ImageAuthentication->AuthInfo.Hdr.dwLength;
102 } else {
103 return 0;
104 }
105 }
106
107 /**
108 Dump a non-nested FMP capsule.
109
110 @param[in] CapsuleHeader A pointer to CapsuleHeader
111 **/
112 VOID
113 DumpFmpCapsule (
114 IN EFI_CAPSULE_HEADER *CapsuleHeader
115 )
116 {
117 EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *FmpCapsuleHeader;
118 UINT64 *ItemOffsetList;
119 UINTN Index;
120 UINTN Count;
121 EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *FmpImageHeader;
122
123 Print(L"[FmpCapusule]\n");
124 Print(L"CapsuleHeader:\n");
125 Print(L" CapsuleGuid - %g\n", &CapsuleHeader->CapsuleGuid);
126 Print(L" HeaderSize - 0x%x\n", CapsuleHeader->HeaderSize);
127 Print(L" Flags - 0x%x\n", CapsuleHeader->Flags);
128 Print(L" CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);
129
130 FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
131 ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);
132 Print(L"FmpHeader:\n");
133 Print(L" Version - 0x%x\n", FmpCapsuleHeader->Version);
134 Print(L" EmbeddedDriverCount - 0x%x\n", FmpCapsuleHeader->EmbeddedDriverCount);
135 Print(L" PayloadItemCount - 0x%x\n", FmpCapsuleHeader->PayloadItemCount);
136 Count = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;
137 for (Index = 0; Index < Count; Index++) {
138 Print(L" Offset[%d] - 0x%x\n", Index, ItemOffsetList[Index]);
139 }
140
141 for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < Count; Index++) {
142 Print(L"FmpPayload[%d] ImageHeader:\n", Index);
143 FmpImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);
144 Print(L" Version - 0x%x\n", FmpImageHeader->Version);
145 Print(L" UpdateImageTypeId - %g\n", &FmpImageHeader->UpdateImageTypeId);
146 Print(L" UpdateImageIndex - 0x%x\n", FmpImageHeader->UpdateImageIndex);
147 Print(L" UpdateImageSize - 0x%x\n", FmpImageHeader->UpdateImageSize);
148 Print(L" UpdateVendorCodeSize - 0x%x\n", FmpImageHeader->UpdateVendorCodeSize);
149 if (FmpImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {
150 Print(L" UpdateHardwareInstance - 0x%lx\n", FmpImageHeader->UpdateHardwareInstance);
151 }
152 }
153 }
154
155 /**
156 Return if there is a FMP header below capsule header.
157
158 @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER
159
160 @retval TRUE There is a FMP header below capsule header.
161 @retval FALSE There is not a FMP header below capsule header
162 **/
163 BOOLEAN
164 IsNestedFmpCapsule (
165 IN EFI_CAPSULE_HEADER *CapsuleHeader
166 )
167 {
168 EFI_STATUS Status;
169 EFI_SYSTEM_RESOURCE_TABLE *Esrt;
170 EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;
171 UINTN Index;
172 BOOLEAN EsrtGuidFound;
173 EFI_CAPSULE_HEADER *NestedCapsuleHeader;
174 UINTN NestedCapsuleSize;
175
176 //
177 // Check ESRT
178 //
179 EsrtGuidFound = FALSE;
180 Status = EfiGetSystemConfigurationTable(&gEfiSystemResourceTableGuid, (VOID **)&Esrt);
181 if (!EFI_ERROR(Status)) {
182 ASSERT (Esrt != NULL);
183 EsrtEntry = (VOID *)(Esrt + 1);
184 for (Index = 0; Index < Esrt->FwResourceCount; Index++, EsrtEntry++) {
185 if (CompareGuid(&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {
186 EsrtGuidFound = TRUE;
187 break;
188 }
189 }
190 }
191
192 if (!EsrtGuidFound) {
193 return FALSE;
194 }
195
196 //
197 // Check nested capsule header
198 // FMP GUID after ESRT one
199 //
200 NestedCapsuleHeader = (EFI_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);
201 NestedCapsuleSize = (UINTN)CapsuleHeader + CapsuleHeader->HeaderSize - (UINTN)NestedCapsuleHeader;
202 if (NestedCapsuleSize < sizeof(EFI_CAPSULE_HEADER)) {
203 return FALSE;
204 }
205 if (!CompareGuid(&NestedCapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {
206 return FALSE;
207 }
208 return TRUE;
209 }
210
211 /**
212 Dump capsule information
213
214 @param[in] CapsuleName The name of the capsule image.
215
216 @retval EFI_SUCCESS The capsule information is dumped.
217 @retval EFI_UNSUPPORTED Input parameter is not valid.
218 **/
219 EFI_STATUS
220 DumpCapsule (
221 IN CHAR16 *CapsuleName
222 )
223 {
224 VOID *Buffer;
225 UINTN FileSize;
226 EFI_CAPSULE_HEADER *CapsuleHeader;
227 EFI_STATUS Status;
228
229 Status = ReadFileToBuffer(CapsuleName, &FileSize, &Buffer);
230 if (EFI_ERROR(Status)) {
231 Print(L"CapsuleApp: Capsule (%s) is not found.\n", CapsuleName);
232 goto Done;
233 }
234
235 CapsuleHeader = Buffer;
236 if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {
237 DumpUxCapsule(CapsuleHeader);
238 Status = EFI_SUCCESS;
239 goto Done;
240 }
241
242 if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {
243 DumpFmpCapsule(CapsuleHeader);
244 }
245 if (IsNestedFmpCapsule(CapsuleHeader)) {
246 Print(L"[NestedCapusule]\n");
247 Print(L"CapsuleHeader:\n");
248 Print(L" CapsuleGuid - %g\n", &CapsuleHeader->CapsuleGuid);
249 Print(L" HeaderSize - 0x%x\n", CapsuleHeader->HeaderSize);
250 Print(L" Flags - 0x%x\n", CapsuleHeader->Flags);
251 Print(L" CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);
252 DumpFmpCapsule((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize));
253 }
254
255 Done:
256 FreePool(Buffer);
257 return Status;
258 }
259
260 /**
261 Dump capsule status variable.
262
263 @retval EFI_SUCCESS The capsule status variable is dumped.
264 @retval EFI_UNSUPPORTED Input parameter is not valid.
265 **/
266 EFI_STATUS
267 DmpCapsuleStatusVariable (
268 VOID
269 )
270 {
271 EFI_STATUS Status;
272 UINT32 Index;
273 CHAR16 CapsuleVarName[20];
274 CHAR16 *TempVarName;
275 EFI_CAPSULE_RESULT_VARIABLE_HEADER *CapsuleResult;
276 EFI_CAPSULE_RESULT_VARIABLE_FMP *CapsuleResultFmp;
277 UINTN CapsuleFileNameSize;
278 CHAR16 CapsuleIndexData[12];
279 CHAR16 *CapsuleIndex;
280
281 Status = GetVariable2(
282 L"CapsuleMax",
283 &gEfiCapsuleReportGuid,
284 (VOID **)&CapsuleIndex,
285 NULL
286 );
287 if (!EFI_ERROR(Status)) {
288 ASSERT (CapsuleIndex != NULL);
289 CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));
290 CapsuleIndexData[11] = 0;
291 Print(L"CapsuleMax - %s\n", CapsuleIndexData);
292 FreePool(CapsuleIndex);
293 }
294 Status = GetVariable2(
295 L"CapsuleLast",
296 &gEfiCapsuleReportGuid,
297 (VOID **)&CapsuleIndex,
298 NULL
299 );
300 if (!EFI_ERROR(Status)) {
301 ASSERT (CapsuleIndex != NULL);
302 CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));
303 CapsuleIndexData[11] = 0;
304 Print(L"CapsuleLast - %s\n", CapsuleIndexData);
305 FreePool(CapsuleIndex);
306 }
307
308
309 StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CapsuleVarName[0]), L"Capsule");
310 TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
311 Index = 0;
312
313 while (TRUE) {
314 UnicodeSPrint (TempVarName, 5 * sizeof(CHAR16), L"%04x", Index);
315
316 Status = GetVariable2 (
317 CapsuleVarName,
318 &gEfiCapsuleReportGuid,
319 (VOID **) &CapsuleResult,
320 NULL
321 );
322 if (Status == EFI_NOT_FOUND) {
323 break;
324 } else if (EFI_ERROR(Status)) {
325 continue;
326 }
327 ASSERT (CapsuleResult != NULL);
328
329 //
330 // display capsule process status
331 //
332 if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER)) {
333 Print (L"CapsuleName: %s\n", CapsuleVarName);
334 Print (L" Capsule Guid: %g\n", &CapsuleResult->CapsuleGuid);
335 Print (L" Capsule ProcessedTime: %t\n", &CapsuleResult->CapsuleProcessed);
336 Print (L" Capsule Status: %r\n", CapsuleResult->CapsuleStatus);
337 }
338
339 if (CompareGuid(&CapsuleResult->CapsuleGuid, &gEfiFmpCapsuleGuid)) {
340 if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) {
341 CapsuleResultFmp = (EFI_CAPSULE_RESULT_VARIABLE_FMP *)(CapsuleResult + 1);
342 Print(L" Capsule FMP Version: 0x%x\n", CapsuleResultFmp->Version);
343 Print(L" Capsule FMP PayloadIndex: 0x%x\n", CapsuleResultFmp->PayloadIndex);
344 Print(L" Capsule FMP UpdateImageIndex: 0x%x\n", CapsuleResultFmp->UpdateImageIndex);
345 Print(L" Capsule FMP UpdateImageTypeId: %g\n", &CapsuleResultFmp->UpdateImageTypeId);
346 if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) {
347 Print(L" Capsule FMP CapsuleFileName: %s\n", (CapsuleResultFmp + 1));
348 CapsuleFileNameSize = StrSize((CHAR16 *)(CapsuleResultFmp + 1));
349 if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + CapsuleFileNameSize) {
350 Print(L" Capsule FMP CapsuleTarget: %s\n", (UINT8 *)(CapsuleResultFmp + 1) + CapsuleFileNameSize);
351 }
352 }
353 }
354 }
355
356 FreePool(CapsuleResult);
357
358 Index++;
359 if (Index > 0xFFFF) {
360 break;
361 }
362 }
363
364 return EFI_SUCCESS;
365 }
366
367 CHAR8 *mFwTypeString[] = {
368 "Unknown",
369 "SystemFirmware",
370 "DeviceFirmware",
371 "UefiDriver",
372 };
373
374 CHAR8 *mLastAttemptStatusString[] = {
375 "Success",
376 "Error: Unsuccessful",
377 "Error: Insufficient Resources",
378 "Error: Incorrect Version",
379 "Error: Invalid Format",
380 "Error: Auth Error",
381 "Error: Power Event AC",
382 "Error: Power Event Battery",
383 };
384
385 /**
386 Convert FwType to a string.
387
388 @param[in] FwType FwType in ESRT
389
390 @return a string for FwType.
391 **/
392 CHAR8 *
393 FwTypeToString (
394 IN UINT32 FwType
395 )
396 {
397 if (FwType < sizeof(mFwTypeString) / sizeof(mFwTypeString[0])) {
398 return mFwTypeString[FwType];
399 } else {
400 return "Invalid";
401 }
402 }
403
404 /**
405 Convert LastAttemptStatus to a string.
406
407 @param[in] LastAttemptStatus LastAttemptStatus in FMP or ESRT
408
409 @return a string for LastAttemptStatus.
410 **/
411 CHAR8 *
412 LastAttemptStatusToString (
413 IN UINT32 LastAttemptStatus
414 )
415 {
416 if (LastAttemptStatus < sizeof(mLastAttemptStatusString) / sizeof(mLastAttemptStatusString[0])) {
417 return mLastAttemptStatusString[LastAttemptStatus];
418 } else {
419 return "Error: Unknown";
420 }
421 }
422
423 /**
424 Dump ESRT entry.
425
426 @param[in] EsrtEntry ESRT entry
427 **/
428 VOID
429 DumpEsrtEntry (
430 IN EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry
431 )
432 {
433 Print(L" FwClass - %g\n", &EsrtEntry->FwClass);
434 Print(L" FwType - 0x%x (%a)\n", EsrtEntry->FwType, FwTypeToString(EsrtEntry->FwType));
435 Print(L" FwVersion - 0x%x\n", EsrtEntry->FwVersion);
436 Print(L" LowestSupportedFwVersion - 0x%x\n", EsrtEntry->LowestSupportedFwVersion);
437 Print(L" CapsuleFlags - 0x%x\n", EsrtEntry->CapsuleFlags);
438 Print(L" PERSIST_ACROSS_RESET - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET);
439 Print(L" POPULATE_SYSTEM_TABLE - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE);
440 Print(L" INITIATE_RESET - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_INITIATE_RESET);
441 Print(L" LastAttemptVersion - 0x%x\n", EsrtEntry->LastAttemptVersion);
442 Print(L" LastAttemptStatus - 0x%x (%a)\n", EsrtEntry->LastAttemptStatus, LastAttemptStatusToString(EsrtEntry->LastAttemptStatus));
443 }
444
445 /**
446 Dump ESRT table.
447
448 @param[in] Esrt ESRT table
449 **/
450 VOID
451 DumpEsrt (
452 IN EFI_SYSTEM_RESOURCE_TABLE *Esrt
453 )
454 {
455 UINTN Index;
456 EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;
457
458 if (Esrt == NULL) {
459 return ;
460 }
461
462 Print(L"EFI_SYSTEM_RESOURCE_TABLE:\n");
463 Print(L"FwResourceCount - 0x%x\n", Esrt->FwResourceCount);
464 Print(L"FwResourceCountMax - 0x%x\n", Esrt->FwResourceCountMax);
465 Print(L"FwResourceVersion - 0x%lx\n", Esrt->FwResourceVersion);
466
467 EsrtEntry = (VOID *)(Esrt + 1);
468 for (Index = 0; Index < Esrt->FwResourceCount; Index++) {
469 Print(L"EFI_SYSTEM_RESOURCE_ENTRY (%d):\n", Index);
470 DumpEsrtEntry(EsrtEntry);
471 EsrtEntry++;
472 }
473 }
474
475 /**
476 Dump ESRT info.
477 **/
478 VOID
479 DumpEsrtData (
480 VOID
481 )
482 {
483 EFI_STATUS Status;
484 EFI_SYSTEM_RESOURCE_TABLE *Esrt;
485
486 Print(L"##############\n");
487 Print(L"# ESRT TABLE #\n");
488 Print(L"##############\n");
489
490 Status = EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid, (VOID **)&Esrt);
491 if (EFI_ERROR(Status)) {
492 Print(L"ESRT - %r\n", Status);
493 return;
494 }
495 DumpEsrt(Esrt);
496 Print(L"\n");
497 }
498
499 /**
500 Dump FMP information.
501
502 @param[in] ImageInfoSize The size of ImageInfo, in bytes.
503 @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.
504 @param[in] DescriptorVersion The version of EFI_FIRMWARE_IMAGE_DESCRIPTOR.
505 @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.
506 @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.
507 @param[in] PackageVersion The version of package.
508 @param[in] PackageVersionName The version name of package.
509 **/
510 VOID
511 DumpFmpImageInfo (
512 IN UINTN ImageInfoSize,
513 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,
514 IN UINT32 DescriptorVersion,
515 IN UINT8 DescriptorCount,
516 IN UINTN DescriptorSize,
517 IN UINT32 PackageVersion,
518 IN CHAR16 *PackageVersionName
519 )
520 {
521 EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo;
522 UINTN Index;
523
524 Print(L" DescriptorVersion - 0x%x\n", DescriptorVersion);
525 Print(L" DescriptorCount - 0x%x\n", DescriptorCount);
526 Print(L" DescriptorSize - 0x%x\n", DescriptorSize);
527 Print(L" PackageVersion - 0x%x\n", PackageVersion);
528 Print(L" PackageVersionName - \"%s\"\n", PackageVersionName);
529 CurrentImageInfo = ImageInfo;
530 for (Index = 0; Index < DescriptorCount; Index++) {
531 Print(L" ImageDescriptor (%d)\n", Index);
532 Print(L" ImageIndex - 0x%x\n", CurrentImageInfo->ImageIndex);
533 Print(L" ImageTypeId - %g\n", &CurrentImageInfo->ImageTypeId);
534 Print(L" ImageId - 0x%lx\n", CurrentImageInfo->ImageId);
535 Print(L" ImageIdName - \"%s\"\n", CurrentImageInfo->ImageIdName);
536 Print(L" Version - 0x%x\n", CurrentImageInfo->Version);
537 Print(L" VersionName - \"%s\"\n", CurrentImageInfo->VersionName);
538 Print(L" Size - 0x%x\n", CurrentImageInfo->Size);
539 Print(L" AttributesSupported - 0x%lx\n", CurrentImageInfo->AttributesSupported);
540 Print(L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
541 Print(L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);
542 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
543 Print(L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE);
544 Print(L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_UEFI_IMAGE);
545 Print(L" AttributesSetting - 0x%lx\n", CurrentImageInfo->AttributesSetting);
546 Print(L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
547 Print(L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);
548 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
549 Print(L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IN_USE);
550 Print(L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_UEFI_IMAGE);
551 Print(L" Compatibilities - 0x%lx\n", CurrentImageInfo->Compatibilities);
552 Print(L" COMPATIB_CHECK_SUPPORTED - 0x%lx\n", CurrentImageInfo->Compatibilities & IMAGE_COMPATIBILITY_CHECK_SUPPORTED);
553 if (DescriptorVersion > 1) {
554 Print(L" LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion);
555 if (DescriptorVersion > 2) {
556 Print(L" LastAttemptVersion - 0x%x\n", CurrentImageInfo->LastAttemptVersion);
557 Print(L" LastAttemptStatus - 0x%x (%a)\n", CurrentImageInfo->LastAttemptStatus, LastAttemptStatusToString(CurrentImageInfo->LastAttemptStatus));
558 Print(L" HardwareInstance - 0x%lx\n", CurrentImageInfo->HardwareInstance);
559 }
560 }
561 //
562 // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version
563 //
564 CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);
565 }
566 }
567
568 /**
569 Dump FMP package information.
570
571 @param[in] PackageVersion The version of package.
572 @param[in] PackageVersionName The version name of package.
573 @param[in] PackageVersionNameMaxLen The maximum length of PackageVersionName.
574 @param[in] AttributesSupported Package attributes that are supported by this device.
575 @param[in] AttributesSetting Package attributes.
576 **/
577 VOID
578 DumpFmpPackageInfo (
579 IN UINT32 PackageVersion,
580 IN CHAR16 *PackageVersionName,
581 IN UINT32 PackageVersionNameMaxLen,
582 IN UINT64 AttributesSupported,
583 IN UINT64 AttributesSetting
584 )
585 {
586 Print(L" PackageVersion - 0x%x\n", PackageVersion);
587 Print(L" PackageVersionName - \"%s\"\n", PackageVersionName);
588 Print(L" PackageVersionNameMaxLen - 0x%x\n", PackageVersionNameMaxLen);
589 Print(L" AttributesSupported - 0x%lx\n", AttributesSupported);
590 Print(L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
591 Print(L" RESET_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);
592 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
593 Print(L" AttributesSetting - 0x%lx\n", AttributesSetting);
594 Print(L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
595 Print(L" RESET_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);
596 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
597 }
598
599 /**
600 Dump FMP protocol info.
601 **/
602 VOID
603 DumpFmpData (
604 VOID
605 )
606 {
607 EFI_STATUS Status;
608 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
609 EFI_HANDLE *HandleBuffer;
610 UINTN NumberOfHandles;
611 UINTN Index;
612 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
613 UINTN ImageInfoSize;
614 UINT32 FmpImageInfoDescriptorVer;
615 UINT8 FmpImageInfoCount;
616 UINTN DescriptorSize;
617 UINT32 PackageVersion;
618 CHAR16 *PackageVersionName;
619 UINT32 PackageVersionNameMaxLen;
620 UINT64 AttributesSupported;
621 UINT64 AttributesSetting;
622
623 Print(L"############\n");
624 Print(L"# FMP DATA #\n");
625 Print(L"############\n");
626 Status = gBS->LocateHandleBuffer (
627 ByProtocol,
628 &gEfiFirmwareManagementProtocolGuid,
629 NULL,
630 &NumberOfHandles,
631 &HandleBuffer
632 );
633 if (EFI_ERROR(Status)) {
634 Print(L"FMP protocol - %r\n", EFI_NOT_FOUND);
635 return;
636 }
637
638 for (Index = 0; Index < NumberOfHandles; Index++) {
639 Status = gBS->HandleProtocol(
640 HandleBuffer[Index],
641 &gEfiFirmwareManagementProtocolGuid,
642 (VOID **)&Fmp
643 );
644 if (EFI_ERROR(Status)) {
645 continue;
646 }
647
648 ImageInfoSize = 0;
649 Status = Fmp->GetImageInfo (
650 Fmp,
651 &ImageInfoSize,
652 NULL,
653 NULL,
654 NULL,
655 NULL,
656 NULL,
657 NULL
658 );
659 if (Status != EFI_BUFFER_TOO_SMALL) {
660 continue;
661 }
662
663 FmpImageInfoBuf = NULL;
664 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
665 if (FmpImageInfoBuf == NULL) {
666 Status = EFI_OUT_OF_RESOURCES;
667 goto EXIT;
668 }
669
670 PackageVersionName = NULL;
671 Status = Fmp->GetImageInfo (
672 Fmp,
673 &ImageInfoSize, // ImageInfoSize
674 FmpImageInfoBuf, // ImageInfo
675 &FmpImageInfoDescriptorVer, // DescriptorVersion
676 &FmpImageInfoCount, // DescriptorCount
677 &DescriptorSize, // DescriptorSize
678 &PackageVersion, // PackageVersion
679 &PackageVersionName // PackageVersionName
680 );
681
682 //
683 // If FMP GetInformation interface failed, skip this resource
684 //
685 if (EFI_ERROR(Status)) {
686 Print(L"FMP (%d) ImageInfo - %r\n", Index, Status);
687 FreePool(FmpImageInfoBuf);
688 continue;
689 }
690
691 Print(L"FMP (%d) ImageInfo:\n", Index);
692 DumpFmpImageInfo(
693 ImageInfoSize, // ImageInfoSize
694 FmpImageInfoBuf, // ImageInfo
695 FmpImageInfoDescriptorVer, // DescriptorVersion
696 FmpImageInfoCount, // DescriptorCount
697 DescriptorSize, // DescriptorSize
698 PackageVersion, // PackageVersion
699 PackageVersionName // PackageVersionName
700 );
701
702 if (PackageVersionName != NULL) {
703 FreePool(PackageVersionName);
704 }
705 FreePool(FmpImageInfoBuf);
706
707 //
708 // Get package info
709 //
710 PackageVersionName = NULL;
711 Status = Fmp->GetPackageInfo (
712 Fmp,
713 &PackageVersion, // PackageVersion
714 &PackageVersionName, // PackageVersionName
715 &PackageVersionNameMaxLen, // PackageVersionNameMaxLen
716 &AttributesSupported, // AttributesSupported
717 &AttributesSetting // AttributesSetting
718 );
719 if (EFI_ERROR(Status)) {
720 Print(L"FMP (%d) PackageInfo - %r\n", Index, Status);
721 } else {
722 Print(L"FMP (%d) ImageInfo:\n", Index);
723 DumpFmpPackageInfo(
724 PackageVersion, // PackageVersion
725 PackageVersionName, // PackageVersionName
726 PackageVersionNameMaxLen, // PackageVersionNameMaxLen
727 AttributesSupported, // AttributesSupported
728 AttributesSetting // AttributesSetting
729 );
730
731 if (PackageVersionName != NULL) {
732 FreePool(PackageVersionName);
733 }
734 }
735 }
736 Print(L"\n");
737
738 EXIT:
739 FreePool(HandleBuffer);
740 }