/** @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)); }