+/** @file\r
+ Dump Capsule image information.\r
+\r
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiDxe.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Protocol/FirmwareManagement.h>\r
+#include <Guid/ImageAuthentication.h>\r
+#include <Guid/CapsuleReport.h>\r
+#include <Guid/SystemResourceTable.h>\r
+#include <Guid/FmpCapsule.h>\r
+#include <IndustryStandard/WindowsUxCapsule.h>\r
+\r
+/**\r
+ Read a file.\r
+\r
+ @param[in] FileName The file to be read.\r
+ @param[in] BufferSize The file buffer size\r
+ @param[in] Buffer The file buffer\r
+\r
+ @retval EFI_SUCCESS Read file successfully\r
+ @retval EFI_NOT_FOUND File not found\r
+**/\r
+EFI_STATUS\r
+ReadFileToBuffer (\r
+ IN CHAR16 *FileName,\r
+ OUT UINTN *BufferSize,\r
+ OUT VOID **Buffer\r
+ );\r
+\r
+/**\r
+ Dump UX capsule information.\r
+\r
+ @param[in] CapsuleHeader The UX capsule header\r
+**/\r
+VOID\r
+DumpUxCapsule (\r
+ IN EFI_CAPSULE_HEADER *CapsuleHeader\r
+ )\r
+{\r
+ EFI_DISPLAY_CAPSULE *DisplayCapsule;\r
+ DisplayCapsule = (EFI_DISPLAY_CAPSULE *)CapsuleHeader;\r
+ Print(L"[UxCapusule]\n");\r
+ Print(L"CapsuleHeader:\n");\r
+ Print(L" CapsuleGuid - %g\n", &DisplayCapsule->CapsuleHeader.CapsuleGuid);\r
+ Print(L" HeaderSize - 0x%x\n", DisplayCapsule->CapsuleHeader.HeaderSize);\r
+ Print(L" Flags - 0x%x\n", DisplayCapsule->CapsuleHeader.Flags);\r
+ Print(L" CapsuleImageSize - 0x%x\n", DisplayCapsule->CapsuleHeader.CapsuleImageSize);\r
+ Print(L"ImagePayload:\n");\r
+ Print(L" Version - 0x%x\n", DisplayCapsule->ImagePayload.Version);\r
+ Print(L" Checksum - 0x%x\n", DisplayCapsule->ImagePayload.Checksum);\r
+ Print(L" ImageType - 0x%x\n", DisplayCapsule->ImagePayload.ImageType);\r
+ Print(L" Mode - 0x%x\n", DisplayCapsule->ImagePayload.Mode);\r
+ Print(L" OffsetX - 0x%x\n", DisplayCapsule->ImagePayload.OffsetX);\r
+ Print(L" OffsetY - 0x%x\n", DisplayCapsule->ImagePayload.OffsetY);\r
+}\r
+\r
+/**\r
+ Dump FMP image authentication information.\r
+\r
+ @param[in] Image The FMP capsule image\r
+ @param[in] ImageSize The size of the FMP capsule image in bytes.\r
+\r
+ @return the size of FMP authentication.\r
+**/\r
+UINTN\r
+DumpImageAuthentication (\r
+ IN VOID *Image,\r
+ IN UINTN ImageSize\r
+ )\r
+{\r
+ EFI_FIRMWARE_IMAGE_AUTHENTICATION *ImageAuthentication;\r
+\r
+ ImageAuthentication = Image;\r
+ if (CompareGuid(&ImageAuthentication->AuthInfo.CertType, &gEfiCertPkcs7Guid) ||\r
+ CompareGuid(&ImageAuthentication->AuthInfo.CertType, &gEfiCertTypeRsa2048Sha256Guid)) {\r
+ Print(L"[ImageAuthentication]\n");\r
+ Print(L" MonotonicCount - 0x%lx\n", ImageAuthentication->MonotonicCount);\r
+ Print(L"WIN_CERTIFICATE:\n");\r
+ Print(L" dwLength - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.dwLength);\r
+ Print(L" wRevision - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.wRevision);\r
+ Print(L" wCertificateType - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.wCertificateType);\r
+ Print(L" CertType - %g\n", &ImageAuthentication->AuthInfo.CertType);\r
+ return sizeof(ImageAuthentication->MonotonicCount) + ImageAuthentication->AuthInfo.Hdr.dwLength;\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+\r
+/**\r
+ Dump a non-nested FMP capsule.\r
+\r
+ @param[in] CapsuleHeader A pointer to CapsuleHeader\r
+**/\r
+VOID\r
+DumpFmpCapsule (\r
+ IN EFI_CAPSULE_HEADER *CapsuleHeader\r
+ )\r
+{\r
+ EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *FmpCapsuleHeader;\r
+ UINT64 *ItemOffsetList;\r
+ UINTN Index;\r
+ UINTN Count;\r
+ EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *FmpImageHeader;\r
+\r
+ Print(L"[FmpCapusule]\n");\r
+ Print(L"CapsuleHeader:\n");\r
+ Print(L" CapsuleGuid - %g\n", &CapsuleHeader->CapsuleGuid);\r
+ Print(L" HeaderSize - 0x%x\n", CapsuleHeader->HeaderSize);\r
+ Print(L" Flags - 0x%x\n", CapsuleHeader->Flags);\r
+ Print(L" CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);\r
+\r
+ FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
+ ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);\r
+ Print(L"FmpHeader:\n");\r
+ Print(L" Version - 0x%x\n", FmpCapsuleHeader->Version);\r
+ Print(L" EmbeddedDriverCount - 0x%x\n", FmpCapsuleHeader->EmbeddedDriverCount);\r
+ Print(L" PayloadItemCount - 0x%x\n", FmpCapsuleHeader->PayloadItemCount);\r
+ Count = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;\r
+ for (Index = 0; Index < Count; Index++) {\r
+ Print(L" Offset[%d] - 0x%x\n", Index, ItemOffsetList[Index]);\r
+ }\r
+\r
+ for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < Count; Index++) {\r
+ Print(L"FmpPayload[%d] ImageHeader:\n", Index);\r
+ FmpImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);\r
+ Print(L" Version - 0x%x\n", FmpImageHeader->Version);\r
+ Print(L" UpdateImageTypeId - %g\n", &FmpImageHeader->UpdateImageTypeId);\r
+ Print(L" UpdateImageIndex - 0x%x\n", FmpImageHeader->UpdateImageIndex);\r
+ Print(L" UpdateImageSize - 0x%x\n", FmpImageHeader->UpdateImageSize);\r
+ Print(L" UpdateVendorCodeSize - 0x%x\n", FmpImageHeader->UpdateVendorCodeSize);\r
+ if (FmpImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
+ Print(L" UpdateHardwareInstance - 0x%lx\n", FmpImageHeader->UpdateHardwareInstance);\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Return if there is a FMP header below capsule header.\r
+\r
+ @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER\r
+\r
+ @retval TRUE There is a FMP header below capsule header.\r
+ @retval FALSE There is not a FMP header below capsule header\r
+**/\r
+BOOLEAN\r
+IsNestedFmpCapsule (\r
+ IN EFI_CAPSULE_HEADER *CapsuleHeader\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_SYSTEM_RESOURCE_TABLE *Esrt;\r
+ EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;\r
+ UINTN Index;\r
+ BOOLEAN EsrtGuidFound;\r
+ EFI_CAPSULE_HEADER *NestedCapsuleHeader;\r
+ UINTN NestedCapsuleSize;\r
+\r
+ //\r
+ // Check ESRT\r
+ //\r
+ EsrtGuidFound = FALSE;\r
+ Status = EfiGetSystemConfigurationTable(&gEfiSystemResourceTableGuid, (VOID **)&Esrt);\r
+ if (!EFI_ERROR(Status)) {\r
+ ASSERT (Esrt != NULL);\r
+ EsrtEntry = (VOID *)(Esrt + 1);\r
+ for (Index = 0; Index < Esrt->FwResourceCount; Index++, EsrtEntry++) {\r
+ if (CompareGuid(&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {\r
+ EsrtGuidFound = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!EsrtGuidFound) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Check nested capsule header\r
+ // FMP GUID after ESRT one\r
+ //\r
+ NestedCapsuleHeader = (EFI_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
+ NestedCapsuleSize = (UINTN)CapsuleHeader + CapsuleHeader->HeaderSize - (UINTN)NestedCapsuleHeader;\r
+ if (NestedCapsuleSize < sizeof(EFI_CAPSULE_HEADER)) {\r
+ return FALSE;\r
+ }\r
+ if (!CompareGuid(&NestedCapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Dump capsule information\r
+\r
+ @param[in] CapsuleName The name of the capsule image.\r
+\r
+ @retval EFI_SUCCESS The capsule information is dumped.\r
+ @retval EFI_UNSUPPORTED Input parameter is not valid.\r
+**/\r
+EFI_STATUS\r
+DumpCapsule (\r
+ IN CHAR16 *CapsuleName\r
+ )\r
+{\r
+ VOID *Buffer;\r
+ UINTN FileSize;\r
+ EFI_CAPSULE_HEADER *CapsuleHeader;\r
+ EFI_STATUS Status;\r
+\r
+ Status = ReadFileToBuffer(CapsuleName, &FileSize, &Buffer);\r
+ if (EFI_ERROR(Status)) {\r
+ Print(L"CapsuleApp: Capsule (%s) is not found.\n", CapsuleName);\r
+ goto Done;\r
+ }\r
+\r
+ CapsuleHeader = Buffer;\r
+ if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {\r
+ DumpUxCapsule(CapsuleHeader);\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+\r
+ if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
+ DumpFmpCapsule(CapsuleHeader);\r
+ }\r
+ if (IsNestedFmpCapsule(CapsuleHeader)) {\r
+ Print(L"[NestedCapusule]\n");\r
+ Print(L"CapsuleHeader:\n");\r
+ Print(L" CapsuleGuid - %g\n", &CapsuleHeader->CapsuleGuid);\r
+ Print(L" HeaderSize - 0x%x\n", CapsuleHeader->HeaderSize);\r
+ Print(L" Flags - 0x%x\n", CapsuleHeader->Flags);\r
+ Print(L" CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);\r
+ DumpFmpCapsule((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize));\r
+ }\r
+\r
+Done:\r
+ FreePool(Buffer);\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Dump capsule status variable.\r
+\r
+ @retval EFI_SUCCESS The capsule status variable is dumped.\r
+ @retval EFI_UNSUPPORTED Input parameter is not valid.\r
+**/\r
+EFI_STATUS\r
+DmpCapsuleStatusVariable (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 Index;\r
+ CHAR16 CapsuleVarName[20];\r
+ CHAR16 *TempVarName;\r
+ EFI_CAPSULE_RESULT_VARIABLE_HEADER *CapsuleResult;\r
+ EFI_CAPSULE_RESULT_VARIABLE_FMP *CapsuleResultFmp;\r
+ UINTN CapsuleFileNameSize;\r
+ CHAR16 CapsuleIndexData[12];\r
+ CHAR16 *CapsuleIndex;\r
+\r
+ Status = GetVariable2(\r
+ L"CapsuleMax",\r
+ &gEfiCapsuleReportGuid,\r
+ (VOID **)&CapsuleIndex,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR(Status)) {\r
+ CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));\r
+ CapsuleIndexData[11] = 0;\r
+ Print(L"CapsuleMax - %s\n", CapsuleIndexData);\r
+ FreePool(CapsuleIndex);\r
+ }\r
+ Status = GetVariable2(\r
+ L"CapsuleLast",\r
+ &gEfiCapsuleReportGuid,\r
+ (VOID **)&CapsuleIndex,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR(Status)) {\r
+ CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));\r
+ CapsuleIndexData[11] = 0;\r
+ Print(L"CapsuleLast - %s\n", CapsuleIndexData);\r
+ FreePool(CapsuleIndex);\r
+ }\r
+\r
+\r
+ StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CapsuleVarName[0]), L"Capsule");\r
+ TempVarName = CapsuleVarName + StrLen (CapsuleVarName);\r
+ Index = 0;\r
+\r
+ while (TRUE) {\r
+ UnicodeSPrint (TempVarName, 5 * sizeof(CHAR16), L"%04x", Index);\r
+\r
+ Status = GetVariable2 (\r
+ CapsuleVarName,\r
+ &gEfiCapsuleReportGuid,\r
+ (VOID **) &CapsuleResult,\r
+ NULL\r
+ );\r
+ if (Status == EFI_NOT_FOUND) {\r
+ break;\r
+ } else if (EFI_ERROR(Status)) {\r
+ continue;\r
+ }\r
+ ASSERT (CapsuleResult != NULL);\r
+\r
+ //\r
+ // display capsule process status\r
+ //\r
+ if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER)) {\r
+ Print (L"CapsuleName: %s\n", CapsuleVarName);\r
+ Print (L" Capsule Guid: %g\n", &CapsuleResult->CapsuleGuid);\r
+ Print (L" Capsule ProcessedTime: %t\n", &CapsuleResult->CapsuleProcessed);\r
+ Print (L" Capsule Status: %r\n", CapsuleResult->CapsuleStatus);\r
+ }\r
+\r
+ if (CompareGuid(&CapsuleResult->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
+ if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) {\r
+ CapsuleResultFmp = (EFI_CAPSULE_RESULT_VARIABLE_FMP *)(CapsuleResult + 1);\r
+ Print(L" Capsule FMP Version: 0x%x\n", CapsuleResultFmp->Version);\r
+ Print(L" Capsule FMP PayloadIndex: 0x%x\n", CapsuleResultFmp->PayloadIndex);\r
+ Print(L" Capsule FMP UpdateImageIndex: 0x%x\n", CapsuleResultFmp->UpdateImageIndex);\r
+ Print(L" Capsule FMP UpdateImageTypeId: %g\n", &CapsuleResultFmp->UpdateImageTypeId);\r
+ if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) {\r
+ Print(L" Capsule FMP CapsuleFileName: %s\n", (CapsuleResultFmp + 1));\r
+ CapsuleFileNameSize = StrSize((CHAR16 *)(CapsuleResultFmp + 1));\r
+ if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + CapsuleFileNameSize) {\r
+ Print(L" Capsule FMP CapsuleTarget: %s\n", (UINT8 *)(CapsuleResultFmp + 1) + CapsuleFileNameSize);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ FreePool(CapsuleResult);\r
+\r
+ Index++;\r
+ if (Index > 0xFFFF) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+CHAR8 *mFwTypeString[] = {\r
+ "Unknown",\r
+ "SystemFirmware",\r
+ "DeviceFirmware",\r
+ "UefiDriver",\r
+};\r
+\r
+CHAR8 *mLastAttemptStatusString[] = {\r
+ "Success",\r
+ "Error: Unsuccessful",\r
+ "Error: Insufficient Resources",\r
+ "Error: Incorrect Version",\r
+ "Error: Invalid Format",\r
+ "Error: Auth Error",\r
+ "Error: Power Event AC",\r
+ "Error: Power Event Battery",\r
+};\r
+\r
+/**\r
+ Convert FwType to a string.\r
+\r
+ @param[in] FwType FwType in ESRT\r
+\r
+ @return a string for FwType.\r
+**/\r
+CHAR8 *\r
+FwTypeToString (\r
+ IN UINT32 FwType\r
+ )\r
+{\r
+ if (FwType < sizeof(mFwTypeString) / sizeof(mFwTypeString[0])) {\r
+ return mFwTypeString[FwType];\r
+ } else {\r
+ return "Invalid";\r
+ }\r
+}\r
+\r
+/**\r
+ Convert LastAttemptStatus to a string.\r
+\r
+ @param[in] LastAttemptStatus LastAttemptStatus in FMP or ESRT\r
+\r
+ @return a string for LastAttemptStatus.\r
+**/\r
+CHAR8 *\r
+LastAttemptStatusToString (\r
+ IN UINT32 LastAttemptStatus\r
+ )\r
+{\r
+ if (LastAttemptStatus < sizeof(mLastAttemptStatusString) / sizeof(mLastAttemptStatusString[0])) {\r
+ return mLastAttemptStatusString[LastAttemptStatus];\r
+ } else {\r
+ return "Error: Unknown";\r
+ }\r
+}\r
+\r
+/**\r
+ Dump ESRT entry.\r
+\r
+ @param[in] EsrtEntry ESRT entry\r
+**/\r
+VOID\r
+DumpEsrtEntry (\r
+ IN EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry\r
+ )\r
+{\r
+ Print(L" FwClass - %g\n", &EsrtEntry->FwClass);\r
+ Print(L" FwType - 0x%x (%a)\n", EsrtEntry->FwType, FwTypeToString(EsrtEntry->FwType));\r
+ Print(L" FwVersion - 0x%x\n", EsrtEntry->FwVersion);\r
+ Print(L" LowestSupportedFwVersion - 0x%x\n", EsrtEntry->LowestSupportedFwVersion);\r
+ Print(L" CapsuleFlags - 0x%x\n", EsrtEntry->CapsuleFlags);\r
+ Print(L" PERSIST_ACROSS_RESET - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET);\r
+ Print(L" POPULATE_SYSTEM_TABLE - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE);\r
+ Print(L" INITIATE_RESET - 0x%x\n", EsrtEntry->CapsuleFlags & CAPSULE_FLAGS_INITIATE_RESET);\r
+ Print(L" LastAttemptVersion - 0x%x\n", EsrtEntry->LastAttemptVersion);\r
+ Print(L" LastAttemptStatus - 0x%x (%a)\n", EsrtEntry->LastAttemptStatus, LastAttemptStatusToString(EsrtEntry->LastAttemptStatus));\r
+}\r
+\r
+/**\r
+ Dump ESRT table.\r
+\r
+ @param[in] Esrt ESRT table\r
+**/\r
+VOID\r
+DumpEsrt (\r
+ IN EFI_SYSTEM_RESOURCE_TABLE *Esrt\r
+ )\r
+{\r
+ UINTN Index;\r
+ EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;\r
+\r
+ if (Esrt == NULL) {\r
+ return ;\r
+ }\r
+\r
+ Print(L"EFI_SYSTEM_RESOURCE_TABLE:\n");\r
+ Print(L"FwResourceCount - 0x%x\n", Esrt->FwResourceCount);\r
+ Print(L"FwResourceCountMax - 0x%x\n", Esrt->FwResourceCountMax);\r
+ Print(L"FwResourceVersion - 0x%lx\n", Esrt->FwResourceVersion);\r
+\r
+ EsrtEntry = (VOID *)(Esrt + 1);\r
+ for (Index = 0; Index < Esrt->FwResourceCount; Index++) {\r
+ Print(L"EFI_SYSTEM_RESOURCE_ENTRY (%d):\n", Index);\r
+ DumpEsrtEntry(EsrtEntry);\r
+ EsrtEntry++;\r
+ }\r
+}\r
+\r
+/**\r
+ Dump ESRT info.\r
+**/\r
+VOID\r
+DumpEsrtData (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_SYSTEM_RESOURCE_TABLE *Esrt;\r
+\r
+ Print(L"##############\n");\r
+ Print(L"# ESRT TABLE #\n");\r
+ Print(L"##############\n");\r
+\r
+ Status = EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid, (VOID **)&Esrt);\r
+ if (EFI_ERROR(Status)) {\r
+ Print(L"ESRT - %r\n", Status);\r
+ return;\r
+ }\r
+ DumpEsrt(Esrt);\r
+ Print(L"\n");\r
+}\r
+\r
+/**\r
+ Dump FMP information.\r
+\r
+ @param[in] ImageInfoSize The size of ImageInfo, in bytes.\r
+ @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+ @param[in] DescriptorVersion The version of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+ @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+ @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.\r
+ @param[in] PackageVersion The version of package.\r
+ @param[in] PackageVersionName The version name of package.\r
+**/\r
+VOID\r
+DumpFmpImageInfo (\r
+ IN UINTN ImageInfoSize,\r
+ IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,\r
+ IN UINT32 DescriptorVersion,\r
+ IN UINT8 DescriptorCount,\r
+ IN UINTN DescriptorSize,\r
+ IN UINT32 PackageVersion,\r
+ IN CHAR16 *PackageVersionName\r
+ )\r
+{\r
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo;\r
+ UINTN Index;\r
+\r
+ Print(L" DescriptorVersion - 0x%x\n", DescriptorVersion);\r
+ Print(L" DescriptorCount - 0x%x\n", DescriptorCount);\r
+ Print(L" DescriptorSize - 0x%x\n", DescriptorSize);\r
+ Print(L" PackageVersion - 0x%x\n", PackageVersion);\r
+ Print(L" PackageVersionName - \"%s\"\n", PackageVersionName);\r
+ CurrentImageInfo = ImageInfo;\r
+ for (Index = 0; Index < DescriptorCount; Index++) {\r
+ Print(L" ImageDescriptor (%d)\n", Index);\r
+ Print(L" ImageIndex - 0x%x\n", CurrentImageInfo->ImageIndex);\r
+ Print(L" ImageTypeId - %g\n", &CurrentImageInfo->ImageTypeId);\r
+ Print(L" ImageId - 0x%lx\n", CurrentImageInfo->ImageId);\r
+ Print(L" ImageIdName - \"%s\"\n", CurrentImageInfo->ImageIdName);\r
+ Print(L" Version - 0x%x\n", CurrentImageInfo->Version);\r
+ Print(L" VersionName - \"%s\"\n", CurrentImageInfo->VersionName);\r
+ Print(L" Size - 0x%x\n", CurrentImageInfo->Size);\r
+ Print(L" AttributesSupported - 0x%lx\n", CurrentImageInfo->AttributesSupported);\r
+ Print(L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
+ Print(L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
+ Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
+ Print(L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE);\r
+ Print(L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_UEFI_IMAGE);\r
+ Print(L" AttributesSetting - 0x%lx\n", CurrentImageInfo->AttributesSetting);\r
+ Print(L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
+ Print(L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
+ Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
+ Print(L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IN_USE);\r
+ Print(L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_UEFI_IMAGE);\r
+ Print(L" Compatibilities - 0x%lx\n", CurrentImageInfo->Compatibilities);\r
+ Print(L" COMPATIB_CHECK_SUPPORTED - 0x%lx\n", CurrentImageInfo->Compatibilities & IMAGE_COMPATIBILITY_CHECK_SUPPORTED);\r
+ if (DescriptorVersion > 1) {\r
+ Print(L" LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion);\r
+ if (DescriptorVersion > 2) {\r
+ Print(L" LastAttemptVersion - 0x%x\n", CurrentImageInfo->LastAttemptVersion);\r
+ Print(L" LastAttemptStatus - 0x%x (%a)\n", CurrentImageInfo->LastAttemptStatus, LastAttemptStatusToString(CurrentImageInfo->LastAttemptStatus));\r
+ Print(L" HardwareInstance - 0x%lx\n", CurrentImageInfo->HardwareInstance);\r
+ }\r
+ }\r
+ //\r
+ // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version\r
+ //\r
+ CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);\r
+ }\r
+}\r
+\r
+/**\r
+ Dump FMP package information.\r
+\r
+ @param[in] PackageVersion The version of package.\r
+ @param[in] PackageVersionName The version name of package.\r
+ @param[in] PackageVersionNameMaxLen The maximum length of PackageVersionName.\r
+ @param[in] AttributesSupported Package attributes that are supported by this device.\r
+ @param[in] AttributesSetting Package attributes.\r
+**/\r
+VOID\r
+DumpFmpPackageInfo (\r
+ IN UINT32 PackageVersion,\r
+ IN CHAR16 *PackageVersionName,\r
+ IN UINT32 PackageVersionNameMaxLen,\r
+ IN UINT64 AttributesSupported,\r
+ IN UINT64 AttributesSetting\r
+ )\r
+{\r
+ Print(L" PackageVersion - 0x%x\n", PackageVersion);\r
+ Print(L" PackageVersionName - \"%s\"\n", PackageVersionName);\r
+ Print(L" PackageVersionNameMaxLen - 0x%x\n", PackageVersionNameMaxLen);\r
+ Print(L" AttributesSupported - 0x%lx\n", AttributesSupported);\r
+ Print(L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
+ Print(L" RESET_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
+ Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
+ Print(L" AttributesSetting - 0x%lx\n", AttributesSetting);\r
+ Print(L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
+ Print(L" RESET_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
+ Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
+}\r
+\r
+/**\r
+ Dump FMP protocol info.\r
+**/\r
+VOID\r
+DumpFmpData (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN NumberOfHandles;\r
+ UINTN Index;\r
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
+ UINTN ImageInfoSize;\r
+ UINT32 FmpImageInfoDescriptorVer;\r
+ UINT8 FmpImageInfoCount;\r
+ UINTN DescriptorSize;\r
+ UINT32 PackageVersion;\r
+ CHAR16 *PackageVersionName;\r
+ UINT32 PackageVersionNameMaxLen;\r
+ UINT64 AttributesSupported;\r
+ UINT64 AttributesSetting;\r
+\r
+ Print(L"############\n");\r
+ Print(L"# FMP DATA #\n");\r
+ Print(L"############\n");\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiFirmwareManagementProtocolGuid,\r
+ NULL,\r
+ &NumberOfHandles,\r
+ &HandleBuffer\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ Print(L"FMP protocol - %r\n", EFI_NOT_FOUND);\r
+ return;\r
+ }\r
+\r
+ for (Index = 0; Index < NumberOfHandles; Index++) {\r
+ Status = gBS->HandleProtocol(\r
+ HandleBuffer[Index],\r
+ &gEfiFirmwareManagementProtocolGuid,\r
+ (VOID **)&Fmp\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ continue;\r
+ }\r
+\r
+ ImageInfoSize = 0;\r
+ Status = Fmp->GetImageInfo (\r
+ Fmp,\r
+ &ImageInfoSize,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL\r
+ );\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ continue;\r
+ }\r
+\r
+ FmpImageInfoBuf = NULL;\r
+ FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
+ if (FmpImageInfoBuf == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto EXIT;\r
+ }\r
+\r
+ PackageVersionName = NULL;\r
+ Status = Fmp->GetImageInfo (\r
+ Fmp,\r
+ &ImageInfoSize, // ImageInfoSize\r
+ FmpImageInfoBuf, // ImageInfo\r
+ &FmpImageInfoDescriptorVer, // DescriptorVersion\r
+ &FmpImageInfoCount, // DescriptorCount\r
+ &DescriptorSize, // DescriptorSize\r
+ &PackageVersion, // PackageVersion\r
+ &PackageVersionName // PackageVersionName\r
+ );\r
+\r
+ //\r
+ // If FMP GetInformation interface failed, skip this resource\r
+ //\r
+ if (EFI_ERROR(Status)) {\r
+ Print(L"FMP (%d) ImageInfo - %r\n", Index, Status);\r
+ FreePool(FmpImageInfoBuf);\r
+ continue;\r
+ }\r
+\r
+ Print(L"FMP (%d) ImageInfo:\n", Index);\r
+ DumpFmpImageInfo(\r
+ ImageInfoSize, // ImageInfoSize\r
+ FmpImageInfoBuf, // ImageInfo\r
+ FmpImageInfoDescriptorVer, // DescriptorVersion\r
+ FmpImageInfoCount, // DescriptorCount\r
+ DescriptorSize, // DescriptorSize\r
+ PackageVersion, // PackageVersion\r
+ PackageVersionName // PackageVersionName\r
+ );\r
+\r
+ if (PackageVersionName != NULL) {\r
+ FreePool(PackageVersionName);\r
+ }\r
+ FreePool(FmpImageInfoBuf);\r
+\r
+ //\r
+ // Get package info\r
+ //\r
+ PackageVersionName = NULL;\r
+ Status = Fmp->GetPackageInfo (\r
+ Fmp,\r
+ &PackageVersion, // PackageVersion\r
+ &PackageVersionName, // PackageVersionName\r
+ &PackageVersionNameMaxLen, // PackageVersionNameMaxLen\r
+ &AttributesSupported, // AttributesSupported\r
+ &AttributesSetting // AttributesSetting\r
+ );\r
+ if (EFI_ERROR(Status)) {\r
+ Print(L"FMP (%d) PackageInfo - %r\n", Index, Status);\r
+ } else {\r
+ Print(L"FMP (%d) ImageInfo:\n", Index);\r
+ DumpFmpPackageInfo(\r
+ PackageVersion, // PackageVersion\r
+ PackageVersionName, // PackageVersionName\r
+ PackageVersionNameMaxLen, // PackageVersionNameMaxLen\r
+ AttributesSupported, // AttributesSupported\r
+ AttributesSetting // AttributesSetting\r
+ );\r
+\r
+ if (PackageVersionName != NULL) {\r
+ FreePool(PackageVersionName);\r
+ }\r
+ }\r
+ }\r
+ Print(L"\n");\r
+\r
+EXIT:\r
+ FreePool(HandleBuffer);\r
+}\r