audk/MdeModulePkg/Library/HobPrintLib/HobPrintLib.c

470 lines
16 KiB
C

/** @file
Prints all the HOBs.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Uefi.h>
#include <Pi/PiMultiPhase.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/HobPrintLib.h>
#include <Guid/MemoryTypeInformation.h>
#include <Guid/MemoryAllocationHob.h>
#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));
}