* [edk2-devel] [PATCH v3 5/6] UefiPayloadPkg: Add FDT Paser relative LIBs.
@ 2024-05-24 4:14 Linus Liu
2024-05-29 20:25 ` Chiu, Chasel
0 siblings, 1 reply; 2+ messages in thread
From: Linus Liu @ 2024-05-24 4:14 UTC (permalink / raw)
To: devel; +Cc: Benny Lin, Gua Guo, Chasel Chiu, James Lu, Dhaval Sharma
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/CustomFdtNodeParserNullLib.c | 51 ++
UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c | 622 ++++++++++++++++++++
UefiPayloadPkg/Library/HobParseLib/HobParseLib.c | 408 +++++++++++++
UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf | 46 ++
UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.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/CustomFdtNodeParserNullLib.c b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.c
new file mode 100644
index 000000000000..0012162fa0d2
--- /dev/null
+++ b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.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;
+ }
+ }
+ } 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);
+ }
+ }
+ } 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
+ }
+ }
+ }
+ }
+ // 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;
+ }
+
+ 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.inf b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf
new file mode 100644
index 000000000000..036ed4315dd0
--- /dev/null
+++ b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf
@@ -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/CustomFdtNodeParserNullLib.inf b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf
new file mode 100644
index 000000000000..62916dd00848
--- /dev/null
+++ b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.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 (#119197): https://edk2.groups.io/g/devel/message/119197
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 related [flat|nested] 2+ messages in thread
* 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
end of thread, other threads:[~2024-05-29 20:25 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox