diff --git a/MdeModulePkg/Library/HobPrintLib/HobPrintLib.c b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.c new file mode 100644 index 0000000000..d2fa92ee6a --- /dev/null +++ b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.c @@ -0,0 +1,469 @@ +/** @file + Prints all the HOBs. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ROW_LIMITER 16 + +typedef struct { + UINT16 Type; + CHAR8 *Name; + HOB_PRINT_HANDLER PrintHandler; +} HOB_PRINT_HANDLER_TABLE; + +CHAR8 *mMemoryTypeStr[] = { + "EfiReservedMemoryType", + "EfiLoaderCode", + "EfiLoaderData", + "EfiBootServicesCode", + "EfiBootServicesData", + "EfiRuntimeServicesCode", + "EfiRuntimeServicesData", + "EfiConventionalMemory", + "EfiUnusableMemory", + "EfiACPIReclaimMemory", + "EfiACPIMemoryNVS", + "EfiMemoryMappedIO", + "EfiMemoryMappedIOPortSpace", + "EfiPalCode", + "EfiPersistentMemory", + "EfiMaxMemoryType" +}; + +CHAR8 *mResource_Type_List[] = { + "EFI_RESOURCE_SYSTEM_MEMORY ", // 0x00000000 + "EFI_RESOURCE_MEMORY_MAPPED_IO ", // 0x00000001 + "EFI_RESOURCE_IO ", // 0x00000002 + "EFI_RESOURCE_FIRMWARE_DEVICE ", // 0x00000003 + "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT ", // 0x00000004 + "EFI_RESOURCE_MEMORY_RESERVED ", // 0x00000005 + "EFI_RESOURCE_IO_RESERVED ", // 0x00000006 + "EFI_RESOURCE_MAX_MEMORY_TYPE " // 0x00000007 +}; + +/** + Print the Hex value of a given range. + + @param[in] ErrorLevel Error Level to print the Hex value. + @param[in] DataStart A pointer to the start of data to be printed. + @param[in] DataSize The length of the data to be printed. + + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintHex ( + IN UINT32 ErrorLevel, + IN UINT8 *DataStart, + IN UINT16 DataSize + ) +{ + UINTN Index1; + UINTN Index2; + UINT8 *StartAddr; + + StartAddr = DataStart; + for (Index1 = 0; Index1 * ROW_LIMITER < DataSize; Index1++) { + DEBUG ((ErrorLevel, " 0x%04p:", (DataStart - StartAddr))); + for (Index2 = 0; (Index2 < ROW_LIMITER) && (Index1 * ROW_LIMITER + Index2 < DataSize); Index2++) { + DEBUG ((ErrorLevel, " %02x", *DataStart)); + DataStart++; + } + + DEBUG ((ErrorLevel, "\n")); + } + + return EFI_SUCCESS; +} + +/** + Print the Hex value of the Invalid HOB. + + @param[in] HobStart A pointer to the Invalid HOB. + @param[in] HobLength The length in bytes of the Invalid HOB. + + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintInvalidHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + DEBUG ((DEBUG_ERROR, " Invalid HOB. Full hex dump in below:\n")); + PrintHex (DEBUG_ERROR, HobStart, HobLength); + return RETURN_INVALID_PARAMETER; +} + +/** + Print the information in HandOffHob. + + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_HANDOFF. + @param[in] HobLength The length in bytes of HOB of type EFI_HOB_TYPE_HANDOFF. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintHandOffHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + if (HobLength < sizeof (*Hob.HandoffInformationTable)) { + return PrintInvalidHob (HobStart, HobLength); + } + + DEBUG ((DEBUG_INFO, " BootMode = 0x%x\n", Hob.HandoffInformationTable->BootMode)); + DEBUG ((DEBUG_INFO, " EfiMemoryTop = 0x%lx\n", Hob.HandoffInformationTable->EfiMemoryTop)); + DEBUG ((DEBUG_INFO, " EfiMemoryBottom = 0x%lx\n", Hob.HandoffInformationTable->EfiMemoryBottom)); + DEBUG ((DEBUG_INFO, " EfiFreeMemoryTop = 0x%lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop)); + DEBUG ((DEBUG_INFO, " EfiFreeMemoryBottom = 0x%lx\n", Hob.HandoffInformationTable->EfiFreeMemoryBottom)); + DEBUG ((DEBUG_INFO, " EfiEndOfHobList = 0x%lx\n", Hob.HandoffInformationTable->EfiEndOfHobList)); + return EFI_SUCCESS; +} + +/** + Print the information in Memory Allocation Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_MEMORY_ALLOCATION. + @param[in] HobLength The length in bytes of HOB of type EFI_HOB_TYPE_MEMORY_ALLOCATION. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintMemoryAllocationHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + + if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocStackGuid)) { + if (HobLength < sizeof (*Hob.MemoryAllocationStack)) { + return PrintInvalidHob (HobStart, HobLength); + } + + DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_STACK\n")); + } else if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocBspStoreGuid)) { + if (HobLength < sizeof (*Hob.MemoryAllocationBspStore)) { + return PrintInvalidHob (HobStart, HobLength); + } + + DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_BSP_STORE\n")); + } else if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocModuleGuid)) { + if (HobLength < sizeof (*Hob.MemoryAllocationModule)) { + return PrintInvalidHob (HobStart, HobLength); + } + + DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_MODULE\n")); + DEBUG ((DEBUG_INFO, " ModuleName = %g\n", &Hob.MemoryAllocationModule->ModuleName)); + DEBUG ((DEBUG_INFO, " EntryPoint = 0x%lx\n", Hob.MemoryAllocationModule->EntryPoint)); + } else { + if (HobLength < sizeof (*Hob.MemoryAllocation)) { + return PrintInvalidHob (HobStart, HobLength); + } + + DEBUG ((DEBUG_INFO, " Type = EFI_HOB_TYPE_MEMORY_ALLOCATION\n")); + } + + DEBUG ((DEBUG_INFO, " Name = %g\n", &Hob.MemoryAllocationStack->AllocDescriptor.Name)); + DEBUG ((DEBUG_INFO, " MemoryBaseAddress = 0x%lx\n", Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress)); + DEBUG ((DEBUG_INFO, " MemoryLength = 0x%lx\n", Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength)); + DEBUG ((DEBUG_INFO, " MemoryType = %a \n", mMemoryTypeStr[Hob.MemoryAllocationStack->AllocDescriptor.MemoryType])); + return EFI_SUCCESS; +} + +/** + Print the information in Resource Discriptor Hob. + @param[in] HobStart A pointer to HOB of type EFI_HOB_TYPE_RESOURCE_DESCRIPTOR. + @param[in] HobLength The Length in bytes of HOB of type EFI_HOB_TYPE_RESOURCE_DESCRIPTOR. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintResourceDiscriptorHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.ResourceDescriptor)); + + DEBUG ((DEBUG_INFO, " ResourceType = %a\n", mResource_Type_List[Hob.ResourceDescriptor->ResourceType])); + if (!IsZeroGuid (&Hob.ResourceDescriptor->Owner)) { + DEBUG ((DEBUG_INFO, " Owner = %g\n", &Hob.ResourceDescriptor->Owner)); + } + + DEBUG ((DEBUG_INFO, " ResourceAttribute = 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute)); + DEBUG ((DEBUG_INFO, " PhysicalStart = 0x%lx\n", Hob.ResourceDescriptor->PhysicalStart)); + DEBUG ((DEBUG_INFO, " ResourceLength = 0x%lx\n", Hob.ResourceDescriptor->ResourceLength)); + return EFI_SUCCESS; +} + +/** + Print the Guid Hob using related print handle function. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_GUID_EXTENSION. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_GUID_EXTENSION. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintGuidHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINT16 DataLength; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.Guid)); + + DataLength = GET_GUID_HOB_DATA_SIZE (Hob.Raw); + + DEBUG ((DEBUG_INFO, " Name = %g\n", &Hob.Guid->Name)); + DEBUG ((DEBUG_INFO, " DataLength = 0x%x\n", DataLength)); + PrintHex (DEBUG_VERBOSE, GET_GUID_HOB_DATA (Hob.Raw), DataLength); + return EFI_SUCCESS; +} + +/** + Print the information in FV Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintFvHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume)); + + DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume->BaseAddress)); + DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume->Length)); + return EFI_SUCCESS; +} + +/** + Print the information in Cpu Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_CPU. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_CPU. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintCpuHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.Cpu)); + + DEBUG ((DEBUG_INFO, " SizeOfMemorySpace = 0x%lx\n", Hob.Cpu->SizeOfMemorySpace)); + DEBUG ((DEBUG_INFO, " SizeOfIoSpace = 0x%lx\n", Hob.Cpu->SizeOfIoSpace)); + return EFI_SUCCESS; +} + +/** + Print the information in MemoryPoolHob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_MEMORY_POOL. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_MEMORY_POOL. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintMemoryPoolHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + UINT16 AllocationSize; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.Pool)); + + AllocationSize = HobLength - sizeof (EFI_HOB_GENERIC_HEADER); + DEBUG ((DEBUG_INFO, " AllocationSize = 0x%lx\n", AllocationSize)); + + PrintHex (DEBUG_VERBOSE, Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER), AllocationSize); + + return EFI_SUCCESS; +} + +/** + Print the information in Fv2Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV2. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV2. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintFv2Hob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume2)); + + DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume2->BaseAddress)); + DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume2->Length)); + DEBUG ((DEBUG_INFO, " FvName = %g\n", &Hob.FirmwareVolume2->FvName)); + DEBUG ((DEBUG_INFO, " FileName = %g\n", &Hob.FirmwareVolume2->FileName)); + return EFI_SUCCESS; +} + +/** + Print the information in Capsule Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_UEFI_CAPSULE. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_UEFI_CAPSULE. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintCapsuleHob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.Capsule)); + + DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.Capsule->BaseAddress)); + DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.Capsule->Length)); + return EFI_SUCCESS; +} + +/** + Print the information in Fv3 Hob. + @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV3. + @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV3. + @retval EFI_SUCCESS If it completed successfully. +**/ +EFI_STATUS +PrintFv3Hob ( + IN VOID *HobStart, + IN UINT16 HobLength + ) +{ + EFI_PEI_HOB_POINTERS Hob; + + Hob.Raw = (UINT8 *)HobStart; + ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume3)); + + DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume3->BaseAddress)); + DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume3->Length)); + DEBUG ((DEBUG_INFO, " AuthenticationStatus = 0x%x\n", Hob.FirmwareVolume3->AuthenticationStatus)); + DEBUG ((DEBUG_INFO, " ExtractedFv = %a\n", (Hob.FirmwareVolume3->ExtractedFv ? "True" : "False"))); + DEBUG ((DEBUG_INFO, " FvName = %g\n", &Hob.FirmwareVolume3->FvName)); + DEBUG ((DEBUG_INFO, " FileName = %g\n", &Hob.FirmwareVolume3->FileName)); + return EFI_SUCCESS; +} + +// +// Mapping table from Hob type to Hob print function. +// +HOB_PRINT_HANDLER_TABLE mHobHandles[] = { + { EFI_HOB_TYPE_HANDOFF, "EFI_HOB_TYPE_HANDOFF", PrintHandOffHob }, + { EFI_HOB_TYPE_MEMORY_ALLOCATION, "EFI_HOB_TYPE_MEMORY_ALLOCATION", PrintMemoryAllocationHob }, + { EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR", PrintResourceDiscriptorHob }, + { EFI_HOB_TYPE_GUID_EXTENSION, "EFI_HOB_TYPE_GUID_EXTENSION", PrintGuidHob }, + { EFI_HOB_TYPE_FV, "EFI_HOB_TYPE_FV", PrintFvHob }, + { EFI_HOB_TYPE_CPU, "EFI_HOB_TYPE_CPU", PrintCpuHob }, + { EFI_HOB_TYPE_MEMORY_POOL, "EFI_HOB_TYPE_MEMORY_POOL", PrintMemoryPoolHob }, + { EFI_HOB_TYPE_FV2, "EFI_HOB_TYPE_FV2", PrintFv2Hob }, + { EFI_HOB_TYPE_UEFI_CAPSULE, "EFI_HOB_TYPE_UEFI_CAPSULE", PrintCapsuleHob }, + { EFI_HOB_TYPE_FV3, "EFI_HOB_TYPE_FV3", PrintFv3Hob } +}; + +/** + Print all HOBs info from the HOB list. + + @param[in] HobStart A pointer to the HOB list. + @param[in] PrintHandler A custom handler to print HOB info. + +**/ +VOID +EFIAPI +PrintHobList ( + IN CONST VOID *HobStart, + IN HOB_PRINT_HANDLER PrintHandler + ) +{ + EFI_STATUS Status; + EFI_PEI_HOB_POINTERS Hob; + UINTN Count; + UINTN Index; + + ASSERT (HobStart != NULL); + + Hob.Raw = (UINT8 *)HobStart; + DEBUG ((DEBUG_INFO, "Print all Hob information from Hob 0x%p\n", Hob.Raw)); + + Status = EFI_SUCCESS; + Count = 0; + // + // Parse the HOB list to see which type it is, and print the information. + // + while (!END_OF_HOB_LIST (Hob)) { + // + // Print HOB generic information + // + for (Index = 0; Index < ARRAY_SIZE (mHobHandles); Index++) { + if (Hob.Header->HobType == mHobHandles[Index].Type) { + DEBUG ((DEBUG_INFO, "HOB[%d]: Type = %a, Offset = 0x%p, Length = 0x%x\n", Count, mHobHandles[Index].Name, (Hob.Raw - (UINT8 *)HobStart), Hob.Header->HobLength)); + break; + } + } + + if (Index == ARRAY_SIZE (mHobHandles)) { + DEBUG ((DEBUG_INFO, "HOB[%d]: Type = %d, Offset = 0x%p, Length = 0x%x\n", Count, Hob.Header->HobType, (Hob.Raw - (UINT8 *)HobStart), Hob.Header->HobLength)); + } + + // + // Process custom HOB print handler first + // + if (PrintHandler != NULL) { + Status = PrintHandler (Hob.Raw, Hob.Header->HobLength); + } + + // + // Process internal HOB print handler + // + if ((PrintHandler == NULL) || EFI_ERROR (Status)) { + if (Index < ARRAY_SIZE (mHobHandles)) { + mHobHandles[Index].PrintHandler (Hob.Raw, Hob.Header->HobLength); + } else { + DEBUG ((DEBUG_INFO, " Unkown Hob type, full hex dump in below:\n")); + PrintHex (DEBUG_INFO, Hob.Raw, Hob.Header->HobLength); + } + } + + Count++; + Hob.Raw = GET_NEXT_HOB (Hob); + } + + DEBUG ((DEBUG_INFO, "There are totally %d Hobs, the End Hob address is %p\n", Count, Hob.Raw)); +} diff --git a/MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf new file mode 100644 index 0000000000..a88cabf67d --- /dev/null +++ b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf @@ -0,0 +1,34 @@ +## @file +# Library class that prints all HOBs. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = HobPrintLib + FILE_GUID = 6b6f69c4-4272-4e8f-9c7f-747e7eed3ba8 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = HobPrintLib + +[Sources] + HobPrintLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + HobLib + +[Guids] + gEfiHobMemoryAllocBspStoreGuid + gEfiHobMemoryAllocStackGuid + gEfiMemoryTypeInformationGuid diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index bf9009641f..30cf4185a4 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -402,6 +402,7 @@ MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf MdeModulePkg/Library/DisplayUpdateProgressLibText/DisplayUpdateProgressLibText.inf MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf + MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf MdeModulePkg/Library/AdvLoggerAccessLibNull/AdvLoggerAccessLib.inf # MU_CHANGE MdeModulePkg/Universal/BdsDxe/BdsDxe.inf