MdeModulePkg/CapsuleApp: Add CapsuleApp application.
[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 CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));
289 CapsuleIndexData[11] = 0;
290 Print(L"CapsuleMax - %s\n", CapsuleIndexData);
291 FreePool(CapsuleIndex);
292 }
293 Status = GetVariable2(
294 L"CapsuleLast",
295 &gEfiCapsuleReportGuid,
296 (VOID **)&CapsuleIndex,
297 NULL
298 );
299 if (!EFI_ERROR(Status)) {
300 CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));
301 CapsuleIndexData[11] = 0;
302 Print(L"CapsuleLast - %s\n", CapsuleIndexData);
303 FreePool(CapsuleIndex);
304 }
305
306
307 StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CapsuleVarName[0]), L"Capsule");
308 TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
309 Index = 0;
310
311 while (TRUE) {
312 UnicodeSPrint (TempVarName, 5 * sizeof(CHAR16), L"%04x", Index);
313
314 Status = GetVariable2 (
315 CapsuleVarName,
316 &gEfiCapsuleReportGuid,
317 (VOID **) &CapsuleResult,
318 NULL
319 );
320 if (Status == EFI_NOT_FOUND) {
321 break;
322 } else if (EFI_ERROR(Status)) {
323 continue;
324 }
325 ASSERT (CapsuleResult != NULL);
326
327 //
328 // display capsule process status
329 //
330 if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER)) {
331 Print (L"CapsuleName: %s\n", CapsuleVarName);
332 Print (L" Capsule Guid: %g\n", &CapsuleResult->CapsuleGuid);
333 Print (L" Capsule ProcessedTime: %t\n", &CapsuleResult->CapsuleProcessed);
334 Print (L" Capsule Status: %r\n", CapsuleResult->CapsuleStatus);
335 }
336
337 if (CompareGuid(&CapsuleResult->CapsuleGuid, &gEfiFmpCapsuleGuid)) {
338 if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) {
339 CapsuleResultFmp = (EFI_CAPSULE_RESULT_VARIABLE_FMP *)(CapsuleResult + 1);
340 Print(L" Capsule FMP Version: 0x%x\n", CapsuleResultFmp->Version);
341 Print(L" Capsule FMP PayloadIndex: 0x%x\n", CapsuleResultFmp->PayloadIndex);
342 Print(L" Capsule FMP UpdateImageIndex: 0x%x\n", CapsuleResultFmp->UpdateImageIndex);
343 Print(L" Capsule FMP UpdateImageTypeId: %g\n", &CapsuleResultFmp->UpdateImageTypeId);
344 if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) {
345 Print(L" Capsule FMP CapsuleFileName: %s\n", (CapsuleResultFmp + 1));
346 CapsuleFileNameSize = StrSize((CHAR16 *)(CapsuleResultFmp + 1));
347 if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + CapsuleFileNameSize) {
348 Print(L" Capsule FMP CapsuleTarget: %s\n", (UINT8 *)(CapsuleResultFmp + 1) + CapsuleFileNameSize);
349 }
350 }
351 }
352 }
353
354 FreePool(CapsuleResult);
355
356 Index++;
357 if (Index > 0xFFFF) {
358 break;
359 }
360 }
361
362 return EFI_SUCCESS;
363 }
364
365 CHAR8 *mFwTypeString[] = {
366 "Unknown",
367 "SystemFirmware",
368 "DeviceFirmware",
369 "UefiDriver",
370 };
371
372 CHAR8 *mLastAttemptStatusString[] = {
373 "Success",
374 "Error: Unsuccessful",
375 "Error: Insufficient Resources",
376 "Error: Incorrect Version",
377 "Error: Invalid Format",
378 "Error: Auth Error",
379 "Error: Power Event AC",
380 "Error: Power Event Battery",
381 };
382
383 /**
384 Convert FwType to a string.
385
386 @param[in] FwType FwType in ESRT
387
388 @return a string for FwType.
389 **/
390 CHAR8 *
391 FwTypeToString (
392 IN UINT32 FwType
393 )
394 {
395 if (FwType < sizeof(mFwTypeString) / sizeof(mFwTypeString[0])) {
396 return mFwTypeString[FwType];
397 } else {
398 return "Invalid";
399 }
400 }
401
402 /**
403 Convert LastAttemptStatus to a string.
404
405 @param[in] LastAttemptStatus LastAttemptStatus in FMP or ESRT
406
407 @return a string for LastAttemptStatus.
408 **/
409 CHAR8 *
410 LastAttemptStatusToString (
411 IN UINT32 LastAttemptStatus
412 )
413 {
414 if (LastAttemptStatus < sizeof(mLastAttemptStatusString) / sizeof(mLastAttemptStatusString[0])) {
415 return mLastAttemptStatusString[LastAttemptStatus];
416 } else {
417 return "Error: Unknown";
418 }
419 }
420
421 /**
422 Dump ESRT entry.
423
424 @param[in] EsrtEntry ESRT entry
425 **/
426 VOID
427 DumpEsrtEntry (
428 IN EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry
429 )
430 {
431 Print(L" FwClass - %g\n", &EsrtEntry->FwClass);
432 Print(L" FwType - 0x%x (%a)\n", EsrtEntry->FwType, FwTypeToString(EsrtEntry->FwType));
433 Print(L" FwVersion - 0x%x\n", EsrtEntry->FwVersion);
434 Print(L" LowestSupportedFwVersion - 0x%x\n", EsrtEntry->LowestSupportedFwVersion);
435 Print(L" CapsuleFlags - 0x%x\n", EsrtEntry->CapsuleFlags);
436 Print(L" PERSIST_ACROSS_RESET - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET);
437 Print(L" POPULATE_SYSTEM_TABLE - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE);
438 Print(L" INITIATE_RESET - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_INITIATE_RESET);
439 Print(L" LastAttemptVersion - 0x%x\n", EsrtEntry->LastAttemptVersion);
440 Print(L" LastAttemptStatus - 0x%x (%a)\n", EsrtEntry->LastAttemptStatus, LastAttemptStatusToString(EsrtEntry->LastAttemptStatus));
441 }
442
443 /**
444 Dump ESRT table.
445
446 @param[in] Esrt ESRT table
447 **/
448 VOID
449 DumpEsrt (
450 IN EFI_SYSTEM_RESOURCE_TABLE *Esrt
451 )
452 {
453 UINTN Index;
454 EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;
455
456 if (Esrt == NULL) {
457 return ;
458 }
459
460 Print(L"EFI_SYSTEM_RESOURCE_TABLE:\n");
461 Print(L"FwResourceCount - 0x%x\n", Esrt->FwResourceCount);
462 Print(L"FwResourceCountMax - 0x%x\n", Esrt->FwResourceCountMax);
463 Print(L"FwResourceVersion - 0x%lx\n", Esrt->FwResourceVersion);
464
465 EsrtEntry = (VOID *)(Esrt + 1);
466 for (Index = 0; Index < Esrt->FwResourceCount; Index++) {
467 Print(L"EFI_SYSTEM_RESOURCE_ENTRY (%d):\n", Index);
468 DumpEsrtEntry(EsrtEntry);
469 EsrtEntry++;
470 }
471 }
472
473 /**
474 Dump ESRT info.
475 **/
476 VOID
477 DumpEsrtData (
478 VOID
479 )
480 {
481 EFI_STATUS Status;
482 EFI_SYSTEM_RESOURCE_TABLE *Esrt;
483
484 Print(L"##############\n");
485 Print(L"# ESRT TABLE #\n");
486 Print(L"##############\n");
487
488 Status = EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid, (VOID **)&Esrt);
489 if (EFI_ERROR(Status)) {
490 Print(L"ESRT - %r\n", Status);
491 return;
492 }
493 DumpEsrt(Esrt);
494 Print(L"\n");
495 }
496
497 /**
498 Dump FMP information.
499
500 @param[in] ImageInfoSize The size of ImageInfo, in bytes.
501 @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.
502 @param[in] DescriptorVersion The version of EFI_FIRMWARE_IMAGE_DESCRIPTOR.
503 @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.
504 @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.
505 @param[in] PackageVersion The version of package.
506 @param[in] PackageVersionName The version name of package.
507 **/
508 VOID
509 DumpFmpImageInfo (
510 IN UINTN ImageInfoSize,
511 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,
512 IN UINT32 DescriptorVersion,
513 IN UINT8 DescriptorCount,
514 IN UINTN DescriptorSize,
515 IN UINT32 PackageVersion,
516 IN CHAR16 *PackageVersionName
517 )
518 {
519 EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo;
520 UINTN Index;
521
522 Print(L" DescriptorVersion - 0x%x\n", DescriptorVersion);
523 Print(L" DescriptorCount - 0x%x\n", DescriptorCount);
524 Print(L" DescriptorSize - 0x%x\n", DescriptorSize);
525 Print(L" PackageVersion - 0x%x\n", PackageVersion);
526 Print(L" PackageVersionName - \"%s\"\n", PackageVersionName);
527 CurrentImageInfo = ImageInfo;
528 for (Index = 0; Index < DescriptorCount; Index++) {
529 Print(L" ImageDescriptor (%d)\n", Index);
530 Print(L" ImageIndex - 0x%x\n", CurrentImageInfo->ImageIndex);
531 Print(L" ImageTypeId - %g\n", &CurrentImageInfo->ImageTypeId);
532 Print(L" ImageId - 0x%lx\n", CurrentImageInfo->ImageId);
533 Print(L" ImageIdName - \"%s\"\n", CurrentImageInfo->ImageIdName);
534 Print(L" Version - 0x%x\n", CurrentImageInfo->Version);
535 Print(L" VersionName - \"%s\"\n", CurrentImageInfo->VersionName);
536 Print(L" Size - 0x%x\n", CurrentImageInfo->Size);
537 Print(L" AttributesSupported - 0x%lx\n", CurrentImageInfo->AttributesSupported);
538 Print(L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
539 Print(L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);
540 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
541 Print(L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE);
542 Print(L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_UEFI_IMAGE);
543 Print(L" AttributesSetting - 0x%lx\n", CurrentImageInfo->AttributesSetting);
544 Print(L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
545 Print(L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);
546 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
547 Print(L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IN_USE);
548 Print(L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_UEFI_IMAGE);
549 Print(L" Compatibilities - 0x%lx\n", CurrentImageInfo->Compatibilities);
550 Print(L" COMPATIB_CHECK_SUPPORTED - 0x%lx\n", CurrentImageInfo->Compatibilities & IMAGE_COMPATIBILITY_CHECK_SUPPORTED);
551 if (DescriptorVersion > 1) {
552 Print(L" LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion);
553 if (DescriptorVersion > 2) {
554 Print(L" LastAttemptVersion - 0x%x\n", CurrentImageInfo->LastAttemptVersion);
555 Print(L" LastAttemptStatus - 0x%x (%a)\n", CurrentImageInfo->LastAttemptStatus, LastAttemptStatusToString(CurrentImageInfo->LastAttemptStatus));
556 Print(L" HardwareInstance - 0x%lx\n", CurrentImageInfo->HardwareInstance);
557 }
558 }
559 //
560 // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version
561 //
562 CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);
563 }
564 }
565
566 /**
567 Dump FMP package information.
568
569 @param[in] PackageVersion The version of package.
570 @param[in] PackageVersionName The version name of package.
571 @param[in] PackageVersionNameMaxLen The maximum length of PackageVersionName.
572 @param[in] AttributesSupported Package attributes that are supported by this device.
573 @param[in] AttributesSetting Package attributes.
574 **/
575 VOID
576 DumpFmpPackageInfo (
577 IN UINT32 PackageVersion,
578 IN CHAR16 *PackageVersionName,
579 IN UINT32 PackageVersionNameMaxLen,
580 IN UINT64 AttributesSupported,
581 IN UINT64 AttributesSetting
582 )
583 {
584 Print(L" PackageVersion - 0x%x\n", PackageVersion);
585 Print(L" PackageVersionName - \"%s\"\n", PackageVersionName);
586 Print(L" PackageVersionNameMaxLen - 0x%x\n", PackageVersionNameMaxLen);
587 Print(L" AttributesSupported - 0x%lx\n", AttributesSupported);
588 Print(L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
589 Print(L" RESET_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);
590 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
591 Print(L" AttributesSetting - 0x%lx\n", AttributesSetting);
592 Print(L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);
593 Print(L" RESET_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);
594 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
595 }
596
597 /**
598 Dump FMP protocol info.
599 **/
600 VOID
601 DumpFmpData (
602 VOID
603 )
604 {
605 EFI_STATUS Status;
606 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
607 EFI_HANDLE *HandleBuffer;
608 UINTN NumberOfHandles;
609 UINTN Index;
610 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;
611 UINTN ImageInfoSize;
612 UINT32 FmpImageInfoDescriptorVer;
613 UINT8 FmpImageInfoCount;
614 UINTN DescriptorSize;
615 UINT32 PackageVersion;
616 CHAR16 *PackageVersionName;
617 UINT32 PackageVersionNameMaxLen;
618 UINT64 AttributesSupported;
619 UINT64 AttributesSetting;
620
621 Print(L"############\n");
622 Print(L"# FMP DATA #\n");
623 Print(L"############\n");
624 Status = gBS->LocateHandleBuffer (
625 ByProtocol,
626 &gEfiFirmwareManagementProtocolGuid,
627 NULL,
628 &NumberOfHandles,
629 &HandleBuffer
630 );
631 if (EFI_ERROR(Status)) {
632 Print(L"FMP protocol - %r\n", EFI_NOT_FOUND);
633 return;
634 }
635
636 for (Index = 0; Index < NumberOfHandles; Index++) {
637 Status = gBS->HandleProtocol(
638 HandleBuffer[Index],
639 &gEfiFirmwareManagementProtocolGuid,
640 (VOID **)&Fmp
641 );
642 if (EFI_ERROR(Status)) {
643 continue;
644 }
645
646 ImageInfoSize = 0;
647 Status = Fmp->GetImageInfo (
648 Fmp,
649 &ImageInfoSize,
650 NULL,
651 NULL,
652 NULL,
653 NULL,
654 NULL,
655 NULL
656 );
657 if (Status != EFI_BUFFER_TOO_SMALL) {
658 continue;
659 }
660
661 FmpImageInfoBuf = NULL;
662 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);
663 if (FmpImageInfoBuf == NULL) {
664 Status = EFI_OUT_OF_RESOURCES;
665 goto EXIT;
666 }
667
668 PackageVersionName = NULL;
669 Status = Fmp->GetImageInfo (
670 Fmp,
671 &ImageInfoSize, // ImageInfoSize
672 FmpImageInfoBuf, // ImageInfo
673 &FmpImageInfoDescriptorVer, // DescriptorVersion
674 &FmpImageInfoCount, // DescriptorCount
675 &DescriptorSize, // DescriptorSize
676 &PackageVersion, // PackageVersion
677 &PackageVersionName // PackageVersionName
678 );
679
680 //
681 // If FMP GetInformation interface failed, skip this resource
682 //
683 if (EFI_ERROR(Status)) {
684 Print(L"FMP (%d) ImageInfo - %r\n", Index, Status);
685 FreePool(FmpImageInfoBuf);
686 continue;
687 }
688
689 Print(L"FMP (%d) ImageInfo:\n", Index);
690 DumpFmpImageInfo(
691 ImageInfoSize, // ImageInfoSize
692 FmpImageInfoBuf, // ImageInfo
693 FmpImageInfoDescriptorVer, // DescriptorVersion
694 FmpImageInfoCount, // DescriptorCount
695 DescriptorSize, // DescriptorSize
696 PackageVersion, // PackageVersion
697 PackageVersionName // PackageVersionName
698 );
699
700 if (PackageVersionName != NULL) {
701 FreePool(PackageVersionName);
702 }
703 FreePool(FmpImageInfoBuf);
704
705 //
706 // Get package info
707 //
708 PackageVersionName = NULL;
709 Status = Fmp->GetPackageInfo (
710 Fmp,
711 &PackageVersion, // PackageVersion
712 &PackageVersionName, // PackageVersionName
713 &PackageVersionNameMaxLen, // PackageVersionNameMaxLen
714 &AttributesSupported, // AttributesSupported
715 &AttributesSetting // AttributesSetting
716 );
717 if (EFI_ERROR(Status)) {
718 Print(L"FMP (%d) PackageInfo - %r\n", Index, Status);
719 } else {
720 Print(L"FMP (%d) ImageInfo:\n", Index);
721 DumpFmpPackageInfo(
722 PackageVersion, // PackageVersion
723 PackageVersionName, // PackageVersionName
724 PackageVersionNameMaxLen, // PackageVersionNameMaxLen
725 AttributesSupported, // AttributesSupported
726 AttributesSetting // AttributesSetting
727 );
728
729 if (PackageVersionName != NULL) {
730 FreePool(PackageVersionName);
731 }
732 }
733 }
734 Print(L"\n");
735
736 EXIT:
737 FreePool(HandleBuffer);
738 }