* Re: [edk2-devel] [PATCH v3 5/6] UefiPayloadPkg: Add FDT Paser relative LIBs.
2024-05-24 4:14 [edk2-devel] [PATCH v3 5/6] UefiPayloadPkg: Add FDT Paser relative LIBs Linus Liu
@ 2024-05-29 20:25 ` Chiu, Chasel
0 siblings, 0 replies; 2+ messages in thread
From: Chiu, Chasel @ 2024-05-29 20:25 UTC (permalink / raw)
To: Liu, Linus, devel@edk2.groups.io
Cc: Lin, Benny, Guo, Gua, Lu, James, Dhaval Sharma, Dong, Guo
Hi Linus,
Some comments below inline.
Thanks,
Chasel
> -----Original Message-----
> From: Liu, Linus <linus.liu@intel.com>
> Sent: Thursday, May 23, 2024 9:14 PM
> To: devel@edk2.groups.io
> Cc: Lin, Benny <benny.lin@intel.com>; Guo, Gua <gua.guo@intel.com>; Chiu,
> Chasel <chasel.chiu@intel.com>; Lu, James <james.lu@intel.com>; Dhaval
> Sharma <dhaval@rivosinc.com>
> Subject: [PATCH v3 5/6] UefiPayloadPkg: Add FDT Paser relative LIBs.
>
> Add FDTParser and CustomFdtNodePaser
> to retrive all FDT node and create the relate hobs.
>
> Cc: Benny Lin <benny.lin@intel.com>
> Cc: Gua Guo <gua.guo@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: James Lu <james.lu@intel.com>
> Cc: Dhaval Sharma <dhaval@rivosinc.com>
>
> Signed-off-by: Linus Liu <linus.liu@intel.com>
> ---
> UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c
> | 158 +++++
>
> UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNul
> lLib.c | 51 ++
> UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c | 622
> ++++++++++++++++++++
> UefiPayloadPkg/Library/HobParseLib/HobParseLib.c | 408
> +++++++++++++
> UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf
> | 46 ++
>
> UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNul
> lLib.inf | 33 ++
> UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf | 63 ++
> UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf | 40 ++
> 8 files changed, 1421 insertions(+)
>
> diff --git
> a/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c
> b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c
> new file mode 100644
> index 000000000000..d1376d21c5dd
> --- /dev/null
> +++
> b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c
> @@ -0,0 +1,158 @@
> +/** @file
>
> + Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +**/
>
> +#include <PiPei.h>
>
> +#include <Pi/PiHob.h>
>
> +#include <Library/BaseLib.h>
>
> +#include <Library/BaseMemoryLib.h>
>
> +#include <Library/MemoryAllocationLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/IoLib.h>
>
> +#include <Library/PrintLib.h>
>
> +#include <Library/FdtLib.h>
>
> +#include <Library/HobLib.h>
>
> +#include <Library/PcdLib.h>
>
> +
>
> +/**
>
> + Add a new HOB to the HOB List.
>
> +
>
> + @param HobType Type of the new HOB.
>
> + @param HobLength Length of the new HOB to allocate.
>
> +
>
> + @return NULL if there is no space to create a hob.
>
> + @return The address point to the new created hob.
>
> +
>
> +**/
>
> +VOID *
>
> +EFIAPI
>
> +CreateHob (
>
> + IN UINT16 HobType,
>
> + IN UINT16 HobLength
>
> + );
>
> +
>
> +/**
>
> + Add HOB into HOB list
>
> + @param[in] Hob The HOB to be added into the HOB list.
>
> +**/
>
> +VOID
>
> +AddNewHob (
>
> + IN EFI_PEI_HOB_POINTERS *Hob
>
> + );
>
> +
>
> +/**
>
> + Check the HOB and decide if it is need inside Payload
>
> + Payload maintainer may make decision which HOB is need or needn't
>
> + Then add the check logic in the function.
>
> + @param[in] Hob The HOB to check
>
> + @retval TRUE If HOB is need inside Payload
>
> + @retval FALSE If HOB is needn't inside Payload
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +FitIsHobNeed (
>
> + EFI_PEI_HOB_POINTERS Hob
>
> + )
>
> +{
>
> + if (FixedPcdGetBool (PcdHandOffFdtEnable)) {
>
> + if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) {
>
> + return FALSE;
>
> + }
>
> +
>
> + if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
>
> + if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name,
> &gUniversalPayloadDeviceTreeGuid)) {
>
> + return FALSE;
>
> + }
>
> +
>
> + if (CompareGuid (&Hob.MemoryAllocationModule-
> >MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
>
> + return FALSE;
>
> + }
>
> +
>
> + if ((Hob.MemoryAllocation->AllocDescriptor.MemoryType ==
> EfiReservedMemoryType) ||
>
> + (Hob.MemoryAllocation->AllocDescriptor.MemoryType ==
> EfiBootServicesCode) ||
>
> + (Hob.MemoryAllocation->AllocDescriptor.MemoryType ==
> EfiBootServicesData) ||
>
> + (Hob.MemoryAllocation->AllocDescriptor.MemoryType ==
> EfiRuntimeServicesCode) ||
>
> + (Hob.MemoryAllocation->AllocDescriptor.MemoryType ==
> EfiRuntimeServicesData) ||
>
> + (Hob.MemoryAllocation->AllocDescriptor.MemoryType ==
> EfiACPIReclaimMemory) ||
>
> + (Hob.MemoryAllocation->AllocDescriptor.MemoryType ==
> EfiACPIMemoryNVS))
>
> + {
>
> + return FALSE;
>
> + }
>
> + }
>
> +
>
> + if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
>
> + if (CompareGuid (&Hob.Guid->Name,
> &gUniversalPayloadSerialPortInfoGuid)) {
>
> + return FALSE;
>
> + }
>
> +
>
> + if (CompareGuid (&Hob.Guid->Name, &gUniversalPayloadAcpiTableGuid)) {
>
> + return FALSE;
>
> + }
>
> +
>
> + if (CompareGuid (&Hob.Guid->Name,
> &gUniversalPayloadPciRootBridgeInfoGuid)) {
>
> + return FALSE;
>
> + }
>
> + }
>
> + }
>
> +
>
> + // Arrive here mean the HOB is need
>
> + return TRUE;
>
> +}
>
> +
>
> +/**
>
> + It will Parse FDT -custom node based on information from bootloaders.
>
> + @param[in] FdtBase The starting memory address of FdtBase
>
> + @param[in] HobList The starting memory address of New Hob list.
>
> +
>
> +**/
>
> +UINTN
>
> +EFIAPI
>
> +CustomFdtNodeParser (
>
> + IN VOID *FdtBase,
>
> + IN VOID *HobList
>
> + )
>
> +{
>
> + INT32 Node, CustomNode;
>
> + INT32 TempLen;
>
> + UINT64 *Data64;
>
> + UINTN CHobList;
>
> + CONST FDT_PROPERTY *PropertyPtr;
>
> + EFI_PEI_HOB_POINTERS Hob;
>
> +
>
> + CHobList = (UINTN)HobList;
>
> +
>
> + DEBUG ((DEBUG_INFO, "%a() #1 \n", __func__));
>
> +
>
> + //
>
> + // Look for if exists hob list node
>
> + //
>
> + Node = FdtSubnodeOffsetNameLen (FdtBase, 0, "options", (INT32)AsciiStrLen
> ("options"));
>
> + if (Node > 0) {
>
> + DEBUG ((DEBUG_INFO, " Found options node (%08X)", Node));
>
> + CustomNode = FdtSubnodeOffsetNameLen (FdtBase, Node, "upl-custom",
> (INT32)AsciiStrLen ("upl-custom"));
>
> + if (CustomNode > 0) {
>
> + DEBUG ((DEBUG_INFO, " Found upl-custom node (%08X)", CustomNode));
>
> + PropertyPtr = FdtGetProperty (FdtBase, CustomNode, "hoblistptr",
> &TempLen);
>
> + Data64 = (UINT64 *)(PropertyPtr->Data);
>
> + CHobList = (UINTN)Fdt64ToCpu (*Data64);
>
> + DEBUG ((DEBUG_INFO, " Found hob list node (%08X)", CustomNode));
>
> + DEBUG ((DEBUG_INFO, " -pointer %016lX\n", CHobList));
>
> + }
>
> + }
>
> +
>
> + Hob.Raw = (UINT8 *)CHobList;
>
> +
>
> + //
>
> + // Since payload created new Hob, move all hobs except PHIT from boot loader
> hob list.
>
> + //
>
> + while (!END_OF_HOB_LIST (Hob)) {
>
> + if (FitIsHobNeed (Hob)) {
>
> + // Add this hob to payload HOB
>
> + AddNewHob (&Hob);
>
> + }
>
> +
>
> + Hob.Raw = GET_NEXT_HOB (Hob);
>
> + }
>
> +
>
> + return CHobList;
>
> +}
>
> diff --git
> a/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserN
> ullLib.c
> b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserN
> ullLib.c
> new file mode 100644
> index 000000000000..0012162fa0d2
> --- /dev/null
> +++
> b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserN
> ullLib.c
> @@ -0,0 +1,51 @@
> +/** @file
>
> + Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +**/
>
> +#include <PiPei.h>
>
> +#include <Library/BaseLib.h>
>
> +#include <Library/BaseMemoryLib.h>
>
> +#include <Library/MemoryAllocationLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/IoLib.h>
>
> +
>
> +#include <Library/PrintLib.h>
>
> +#include <Library/FdtLib.h>
>
> +
>
> +/**
>
> + Check the HOB and decide if it is need inside Payload
>
> + Payload maintainer may make decision which HOB is need or needn't
>
> + Then add the check logic in the function.
>
> + @param[in] Hob The HOB to check
>
> + @retval TRUE If HOB is need inside Payload
>
> + @retval FALSE If HOB is needn't inside Payload
>
> +**/
>
> +BOOLEAN
>
> +FitIsHobNeed (
>
> + EFI_PEI_HOB_POINTERS Hob
>
> + )
>
> +{
>
> + return FALSE;
>
> +}
>
> +
>
> +/**
>
> + It will Parse FDT -custom node based on information from bootloaders.
>
> + @param[in] FdtBase The starting memory address of FdtBase.
>
> + @param[in] HobList The starting memory address of New Hob list.
>
> + @retval HobList The base address of Hoblist.
>
> +
>
> +**/
>
> +UINTN
>
> +CustomFdtNodeParser (
>
> + IN VOID *Fdt,
>
> + IN VOID *HobList
>
> + )
>
> +{
>
> + UINTN CHobList;
>
> +
>
> + if (HobList != NULL) {
>
> + CHobList = (UINTN)HobList;
>
> + }
>
> +
>
> + return CHobList;
>
> +}
>
> diff --git a/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c
> b/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c
> new file mode 100644
> index 000000000000..c18e36661438
> --- /dev/null
> +++ b/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c
> @@ -0,0 +1,622 @@
> +/** @file
>
> + Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +**/
>
> +
>
> +#include <PiPei.h>
>
> +#include <Library/BaseLib.h>
>
> +#include <Library/BaseMemoryLib.h>
>
> +#include <Library/MemoryAllocationLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/HobLib.h>
>
> +#include <Library/PcdLib.h>
>
> +#include <Library/IoLib.h>
>
> +#include <Guid/MemoryAllocationHob.h>
>
> +#include <Guid/DebugPrintErrorLevel.h>
>
> +#include <Guid/SerialPortInfoGuid.h>
>
> +#include <Guid/MemoryMapInfoGuid.h>
>
> +#include <Guid/AcpiBoardInfoGuid.h>
>
> +#include <Guid/GraphicsInfoHob.h>
>
> +#include <Guid/UniversalPayloadBase.h>
>
> +#include <UniversalPayload/SmbiosTable.h>
>
> +#include <UniversalPayload/AcpiTable.h>
>
> +#include <UniversalPayload/UniversalPayload.h>
>
> +#include <UniversalPayload/ExtraData.h>
>
> +#include <UniversalPayload/SerialPortInfo.h>
>
> +#include <UniversalPayload/DeviceTree.h>
>
> +#include <UniversalPayload/PciRootBridges.h>
>
> +#include <IndustryStandard/SmBios.h>
>
> +#include <Library/PrintLib.h>
>
> +#include <Library/FdtLib.h>
>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
>
> +#include <Protocol/PciIo.h>
>
> +
>
> +#define MEMORY_ATTRIBUTE_DEFAULT
> (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
>
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
>
> + EFI_RESOURCE_ATTRIBUTE_TESTED | \
>
> + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | \
>
> + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | \
>
> +
> EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | \
>
> + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE )
>
> +
>
> +#define ROOT_BRIDGE_SUPPORTS_DEFAULT
> (EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | \
>
> + EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | \
>
> + EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 | \
>
> + EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | \
>
> + EFI_PCI_IO_ATTRIBUTE_VGA_IO | \
>
> + EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | \
>
> + EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | \
>
> + EFI_PCI_IO_ATTRIBUTE_ISA_IO | \
>
> + EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO )
>
> +
>
> +extern VOID *mHobList;
>
> +
>
> +/**
>
> + Build ACPI board info HOB using infomation from ACPI table
>
> +
>
> + @param AcpiTableBase ACPI table start address in memory
>
> +
>
> + @retval A pointer to ACPI board HOB ACPI_BOARD_INFO. Null if build HOB
> failure.
>
> +**/
>
> +ACPI_BOARD_INFO *
>
> +BuildHobFromAcpi (
>
> + IN UINT64 AcpiTableBase
>
> + );
>
> +
>
> +/**
>
> + Build a Handoff Information Table HOB
>
> +
>
> + This function initialize a HOB region from EfiMemoryBegin to
>
> + EfiMemoryTop. And EfiFreeMemoryBottom and EfiFreeMemoryTop should
>
> + be inside the HOB region.
>
> +
>
> + @param[in] EfiMemoryBottom Total memory start address
>
> + @param[in] EfiMemoryTop Total memory end address.
>
> + @param[in] EfiFreeMemoryBottom Free memory start address
>
> + @param[in] EfiFreeMemoryTop Free memory end address.
>
> +
>
> + @return The pointer to the handoff HOB table.
>
> +
>
> +**/
>
> +EFI_HOB_HANDOFF_INFO_TABLE *
>
> +EFIAPI
>
> +HobConstructor (
>
> + IN VOID *EfiMemoryBottom,
>
> + IN VOID *EfiMemoryTop,
>
> + IN VOID *EfiFreeMemoryBottom,
>
> + IN VOID *EfiFreeMemoryTop
>
> + );
>
> +
>
> +/**
>
> + It will parse FDT based on DTB from bootloaders.
>
> +
>
> + @param[in] FdtBase Address of the Fdt data.
>
> +
>
> + @return The address to the new hob list
>
> +**/
>
> +UINTN
>
> +EFIAPI
>
> +ParseDtb (
>
> + IN VOID *FdtBase
>
> + )
>
> +{
>
> + VOID *Fdt;
>
> + INT32 Node;
>
> + INT32 Property;
>
> + INT32 Depth;
>
> + FDT_NODE_HEADER *NodePtr;
>
> + CONST FDT_PROPERTY *PropertyPtr;
>
> + CONST CHAR8 *TempStr;
>
> + INT32 TempLen;
>
> + UINT32 *Data32;
>
> + UINT64 *Data64;
>
> + UINT64 StartAddress;
>
> + INT32 SubNode;
>
> + UINT64 NumberOfBytes;
>
> + UINT32 Attribute;
>
> + UINT8 ECCAttribute;
>
> + UINT32 ECCData, ECCData2;
>
> + UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *Serial;
>
> + UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo;
>
> + UNIVERSAL_PAYLOAD_ACPI_TABLE *PlatformAcpiTable;
>
> + UNIVERSAL_PAYLOAD_SMBIOS_TABLE *SmbiosTable;
>
> + UEFI_PAYLOAD_DEBUG_PRINT_ERROR_LEVEL *DebugPrintErrorLevelInfo;
>
> + UNIVERSAL_PAYLOAD_BASE *PayloadBase;
>
> + EFI_PEI_GRAPHICS_INFO_HOB *GraphicsInfo;
>
> + EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *GraphicsDev;
>
> + UINT8 SizeOfMemorySpace;
>
> + UINT64 FrameBufferBase;
>
> + UINT64 FrameBufferSize;
>
> + UINTN MinimalNeededSize;
>
> + EFI_PHYSICAL_ADDRESS FreeMemoryBottom;
>
> + EFI_PHYSICAL_ADDRESS FreeMemoryTop;
>
> + EFI_PHYSICAL_ADDRESS MemoryBottom;
>
> + EFI_PHYSICAL_ADDRESS MemoryTop;
>
> + BOOLEAN IsHobConstructed;
>
> + UINTN NewHobList;
>
> + UINT8 RootBridgeCount;
>
> + UINT8 index;
>
> + UINTN HobDataSize;
>
> +
>
> + Fdt = FdtBase;
>
> + Depth = 0;
>
> + FrameBufferBase = 0;
>
> + FrameBufferSize = 0;
>
> + MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
>
> + IsHobConstructed = FALSE;
>
> + NewHobList = 0;
>
> + PlatformAcpiTable = NULL;
>
> + SmbiosTable = NULL;
>
> + PciRootBridgeInfo = NULL;
>
> + RootBridgeCount = 0;
>
> + index = 1;
>
> + HobDataSize = 0;
>
> +
>
> + DEBUG ((DEBUG_INFO, "FDT = 0x%x %x\n", Fdt, Fdt32ToCpu (*((UINT32
> *)Fdt))));
>
> + DEBUG ((DEBUG_INFO, "Start parsing DTB data\n"));
>
> + DEBUG ((DEBUG_INFO, "MinimalNeededSize :%x\n", MinimalNeededSize));
>
> +
>
> + for (Node = FdtNextNode (Fdt, 0, &Depth); Node >= 0; Node = FdtNextNode
> (Fdt, Node, &Depth)) {
>
> + if (Depth != 1) {
>
> + continue;
>
> + }
>
> +
>
> + NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + Node + Fdt32ToCpu
> (((FDT_HEADER *)Fdt)->OffsetDtStruct));
>
> + DEBUG ((DEBUG_INFO, "\n Node(%08x) %a Depth %x", Node, NodePtr-
> >Name, Depth));
>
> + // memory node
>
> + if (AsciiStrnCmp (NodePtr->Name, "memory@", AsciiStrLen ("memory@")) ==
> 0) {
>
> + for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property =
> FdtNextPropertyOffset (Fdt, Property)) {
>
> + PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
>
> + TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset),
> NULL);
>
> + if (AsciiStrCmp (TempStr, "reg") == 0) {
>
> + Data64 = (UINT64 *)(PropertyPtr->Data);
>
> + StartAddress = Fdt64ToCpu (*Data64);
>
> + NumberOfBytes = Fdt64ToCpu (*(Data64 + 1));
>
> + DEBUG ((DEBUG_INFO, "\n Property(%08X) %a", Property, TempStr));
>
> + DEBUG ((DEBUG_INFO, " %016lX %016lX", StartAddress,
> NumberOfBytes));
>
> + if (!IsHobConstructed) {
>
> + if ((NumberOfBytes > MinimalNeededSize) && (StartAddress <
> BASE_4GB)) {
>
> + MemoryBottom = StartAddress + NumberOfBytes -
> MinimalNeededSize;
>
> + FreeMemoryBottom = MemoryBottom;
>
> + FreeMemoryTop = StartAddress + NumberOfBytes;
>
> + MemoryTop = FreeMemoryTop;
>
> +
>
> + DEBUG ((DEBUG_INFO, "MemoryBottom :0x%llx\n", MemoryBottom));
>
> + DEBUG ((DEBUG_INFO, "FreeMemoryBottom :0x%llx\n",
> FreeMemoryBottom));
>
> + DEBUG ((DEBUG_INFO, "FreeMemoryTop :0x%llx\n", FreeMemoryTop));
>
> + DEBUG ((DEBUG_INFO, "MemoryTop :0x%llx\n", MemoryTop));
>
> + mHobList = HobConstructor ((VOID *)(UINTN)MemoryBottom,
> (VOID *)(UINTN)MemoryTop, (VOID *)(UINTN)FreeMemoryBottom, (VOID
> *)(UINTN)FreeMemoryTop);
>
> + IsHobConstructed = TRUE;
>
> + NewHobList = (UINTN)mHobList;
>
> + break;
>
> + }
>
> + }
>
> + }
>
> + }
>
> + } // end of memory node
>
> + else if (AsciiStrnCmp (NodePtr->Name, "pci-rb", AsciiStrLen ("pci-rb")) == 0) {
>
> + RootBridgeCount++;
>
> + }
>
> + }
>
> +
>
> + Depth = 0;
>
> + for (Node = FdtNextNode (Fdt, 0, &Depth); Node >= 0; Node = FdtNextNode
> (Fdt, Node, &Depth)) {
>
> + if (Depth != 1) {
>
> + continue;
>
> + }
>
> +
>
> + NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + Node + Fdt32ToCpu
> (((FDT_HEADER *)Fdt)->OffsetDtStruct));
>
> + DEBUG ((DEBUG_INFO, "\n Node(%08x) %a Depth %x", Node, NodePtr-
> >Name, Depth));
>
> +
>
> + // memory node
>
> + if (AsciiStrnCmp (NodePtr->Name, "memory@", AsciiStrLen ("memory@")) ==
> 0) {
>
> + Attribute = MEMORY_ATTRIBUTE_DEFAULT;
>
> + ECCAttribute = 0;
>
> + ECCData = ECCData2 = 0;
>
> + for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property =
> FdtNextPropertyOffset (Fdt, Property)) {
>
> + PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
>
> + TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset),
> NULL);
>
> + if (AsciiStrCmp (TempStr, "reg") == 0) {
>
> + Data64 = (UINT64 *)(PropertyPtr->Data);
>
> + StartAddress = Fdt64ToCpu (*Data64);
>
> + NumberOfBytes = Fdt64ToCpu (*(Data64 + 1));
>
> + } else if (AsciiStrCmp (TempStr, "ecc-detection-bits") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + ECCData = Fdt32ToCpu (*Data32);
>
> + } else if (AsciiStrCmp (TempStr, "ecc-correction-bits") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + ECCData2 = Fdt32ToCpu (*Data32);
>
> + }
>
> + }
>
> +
>
> + if (ECCData == ECCData2) {
>
> + if (ECCData == 1) {
>
> + ECCAttribute = EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC;
>
> + } else if (ECCData == 2) {
>
> + ECCAttribute = EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC;
>
> + }
>
> + }
>
> +
>
> + if (ECCAttribute != 0) {
>
> + Attribute |= ECCAttribute;
>
> + }
>
> +
>
> + BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attribute,
> StartAddress, NumberOfBytes);
>
> + } // end of memory node
>
> + // reserved-memory
>
> + else if (AsciiStrCmp (NodePtr->Name, "reserved-memory") == 0) {
>
> + for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode =
> FdtNextSubnode (Fdt, SubNode)) {
>
> + NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode +
> Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
>
> + DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr-
> >Name));
>
> +
>
> + PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg", &TempLen);
>
> + ASSERT (TempLen > 0);
>
> + if (TempLen > 0) {
>
> + Data64 = (UINT64 *)(PropertyPtr->Data);
>
> + StartAddress = Fdt64ToCpu (*Data64);
>
> + NumberOfBytes = Fdt64ToCpu (*(Data64 + 1));
>
> + DEBUG ((DEBUG_INFO, "\n Property(%08X) %a", Property, TempStr));
>
> + DEBUG ((DEBUG_INFO, " %016lX %016lX", StartAddress,
> NumberOfBytes));
>
> + }
>
> +
>
> + if (AsciiStrnCmp (NodePtr->Name, "mmio@", AsciiStrLen ("mmio@")) == 0) {
>
> + DEBUG ((DEBUG_INFO, " MemoryMappedIO"));
>
> + BuildMemoryAllocationHob (StartAddress, NumberOfBytes,
> EfiMemoryMappedIO);
>
> + } else {
>
> + PropertyPtr = FdtGetProperty (Fdt, SubNode, "compatible", &TempLen);
>
> + if (!(TempLen > 0)) {
>
> + BuildMemoryAllocationHob (StartAddress, NumberOfBytes,
> EfiReservedMemoryType);
>
> + continue;
>
> + }
>
> +
>
> + TempStr = (CHAR8 *)(PropertyPtr->Data);
>
> +
>
> + if (AsciiStrnCmp (TempStr, "boot-code", AsciiStrLen ("boot-code")) == 0) {
>
> + DEBUG ((DEBUG_INFO, " boot-code"));
>
> + BuildMemoryAllocationHob (StartAddress, NumberOfBytes,
> EfiBootServicesCode);
>
> + } else if (AsciiStrnCmp (TempStr, "boot-data", AsciiStrLen ("boot-data")) ==
> 0) {
>
> + DEBUG ((DEBUG_INFO, " boot-data"));
>
> + BuildMemoryAllocationHob (StartAddress, NumberOfBytes,
> EfiBootServicesData);
>
> + } else if (AsciiStrnCmp (TempStr, "runtime-code", AsciiStrLen ("runtime-
> code")) == 0) {
>
> + DEBUG ((DEBUG_INFO, " runtime-code"));
>
> + BuildMemoryAllocationHob (StartAddress, NumberOfBytes,
> EfiRuntimeServicesCode);
>
> + } else if (AsciiStrnCmp (TempStr, "runtime-data", AsciiStrLen ("runtime-
> data")) == 0) {
>
> + DEBUG ((DEBUG_INFO, " runtime-data"));
>
> + BuildMemoryAllocationHob (StartAddress, NumberOfBytes,
> EfiRuntimeServicesData);
>
> + } else if (AsciiStrnCmp (TempStr, "acpi", AsciiStrLen ("acpi")) == 0) {
>
> + DEBUG ((DEBUG_INFO, " acpi, StartAddress:%x, NumberOfBytes:%x",
> StartAddress, NumberOfBytes));
>
> + BuildMemoryAllocationHob (StartAddress, NumberOfBytes,
> EfiBootServicesData);
>
> + PlatformAcpiTable = BuildGuidHob (&gUniversalPayloadAcpiTableGuid,
> sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE));
>
> + if (PlatformAcpiTable != NULL) {
>
> + DEBUG ((DEBUG_INFO, " build gUniversalPayloadAcpiTableGuid ,
> NumberOfBytes:%x", NumberOfBytes));
>
> + PlatformAcpiTable->Rsdp =
> (EFI_PHYSICAL_ADDRESS)(UINTN)StartAddress;
>
> + PlatformAcpiTable->Header.Revision =
> UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION;
>
> + PlatformAcpiTable->Header.Length = sizeof
> (UNIVERSAL_PAYLOAD_ACPI_TABLE);
>
> + }
>
> + } else if (AsciiStrnCmp (TempStr, "acpi-nvs", AsciiStrLen ("acpi-nvs")) == 0) {
>
> + DEBUG ((DEBUG_INFO, " acpi-nvs"));
>
> + BuildMemoryAllocationHob (StartAddress, NumberOfBytes,
> EfiACPIMemoryNVS);
>
> + } else if (AsciiStrnCmp (TempStr, "smbios", AsciiStrLen ("smbios")) == 0) {
>
> + DEBUG ((DEBUG_INFO, " build smbios, NumberOfBytes:%x",
> NumberOfBytes));
>
> + SmbiosTable = BuildGuidHob (&gUniversalPayloadSmbios3TableGuid,
> sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE) + sizeof
> (SMBIOS_TABLE_3_0_ENTRY_POINT));
>
> + if (SmbiosTable != NULL) {
>
> + SmbiosTable->Header.Revision =
> UNIVERSAL_PAYLOAD_SMBIOS_TABLE_REVISION;
>
> + SmbiosTable->Header.Length = sizeof
> (UNIVERSAL_PAYLOAD_SMBIOS_TABLE);
>
> + SmbiosTable->SmBiosEntryPoint =
> (EFI_PHYSICAL_ADDRESS)(UINTN)(&StartAddress);
>
> + }
>
> + }
>
> + }
>
> + }
>
> + } // end of reserved-memory
>
> +
>
> + if (AsciiStrnCmp (NodePtr->Name, "serial@", AsciiStrLen ("serial@")) == 0) {
>
> + //
>
> + // Create SerialPortInfo HOB.
>
> + //
>
> + Serial = BuildGuidHob (&gUniversalPayloadSerialPortInfoGuid, sizeof
> (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO));
>
> + ASSERT (Serial != NULL);
>
> + if (Serial == NULL) {
>
> + break;
>
> + }
>
> +
>
> + Serial->Header.Revision =
> UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO_REVISION;
>
> + Serial->Header.Length = sizeof
> (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO);
>
> + Serial->RegisterStride = 1;
>
> +
>
> + for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property =
> FdtNextPropertyOffset (Fdt, Property)) {
>
> + PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
>
> + TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset),
> NULL);
>
> + if (AsciiStrCmp (TempStr, "current-speed") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + DEBUG ((DEBUG_INFO, "\n Property(%08X) %a", Property, TempStr));
>
> + DEBUG ((DEBUG_INFO, " %X", Fdt32ToCpu (*Data32)));
>
> +
>
> + Serial->BaudRate = Fdt32ToCpu (*Data32);
>
> + } else if (AsciiStrCmp (TempStr, "reg") == 0) {
>
> + Data64 = (UINT64 *)(PropertyPtr->Data);
>
> + StartAddress = Fdt64ToCpu (*(Data64 + 1));
>
> + DEBUG ((DEBUG_INFO, "\n Property(%08X) %a", Property, TempStr));
>
> + DEBUG ((DEBUG_INFO, " %016lX", StartAddress));
>
> +
>
> + Serial->RegisterBase = StartAddress;
>
> + } else if (AsciiStrCmp (TempStr, "reg-io-width") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + DEBUG ((DEBUG_INFO, "\n Property(%08X) %a", Property, TempStr));
>
> + DEBUG ((DEBUG_INFO, " %X", Fdt32ToCpu (*Data32)));
>
> + Serial->UseMmio = Fdt32ToCpu (*(Data32)) == 4 ? TRUE : FALSE;
reg-io-width is reg data width, not reg base address width, so UPL has to rely on address-cells=3 to know base address type from the reg property.
Please help to correct this and we require address-cells=3 for those UPL consumed nodes which having reg or ranges properties.
>
> + }
>
> + }
>
> + } else if (AsciiStrCmp (NodePtr->Name, "graphic") == 0) {
>
> + //
>
> + // Create GraphicInfo HOB.
>
> + //
>
> + GraphicsInfo = BuildGuidHob (&gEfiGraphicsInfoHobGuid, sizeof
> (EFI_PEI_GRAPHICS_INFO_HOB));
>
> + ASSERT (GraphicsInfo != NULL);
>
> + if (GraphicsInfo == NULL) {
>
> + break;
>
> + }
>
> +
>
> + GraphicsDev = BuildGuidHob (&gEfiGraphicsDeviceInfoHobGuid, sizeof
> (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB));
>
> + ASSERT (GraphicsDev != NULL);
>
> + if (GraphicsDev == NULL) {
>
> + break;
>
> + }
>
> +
>
> + if (FrameBufferBase != 0) {
>
> + GraphicsInfo->FrameBufferBase = FrameBufferBase;
>
> + }
>
> +
>
> + if (FrameBufferSize != 0) {
>
> + GraphicsInfo->FrameBufferSize = (UINT32)FrameBufferSize;
>
> + }
>
> +
>
> + for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property =
> FdtNextPropertyOffset (Fdt, Property)) {
>
> + PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
>
> + TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset),
> NULL);
>
> + if (AsciiStrCmp (TempStr, "resolution") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + GraphicsInfo->GraphicsMode.HorizontalResolution = Fdt32ToCpu
> (*Data32);
>
> + GraphicsInfo->GraphicsMode.VerticalResolution = Fdt32ToCpu (*(Data32
> + 1));
>
> + } else if (AsciiStrCmp (TempStr, "pixel-format") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + GraphicsInfo->GraphicsMode.PixelFormat = Fdt32ToCpu (*Data32);
>
> + } else if (AsciiStrCmp (TempStr, "pixel-mask") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + GraphicsInfo->GraphicsMode.PixelInformation.RedMask = Fdt32ToCpu
> (*Data32);
>
> + GraphicsInfo->GraphicsMode.PixelInformation.GreenMask = Fdt32ToCpu
> (*(Data32 + 1));
>
> + GraphicsInfo->GraphicsMode.PixelInformation.BlueMask = Fdt32ToCpu
> (*(Data32 + 2));
>
> + } else if (AsciiStrCmp (TempStr, "pixe-scanline") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + GraphicsInfo->GraphicsMode.PixelsPerScanLine = Fdt32ToCpu (*Data32);
>
> + } else if (AsciiStrCmp (TempStr, "id") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + GraphicsDev->VendorId = Fdt32ToCpu (*Data32) >> 16;
>
> + GraphicsDev->DeviceId = Fdt32ToCpu (*Data32) & 0xffff;
>
> + } else if (AsciiStrCmp (TempStr, "subsystem-id") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + GraphicsDev->SubsystemVendorId = Fdt32ToCpu (*Data32) >> 16;
>
> + GraphicsDev->SubsystemId = Fdt32ToCpu (*Data32) & 0xffff;
>
> + } else if (AsciiStrCmp (TempStr, "revision-id") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + GraphicsDev->RevisionId = (UINT8)Fdt32ToCpu (*Data32);
>
> + } else if (AsciiStrCmp (TempStr, "bar-index") == 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + GraphicsDev->BarIndex = (UINT8)Fdt32ToCpu (*Data32);
>
> + }
>
Per UPL specification, 'graphic' node should be 'framebuffer' node, example as below:
1. Fill HOB frameBufferBase/Size by FDT framebuffer->reg
2. Fill HOB for X and Y:
GraphicsInfo->GraphicsMode.HorizontalResolution = framebuffer->width
GraphicsInfo->GraphicsMode.VerticalResolution = framebuffer->height
3. use framebuffer->format property to fill PixelFormat:
GraphicsInfo->GraphicsMode.PixelFormat : framebuffer->format:
PixelRedGreenBlueReserved8BitPerColor : 'a8r8g8b8'
PixelBlueGreenRedReserved8BitPerColor : 'a8b8g8r8'
PixelFormatMax (Unsupported by current UefiPayload) : 'a16b16g16r16'
4. HOB PixelInformation (BitMask) currently is not used by UPL, you may keep them as 0.
5. Fill HOB PixelsPerScanLine
GraphicsInfo->GraphicsMode.PixelsPerScanLine = framebuffer->stride
6. GraphicsDev HOB is for PCI GFX device only and all fields should be filled by "PCI GFX device node", which will be pointed by framebuffer->display. Below is example of PCI GFX node
rb@E0000000 {
compatible = "pci-host-ecam-generic";
reg = <...>
ranges = <...>;
gma@E0010000 {
/* gfx device 00:02:00 */
vendor-id = <0x8086>
device-id = <0x4680>
revision-id = <0x4>
subsystem-vendor-id = <0x8086>
subsystem-id = <0x2212>
};
};
};
framebuffer@b0000000 {
compatible = "simple-framebuffer";
reg = <0x82000000, 0x0, 0xb0000000, 0x400, 0x500000>; //base 0xB0000000, size=0x4000500000
width = <3840>;
height = <2160>;
format = "a8r8g8b8";
display = <&gma>;
};
Note1: GraphicsDev HOB default is all 0xFF, please SetMem() of this buffer to 0xFF before parsing FDT nodes.
Note2: GraphicsDev->BarIndex is not part of standard DT PCI binding, so leave it as default 0xFF.
> + }
>
> + } else if (AsciiStrCmp (NodePtr->Name, "options") == 0) {
>
> + DEBUG ((DEBUG_INFO, " Found options node (%08X)", Node));
>
> +
>
> + for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode =
> FdtNextSubnode (Fdt, SubNode)) {
>
> + NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode +
> Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
>
> + DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr-
> >Name));
>
> +
>
> + if (AsciiStrnCmp (NodePtr->Name, "upl-images@", AsciiStrLen ("upl-
> images@")) == 0) {
>
> + DEBUG ((DEBUG_INFO, " Found image@ node \n"));
>
> + //
>
> + // Build PayloadBase HOB .
>
> + //
>
> + PayloadBase = BuildGuidHob (&gUniversalPayloadBaseGuid, sizeof
> (UNIVERSAL_PAYLOAD_BASE));
>
> + ASSERT (PayloadBase != NULL);
>
> + if (PayloadBase == NULL) {
>
> + return EFI_OUT_OF_RESOURCES;
>
> + }
>
> +
>
> + PayloadBase->Header.Revision = UNIVERSAL_PAYLOAD_BASE_REVISION;
>
> + PayloadBase->Header.Length = sizeof (UNIVERSAL_PAYLOAD_BASE);
>
> +
>
> + PropertyPtr = FdtGetProperty (Fdt, SubNode, "addr", &TempLen);
>
> +
>
> + ASSERT (TempLen > 0);
>
> + if (TempLen > 0) {
>
> + Data64 = (UINT64 *)(PropertyPtr->Data);
>
> + StartAddress = Fdt64ToCpu (*Data64);
>
> + DEBUG ((DEBUG_INFO, "\n Property(00000000) entry"));
>
> + DEBUG ((DEBUG_INFO, " %016lX\n", StartAddress));
>
> +
>
> + PayloadBase->Entry = (EFI_PHYSICAL_ADDRESS)StartAddress;
>
> + }
>
> + }
>
> +
>
> + if (AsciiStrnCmp (NodePtr->Name, "upl-params", AsciiStrLen ("upl-params"))
> == 0) {
>
> + PropertyPtr = FdtGetProperty (Fdt, SubNode, "address_width", &TempLen);
>
> + if (TempLen > 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + DEBUG ((DEBUG_INFO, "\n Property(00000000) address_width"));
>
> + DEBUG ((DEBUG_INFO, " %X", Fdt32ToCpu (*Data32)));
>
> + SizeOfMemorySpace = (UINT8)Fdt32ToCpu (*Data32);
>
> + #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
>
> + BuildCpuHob (SizeOfMemorySpace, 16);
>
> + #else
>
> + BuildCpuHob (SizeOfMemorySpace, 0);
>
> + #endif
>
> + }
>
1. We also need to fill BootMode from FDT upl-params->BootMode:
convert upl-params->boot-mode string to bootmode_enum
(EFI_HOB_HANDOFF_INFO_TABLE) (UINTN) mHobList->BootMode = bootmode_enum;
2. UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES->ResourceAssigned HOB data should be filled by upl-params->pci-enum-done (when present, set to 1)
> + }
>
> + }
>
> + }
>
> + // Optional
>
> + else if (AsciiStrnCmp (NodePtr->Name, "pci-rb", AsciiStrLen ("pci-rb")) == 0) {
>
> + DEBUG ((DEBUG_INFO, " Found pci-rb node (%08X)", Node));
>
> +
>
> + HobDataSize = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES) +
> RootBridgeCount *sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE);
>
> + //
>
> + // Create PCI Root Bridge Info Hob.
>
> + //
>
> + if (PciRootBridgeInfo == NULL) {
>
> + PciRootBridgeInfo = BuildGuidHob
> (&gUniversalPayloadPciRootBridgeInfoGuid, HobDataSize);
>
> + ASSERT (PciRootBridgeInfo != NULL);
>
> + if (PciRootBridgeInfo == NULL) {
>
> + break;
>
> + }
>
> +
>
> + ZeroMem (PciRootBridgeInfo, HobDataSize);
>
> + PciRootBridgeInfo->Header.Length = sizeof
> (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES);
>
> + PciRootBridgeInfo->Header.Revision =
> UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION;
>
> + PciRootBridgeInfo->Count = RootBridgeCount;
>
> + PciRootBridgeInfo->ResourceAssigned = FALSE;
>
> + }
>
> +
>
> + for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property =
> FdtNextPropertyOffset (Fdt, Property)) {
>
> + PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
>
> + TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset),
> NULL);
>
> +
>
> + if (AsciiStrCmp (TempStr, "ranges") == 0) {
>
> + DEBUG ((DEBUG_INFO, " Found ranges Property TempLen (%08X)\n",
> TempLen));
>
> +
>
> + PciRootBridgeInfo->RootBridge[index].AllocationAttributes =
> EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |
> EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
>
> + PciRootBridgeInfo->RootBridge[index].Supports =
> ROOT_BRIDGE_SUPPORTS_DEFAULT;
>
> + PciRootBridgeInfo->RootBridge[index].PMemAbove4G.Base = PcdGet64
> (PcdPciReservedPMemAbove4GBBase);
>
> + PciRootBridgeInfo->RootBridge[index].PMemAbove4G.Limit = PcdGet64
> (PcdPciReservedPMemAbove4GBLimit);
>
> + PciRootBridgeInfo->RootBridge[index].PMem.Base = PcdGet32
> (PcdPciReservedPMemBase);
>
> + PciRootBridgeInfo->RootBridge[index].PMem.Limit = PcdGet32
> (PcdPciReservedPMemLimit);
>
> + PciRootBridgeInfo->RootBridge[index].UID = index;
>
> + PciRootBridgeInfo->RootBridge[index].HID = EISA_PNP_ID
> (0x0A03);
>
> +
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + PciRootBridgeInfo->RootBridge[index].Mem.Base = Fdt32ToCpu
> (*(Data32 + 2));
>
> + PciRootBridgeInfo->RootBridge[index].Mem.Limit = Fdt32ToCpu
> (*(Data32 + 6)) + Fdt32ToCpu (*(Data32 + 2)) -1;
>
> + PciRootBridgeInfo->RootBridge[index].MemAbove4G.Base = Fdt32ToCpu
> (*(Data32 + 9)) + LShiftU64 (Fdt32ToCpu (*(Data32 + 8)), 32);
>
> + PciRootBridgeInfo->RootBridge[index].MemAbove4G.Limit =
> PciRootBridgeInfo->RootBridge[index].MemAbove4G.Base + LShiftU64
> (Fdt32ToCpu (*(Data32 + 12)), 32) + Fdt32ToCpu (*(Data32 + 13)) -1;
>
> + PciRootBridgeInfo->RootBridge[index].Io.Base = Fdt32ToCpu
> (*(Data32 + 16));
>
> + PciRootBridgeInfo->RootBridge[index].Io.Limit = PciRootBridgeInfo-
> >RootBridge[index].Io.Base + Fdt32ToCpu (*(Data32 + 20)) -1;
>
> +
>
> + DEBUG ((DEBUG_INFO, "RootBridgeCount %x, index :%x\n",
> RootBridgeCount, index));
>
> +
>
> + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base %x, \n",
> PciRootBridgeInfo->RootBridge[index].Mem.Base));
>
> + DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.limit %x, \n",
> PciRootBridgeInfo->RootBridge[index].Mem.Limit));
>
> +
>
> + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base %llx, \n",
> PciRootBridgeInfo->RootBridge[index].MemAbove4G.Base));
>
> + DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.limit %llx, \n",
> PciRootBridgeInfo->RootBridge[index].MemAbove4G.Limit));
>
> +
>
> + DEBUG ((DEBUG_INFO, "PciRootBridge->Io.Base %llx, \n",
> PciRootBridgeInfo->RootBridge[index].Io.Base));
>
> + DEBUG ((DEBUG_INFO, "PciRootBridge->Io.limit %llx, \n",
> PciRootBridgeInfo->RootBridge[index].Io.Limit));
>
> + if (index > 0) {
>
> + index--;
>
> + }
>
> + }
>
> +
>
> + if (AsciiStrCmp (TempStr, "bus-range") == 0) {
>
> + UINT16 *Data16;
>
> +
>
> + DEBUG ((DEBUG_INFO, " Found bus-range Property TempLen (%08X)\n",
> TempLen));
>
> +
>
> + if (RootBridgeCount == 1) {
>
> + index = 0;
>
> + }
>
> +
>
> + Data16 = (UINT16 *)(PropertyPtr->Data);
>
> + PciRootBridgeInfo->RootBridge[index].Bus.Base = Fdt16ToCpu
> (*Data16) & 0xFF;
>
> + PciRootBridgeInfo->RootBridge[index].Bus.Limit = Fdt16ToCpu
> (*(Data16 + 1)) & 0xFF;
>
> + PciRootBridgeInfo->RootBridge[index].Bus.Translation = 0;
>
> +
>
> + DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.Base %x, \n",
> PciRootBridgeInfo->RootBridge[index].Bus.Base));
>
> + DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.limit %x, \n",
> PciRootBridgeInfo->RootBridge[index].Bus.Limit));
>
> + }
>
> + }
>
> + } else if (AsciiStrCmp (NodePtr->Name, "DebugPrintErrorLevel") == 0) {
>
> + //
>
> + // Create DebugPrintErrorLevel Hob.
>
> + //
>
> + DebugPrintErrorLevelInfo = BuildGuidHob (&gEdkiiDebugPrintErrorLevelGuid,
> sizeof (UEFI_PAYLOAD_DEBUG_PRINT_ERROR_LEVEL));
>
> + ASSERT (DebugPrintErrorLevelInfo != NULL);
>
> + if (DebugPrintErrorLevelInfo == NULL) {
>
> + break;
>
> + }
>
DebugPrintErrorLevel node is not defined in UPL spec, please remove relevant code here.
If required gEdkiiDebugPrintErrorLevelGuid hob can be passed by CustomFdtNode as it is EDK2 specific implementation.
> +
>
> + DebugPrintErrorLevelInfo->Header.Revision =
> UEFI_PAYLOAD_DEBUG_PRINT_ERROR_LEVEL_REVISION;
>
> + DebugPrintErrorLevelInfo->Header.Length = sizeof
> (UEFI_PAYLOAD_DEBUG_PRINT_ERROR_LEVEL);
>
> +
>
> + PropertyPtr = FdtGetProperty (Fdt, Node, "errorlevel", &TempLen);
>
> + ASSERT (TempLen > 0);
>
> + if (TempLen > 0) {
>
> + Data32 = (UINT32 *)(PropertyPtr->Data);
>
> + DEBUG ((DEBUG_INFO, "\n Property(00000000) errorlevel"));
>
> + DEBUG ((DEBUG_INFO, " %X", Fdt32ToCpu (*Data32)));
>
> + DebugPrintErrorLevelInfo->ErrorLevel = Fdt32ToCpu (*Data32);
>
> + }
>
> + }
>
> + }
>
> +
>
> + DEBUG ((DEBUG_INFO, "\n"));
>
> +
>
> + return NewHobList;
>
> +}
>
> +
>
> +/**
>
> + It will Parse FDT -node based on information from bootloaders.
>
> + @param[in] FdtBase The starting memory address of FdtBase
>
> + @retval HobList The base address of Hoblist.
>
> +
>
> +**/
>
> +UINTN
>
> +EFIAPI
>
> +FdtNodeParser (
>
> + IN VOID *FdtBase
>
> + )
>
> +{
>
> + return ParseDtb (FdtBase);
>
> +}
>
> +
>
> +/**
>
> + It will build a graphic device hob.
>
> +
>
> + @retval EFI_SUCCESS If it completed successfully.
>
> + @retval Others If it failed to parse DTB.
>
> +**/
>
> +EFI_STATUS
>
> +BuildGraphicDevHob (
>
> + VOID
>
> + );
>
> +
>
> +/**
>
> + It will initialize HOBs for UPL.
>
> +
>
> + @param[in] FdtBase Address of the Fdt data.
>
> +
>
> + @retval EFI_SUCCESS If it completed successfully.
>
> + @retval Others If it failed to initialize HOBs.
>
> +**/
>
> +UINTN
>
> +EFIAPI
>
> +UplInitHob (
>
> + IN VOID *FdtBase
>
> + )
>
> +{
>
> + UINTN NHobAddress;
>
> +
>
> + NHobAddress = 0;
>
> + //
>
> + // Check parameter type(
>
> + //
>
> + if (FdtCheckHeader (FdtBase) == 0) {
>
> + DEBUG ((DEBUG_INFO, "%a() FDT blob\n", __func__));
>
> + NHobAddress = FdtNodeParser ((VOID *)FdtBase);
>
> + } else {
>
> + DEBUG ((DEBUG_INFO, "%a() HOb list\n", __func__));
>
> + mHobList = FdtBase;
>
> +
>
> + return (UINTN)(mHobList);
>
> + }
>
> +
>
> + return NHobAddress;
>
> +}
>
> diff --git a/UefiPayloadPkg/Library/HobParseLib/HobParseLib.c
> b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.c
> new file mode 100644
> index 000000000000..72da4fcaf74f
> --- /dev/null
> +++ b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.c
> @@ -0,0 +1,408 @@
> +/** @file
>
> + Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +**/
>
> +
>
> +#include <PiPei.h>
>
> +#include <Library/BaseLib.h>
>
> +#include <Library/BaseMemoryLib.h>
>
> +#include <Library/MemoryAllocationLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/HobLib.h>
>
> +#include <Library/PcdLib.h>
>
> +#include <Guid/MemoryAllocationHob.h>
>
> +#include <Library/IoLib.h>
>
> +#include <Library/CpuLib.h>
>
> +#include <IndustryStandard/Acpi.h>
>
> +#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
>
> +#include <Guid/AcpiBoardInfoGuid.h>
>
> +#include <UniversalPayload/AcpiTable.h>
>
> +#include <UniversalPayload/UniversalPayload.h>
>
> +#include <UniversalPayload/ExtraData.h>
>
> +
>
> +#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT
> | \
>
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
>
> + EFI_RESOURCE_ATTRIBUTE_TESTED | \
>
> + EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | \
>
> + EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | \
>
> + EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | \
>
> + EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED | \
>
> + EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \
>
> + EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \
>
> + EFI_RESOURCE_ATTRIBUTE_64_BIT_IO | \
>
> + EFI_RESOURCE_ATTRIBUTE_PERSISTENT )
>
> +
>
> +#define TESTED_MEMORY_ATTRIBUTES
> (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
>
> + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
>
> + EFI_RESOURCE_ATTRIBUTE_TESTED )
>
> +
>
> +extern VOID *mHobList;
>
> +
>
> +/**
>
> + Add a new HOB to the HOB List.
>
> +
>
> + @param HobType Type of the new HOB.
>
> + @param HobLength Length of the new HOB to allocate.
>
> +
>
> + @return NULL if there is no space to create a hob.
>
> + @return The address point to the new created hob.
>
> +
>
> +**/
>
> +VOID *
>
> +EFIAPI
>
> +CreateHob (
>
> + IN UINT16 HobType,
>
> + IN UINT16 HobLength
>
> + );
>
> +
>
> +/**
>
> + Build a Handoff Information Table HOB
>
> +
>
> + This function initialize a HOB region from EfiMemoryBegin to
>
> + EfiMemoryTop. And EfiFreeMemoryBottom and EfiFreeMemoryTop should
>
> + be inside the HOB region.
>
> +
>
> + @param[in] EfiMemoryBottom Total memory start address
>
> + @param[in] EfiMemoryTop Total memory end address.
>
> + @param[in] EfiFreeMemoryBottom Free memory start address
>
> + @param[in] EfiFreeMemoryTop Free memory end address.
>
> +
>
> + @return The pointer to the handoff HOB table.
>
> +
>
> +**/
>
> +EFI_HOB_HANDOFF_INFO_TABLE *
>
> +EFIAPI
>
> +HobConstructor (
>
> + IN VOID *EfiMemoryBottom,
>
> + IN VOID *EfiMemoryTop,
>
> + IN VOID *EfiFreeMemoryBottom,
>
> + IN VOID *EfiFreeMemoryTop
>
> + );
>
> +
>
> +/**
>
> + Build ACPI board info HOB using infomation from ACPI table
>
> +
>
> + @param AcpiTableBase ACPI table start address in memory
>
> +
>
> + @retval A pointer to ACPI board HOB ACPI_BOARD_INFO. Null if build HOB
> failure.
>
> +**/
>
> +ACPI_BOARD_INFO *
>
> +BuildHobFromAcpi (
>
> + IN UINT64 AcpiTableBase
>
> + );
>
> +
>
> +/**
>
> + *
>
> + Add HOB into HOB list
>
> +
>
> + @param[in] Hob The HOB to be added into the HOB list.
>
> +**/
>
> +VOID
>
> +AddNewHob (
>
> + IN EFI_PEI_HOB_POINTERS *Hob
>
> + )
>
> +{
>
> + EFI_PEI_HOB_POINTERS NewHob;
>
> +
>
> + if (Hob->Raw == NULL) {
>
> + return;
>
> + }
>
> +
>
> + NewHob.Header = CreateHob (Hob->Header->HobType, Hob->Header-
> >HobLength);
>
> +
>
> + if (NewHob.Header != NULL) {
>
> + CopyMem (NewHob.Header + 1, Hob->Header + 1, Hob->Header->HobLength
> - sizeof (EFI_HOB_GENERIC_HEADER));
>
> + }
>
> +}
>
> +
>
> +/**
>
> + Found the Resource Descriptor HOB that contains a range (Base, Top)
>
> +
>
> + @param[in] HobList Hob start address
>
> + @param[in] Base Memory start address
>
> + @param[in] Top Memory end address.
>
> +
>
> + @retval The pointer to the Resource Descriptor HOB.
>
> +**/
>
> +EFI_HOB_RESOURCE_DESCRIPTOR *
>
> +FindResourceDescriptorByRange (
>
> + IN VOID *HobList,
>
> + IN EFI_PHYSICAL_ADDRESS Base,
>
> + IN EFI_PHYSICAL_ADDRESS Top
>
> + )
>
> +{
>
> + EFI_PEI_HOB_POINTERS Hob;
>
> + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
>
> +
>
> + for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw =
> GET_NEXT_HOB (Hob)) {
>
> + //
>
> + // Skip all HOBs except Resource Descriptor HOBs
>
> + //
>
> + if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
>
> + continue;
>
> + }
>
> +
>
> + //
>
> + // Skip Resource Descriptor HOBs that do not describe tested system memory
>
> + //
>
> + ResourceHob = Hob.ResourceDescriptor;
>
> + if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
>
> + continue;
>
> + }
>
> +
>
> + if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) !=
> TESTED_MEMORY_ATTRIBUTES) {
>
> + continue;
>
> + }
>
> +
>
> + //
>
> + // Skip Resource Descriptor HOBs that do not contain the PHIT range
> EfiFreeMemoryBottom..EfiFreeMemoryTop
>
> + //
>
> + if (Base < ResourceHob->PhysicalStart) {
>
> + continue;
>
> + }
>
> +
>
> + if (Top > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) {
>
> + continue;
>
> + }
>
> +
>
> + return ResourceHob;
>
> + }
>
> +
>
> + return NULL;
>
> +}
>
> +
>
> +/**
>
> + Find the highest below 4G memory resource descriptor, except the input
> Resource Descriptor.
>
> +
>
> + @param[in] HobList Hob start address
>
> + @param[in] MinimalNeededSize Minimal needed size.
>
> + @param[in] ExceptResourceHob Ignore this Resource Descriptor.
>
> +
>
> + @retval The pointer to the Resource Descriptor HOB.
>
> +**/
>
> +EFI_HOB_RESOURCE_DESCRIPTOR *
>
> +FindAnotherHighestBelow4GResourceDescriptor (
>
> + IN VOID *HobList,
>
> + IN UINTN MinimalNeededSize,
>
> + IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob
>
> + )
>
> +{
>
> + EFI_PEI_HOB_POINTERS Hob;
>
> + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
>
> + EFI_HOB_RESOURCE_DESCRIPTOR *ReturnResourceHob;
>
> +
>
> + ReturnResourceHob = NULL;
>
> +
>
> + for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw =
> GET_NEXT_HOB (Hob)) {
>
> + //
>
> + // Skip all HOBs except Resource Descriptor HOBs
>
> + //
>
> + if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
>
> + continue;
>
> + }
>
> +
>
> + //
>
> + // Skip Resource Descriptor HOBs that do not describe tested system memory
>
> + //
>
> + ResourceHob = Hob.ResourceDescriptor;
>
> + if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
>
> + continue;
>
> + }
>
> +
>
> + if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) !=
> TESTED_MEMORY_ATTRIBUTES) {
>
> + continue;
>
> + }
>
> +
>
> + //
>
> + // Skip if the Resource Descriptor HOB equals to ExceptResourceHob
>
> + //
>
> + if (ResourceHob == ExceptResourceHob) {
>
> + continue;
>
> + }
>
> +
>
> + //
>
> + // Skip Resource Descriptor HOBs that are beyond 4G
>
> + //
>
> + if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) >
> BASE_4GB) {
>
> + continue;
>
> + }
>
> +
>
> + //
>
> + // Skip Resource Descriptor HOBs that are too small
>
> + //
>
> + if (ResourceHob->ResourceLength < MinimalNeededSize) {
>
> + continue;
>
> + }
>
> +
>
> + //
>
> + // Return the topest Resource Descriptor
>
> + //
>
> + if (ReturnResourceHob == NULL) {
>
> + ReturnResourceHob = ResourceHob;
>
> + } else {
>
> + if (ReturnResourceHob->PhysicalStart < ResourceHob->PhysicalStart) {
>
> + ReturnResourceHob = ResourceHob;
>
> + }
>
> + }
>
> + }
>
> +
>
> + return ReturnResourceHob;
>
> +}
>
> +
>
> +/**
>
> + Check the HOB and decide if it is need inside Payload
>
> +
>
> + Payload maintainer may make decision which HOB is need or needn't
>
> + Then add the check logic in the function.
>
> +
>
> + @param[in] Hob The HOB to check
>
> +
>
> + @retval TRUE If HOB is need inside Payload
>
> + @retval FALSE If HOB is needn't inside Payload
>
> +**/
>
> +BOOLEAN
>
> +IsHobNeed (
>
> + EFI_PEI_HOB_POINTERS Hob
>
> + )
>
> +{
>
> + if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) {
>
> + return FALSE;
>
> + }
>
> +
>
> + if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
>
> + if (CompareGuid (&Hob.MemoryAllocationModule-
> >MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
>
> + return FALSE;
>
> + }
>
> + }
>
> +
>
> + // Arrive here mean the HOB is need
>
> + return TRUE;
>
> +}
>
> +
>
> +/**
>
> + It will build HOBs based on information from bootloaders.
>
> +
>
> + @param[in] BootloaderParameter The starting memory address of
> bootloader parameter block.
>
> +
>
> + @retval EFI_SUCCESS If it completed successfully.
>
> + @retval Others If it failed to build required HOBs.
>
> +**/
>
> +EFI_STATUS
>
> +BuildHobs (
>
> + IN UINTN BootloaderParameter
>
> + )
>
> +{
>
> + EFI_PEI_HOB_POINTERS Hob;
>
> + UINTN MinimalNeededSize;
>
> + EFI_PHYSICAL_ADDRESS FreeMemoryBottom;
>
> + EFI_PHYSICAL_ADDRESS FreeMemoryTop;
>
> + EFI_PHYSICAL_ADDRESS MemoryBottom;
>
> + EFI_PHYSICAL_ADDRESS MemoryTop;
>
> + EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob;
>
> + EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
>
> +
>
> + #if (!FixedPcdGetBool (PcdHandOffFdtEnable))
>
> + UINT8 *GuidHob;
>
> + UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTable;
>
> + ACPI_BOARD_INFO *AcpiBoardInfo;
>
> + #endif
>
> + EFI_HOB_HANDOFF_INFO_TABLE *HobInfo;
>
> +
>
> + Hob.Raw = (UINT8 *)BootloaderParameter;
>
> + MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
>
> +
>
> + ASSERT (Hob.Raw != NULL);
>
> + ASSERT ((UINTN)Hob.HandoffInformationTable->EfiFreeMemoryTop ==
> Hob.HandoffInformationTable->EfiFreeMemoryTop);
>
> + ASSERT ((UINTN)Hob.HandoffInformationTable->EfiMemoryTop ==
> Hob.HandoffInformationTable->EfiMemoryTop);
>
> + ASSERT ((UINTN)Hob.HandoffInformationTable->EfiFreeMemoryBottom ==
> Hob.HandoffInformationTable->EfiFreeMemoryBottom);
>
> + ASSERT ((UINTN)Hob.HandoffInformationTable->EfiMemoryBottom ==
> Hob.HandoffInformationTable->EfiMemoryBottom);
>
> +
>
> + //
>
> + // Try to find Resource Descriptor HOB that contains Hob range
> EfiMemoryBottom..EfiMemoryTop
>
> + //
>
> + PhitResourceHob = FindResourceDescriptorByRange (Hob.Raw,
> Hob.HandoffInformationTable->EfiMemoryBottom,
> Hob.HandoffInformationTable->EfiMemoryTop);
>
> + if (PhitResourceHob == NULL) {
>
> + //
>
> + // Boot loader's Phit Hob is not in an available Resource Descriptor, find
> another Resource Descriptor for new Phit Hob
>
> + //
>
> + ResourceHob = FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw,
> MinimalNeededSize, NULL);
>
> + if (ResourceHob == NULL) {
>
> + return EFI_NOT_FOUND;
>
> + }
>
> +
>
> + MemoryBottom = ResourceHob->PhysicalStart + ResourceHob-
> >ResourceLength - MinimalNeededSize;
>
> + FreeMemoryBottom = MemoryBottom;
>
> + FreeMemoryTop = ResourceHob->PhysicalStart + ResourceHob-
> >ResourceLength;
>
> + MemoryTop = FreeMemoryTop;
>
> + } else if (PhitResourceHob->PhysicalStart + PhitResourceHob->ResourceLength -
> Hob.HandoffInformationTable->EfiMemoryTop >= MinimalNeededSize) {
>
> + //
>
> + // New availiable Memory range in new hob is right above memory top in old
> hob.
>
> + //
>
> + MemoryBottom = Hob.HandoffInformationTable->EfiFreeMemoryTop;
>
> + FreeMemoryBottom = Hob.HandoffInformationTable->EfiMemoryTop;
>
> + FreeMemoryTop = FreeMemoryBottom + MinimalNeededSize;
>
> + MemoryTop = FreeMemoryTop;
>
> + } else if (Hob.HandoffInformationTable->EfiMemoryBottom - PhitResourceHob-
> >PhysicalStart >= MinimalNeededSize) {
>
> + //
>
> + // New availiable Memory range in new hob is right below memory bottom in
> old hob.
>
> + //
>
> + MemoryBottom = Hob.HandoffInformationTable->EfiMemoryBottom -
> MinimalNeededSize;
>
> + FreeMemoryBottom = MemoryBottom;
>
> + FreeMemoryTop = Hob.HandoffInformationTable->EfiMemoryBottom;
>
> + MemoryTop = Hob.HandoffInformationTable->EfiMemoryTop;
>
> + } else {
>
> + //
>
> + // In the Resource Descriptor HOB contains boot loader Hob, there is no
> enough free memory size for payload hob
>
> + // Find another Resource Descriptor Hob
>
> + //
>
> + ResourceHob = FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw,
> MinimalNeededSize, PhitResourceHob);
>
> + if (ResourceHob == NULL) {
>
> + return EFI_NOT_FOUND;
>
> + }
>
> +
>
> + MemoryBottom = ResourceHob->PhysicalStart + ResourceHob-
> >ResourceLength - MinimalNeededSize;
>
> + FreeMemoryBottom = MemoryBottom;
>
> + FreeMemoryTop = ResourceHob->PhysicalStart + ResourceHob-
> >ResourceLength;
>
> + MemoryTop = FreeMemoryTop;
>
> + }
>
> +
>
> + HobInfo = HobConstructor ((VOID *)(UINTN)MemoryBottom, (VOID
> *)(UINTN)MemoryTop, (VOID *)(UINTN)FreeMemoryBottom, (VOID
> *)(UINTN)FreeMemoryTop);
>
> + HobInfo->BootMode = Hob.HandoffInformationTable->BootMode;
>
> + //
>
> + // From now on, mHobList will point to the new Hob range.
>
> + //
>
> +
>
> + //
>
> + // Create an empty FvHob for the DXE FV that contains DXE core.
>
> + //
>
> + BuildFvHob ((EFI_PHYSICAL_ADDRESS)0, 0);
>
> + //
>
> + // Since payload created new Hob, move all hobs except PHIT from boot loader
> hob list.
>
> + //
>
> + Hob.Raw = (UINT8 *)BootloaderParameter;
>
> + while (!END_OF_HOB_LIST (Hob)) {
>
> + if (IsHobNeed (Hob)) {
>
> + // Add this hob to payload HOB
>
> + AddNewHob (&Hob);
>
> + }
>
> +
>
> + Hob.Raw = GET_NEXT_HOB (Hob);
>
> + }
>
> +
>
> + #if (!FixedPcdGetBool (PcdHandOffFdtEnable))
>
> + //
>
> + // Create guid hob for acpi board information
>
> + //
>
> + DEBUG ((DEBUG_INFO, "Create guid hob for acpi board information \n"));
>
> +
>
> + GuidHob = GetFirstGuidHob (&gUniversalPayloadAcpiTableGuid);
>
> + if (GuidHob != NULL) {
>
> + AcpiTable = (UNIVERSAL_PAYLOAD_ACPI_TABLE *)GET_GUID_HOB_DATA
> (GuidHob);
>
> + AcpiBoardInfo = BuildHobFromAcpi ((UINT64)AcpiTable->Rsdp);
>
> + ASSERT (AcpiBoardInfo != NULL);
>
> + }
>
> +
>
> + #endif
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> diff --git
> a/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.in
> f
> b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.in
> f
> new file mode 100644
> index 000000000000..036ed4315dd0
> --- /dev/null
> +++
> b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.in
> f
> @@ -0,0 +1,46 @@
> +## @file
>
> +# Custom FDT Node Parse Library.
>
> +#
>
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010005
>
> + BASE_NAME = CustomFdtNodeParserLib
>
> + FILE_GUID = 732B2B8F-65AD-4BF8-A98F-6E0D330F7A60
>
> + MODULE_TYPE = BASE
>
> + VERSION_STRING = 1.0
>
> + LIBRARY_CLASS = CustomFdtNodeParserLib
>
> +
>
> +#
>
> +# The following information is for reference only and not required by the build
> tools.
>
> +#
>
> +# VALID_ARCHITECTURES = IA32 X64
>
> +#
>
> +
>
> +[Sources]
>
> + CustomFdtNodeParserLib.c
>
> +
>
> +[Packages]
>
> + MdePkg/MdePkg.dec
>
> + MdeModulePkg/MdeModulePkg.dec
>
> + UefiPayloadPkg/UefiPayloadPkg.dec
>
> +
>
> +[LibraryClasses]
>
> + BaseMemoryLib
>
> + DebugLib
>
> + FdtLib
>
> + HobLib
>
> + PcdLib
>
> +
>
> +[Guids]
>
> + gUniversalPayloadPciRootBridgeInfoGuid
>
> + gUniversalPayloadSerialPortInfoGuid
>
> + gUniversalPayloadDeviceTreeGuid
>
> + gUniversalPayloadAcpiTableGuid
>
> + gEfiHobMemoryAllocModuleGuid
>
> +
>
> +[Pcd]
>
> + gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable
>
> diff --git
> a/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserN
> ullLib.inf
> b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserN
> ullLib.inf
> new file mode 100644
> index 000000000000..62916dd00848
> --- /dev/null
> +++
> b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserN
> ullLib.inf
> @@ -0,0 +1,33 @@
> +## @file
>
> +# Custom FDT Node Parse Library.
>
> +#
>
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010005
>
> + BASE_NAME = CustomFdtNodeParserLibNull
>
> + FILE_GUID = 386496E4-37DB-4531-BA0C-16D126E63C55
>
> + MODULE_TYPE = BASE
>
> + VERSION_STRING = 1.0
>
> + LIBRARY_CLASS = CustomFdtNodeParserLib
>
> +
>
> +#
>
> +# The following information is for reference only and not required by the build
> tools.
>
> +#
>
> +# VALID_ARCHITECTURES = IA32 X64
>
> +#
>
> +
>
> +[Sources]
>
> + CustomFdtNodeParserNullLib.c
>
> +
>
> +[Packages]
>
> + MdePkg/MdePkg.dec
>
> + MdeModulePkg/MdeModulePkg.dec
>
> + UefiPayloadPkg/UefiPayloadPkg.dec
>
> +
>
> +[LibraryClasses]
>
> + DebugLib
>
> + FdtLib
>
> diff --git a/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
> b/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
> new file mode 100644
> index 000000000000..91be56758db5
> --- /dev/null
> +++ b/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
> @@ -0,0 +1,63 @@
> +## @file
>
> +# Coreboot Table Parse Library.
>
> +#
>
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010005
>
> + BASE_NAME = FdtParseLib
>
> + FILE_GUID = 8956F72D-9626-4959-98B7-1BD4A3EA687E
>
> + MODULE_TYPE = BASE
>
> + VERSION_STRING = 1.0
>
> + LIBRARY_CLASS = FdtParseLib
>
> +
>
> +#
>
> +# The following information is for reference only and not required by the build
> tools.
>
> +#
>
> +# VALID_ARCHITECTURES = IA32 X64
>
> +#
>
> +
>
> +[Sources]
>
> + FdtParserLib.c
>
> +
>
> +[Packages]
>
> + MdePkg/MdePkg.dec
>
> + MdeModulePkg/MdeModulePkg.dec
>
> + UefiPayloadPkg/UefiPayloadPkg.dec
>
> +
>
> +[LibraryClasses]
>
> + DebugLib
>
> + PcdLib
>
> + HobLib
>
> + FdtLib
>
> + CustomFdtNodeParserLib
>
> +
>
> +[Guids]
>
> + gUniversalPayloadDeviceTreeGuid
>
> + gEfiGraphicsInfoHobGuid
>
> + gEfiGraphicsDeviceInfoHobGuid
>
> + gUniversalPayloadAcpiTableGuid
>
> + gUniversalPayloadSerialPortInfoGuid
>
> +
>
> +[Pcd.IA32,Pcd.X64]
>
> + gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
>
> + gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
>
> + gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable
>
> + gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
>
> + gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemBase
>
> + gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemLimit
>
> + gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBBase
>
> + gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBLimit
>
> +
>
> +
>
> +[BuildOptions]
>
> + MSFT:*_*_*_CC_FLAGS = /wd4305
>
> + GCC:*_*_IA32_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-
> to-pointer-cast
>
> + GCC:*_*_X64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-
> to-pointer-cast
>
> + GCC:*_*_ARM_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-
> to-pointer-cast
>
> + GCC:*_*_AARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-
> error=int-to-pointer-cast
>
> + GCC:*_*_RISCV64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-
> error=int-to-pointer-cast
>
> + GCC:*_*_LOONGARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-
> error=int-to-pointer-cast
>
> diff --git a/UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf
> b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf
> new file mode 100644
> index 000000000000..634c7ff56746
> --- /dev/null
> +++ b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf
> @@ -0,0 +1,40 @@
> +## @file
>
> +# UPL Hob Parse Library.
>
> +#
>
> +# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +[Defines]
>
> + INF_VERSION = 0x00010005
>
> + BASE_NAME = HobParseLib
>
> + FILE_GUID = EFB05FE7-604B-40DA-9A59-E2F998528754
>
> + MODULE_TYPE = DXE_DRIVER
>
> + VERSION_STRING = 1.0
>
> + LIBRARY_CLASS = HobParseLib|DXE_DRIVER DXE_RUNTIME_DRIVER
> SMM_CORE DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
>
> +
>
> +#
>
> +# The following information is for reference only and not required by the build
> tools.
>
> +#
>
> +# VALID_ARCHITECTURES = IA32 X64
>
> +#
>
> +
>
> +[Sources]
>
> + HobParseLib.c
>
> +
>
> +[Packages]
>
> + MdePkg/MdePkg.dec
>
> + MdeModulePkg/MdeModulePkg.dec
>
> + UefiPayloadPkg/UefiPayloadPkg.dec
>
> +
>
> +[LibraryClasses]
>
> + BaseLib
>
> + BaseMemoryLib
>
> + IoLib
>
> + DebugLib
>
> + PcdLib
>
> + HobLib
>
> +
>
> +[Pcd.IA32,Pcd.X64]
>
> + gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
>
> + gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable
>
> --
> 2.39.2.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119366): https://edk2.groups.io/g/devel/message/119366
Mute This Topic: https://groups.io/mt/106275995/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 2+ messages in thread