From: "Linus Liu" <linus.liu@intel.com>
To: devel@edk2.groups.io
Cc: Benny Lin <benny.lin@intel.com>, Gua Guo <gua.guo@intel.com>,
Chasel Chiu <chasel.chiu@intel.com>,
James Lu <james.lu@intel.com>,
Dhaval Sharma <dhaval@rivosinc.com>
Subject: [edk2-devel] [PATCH v4 5/6] UefiPayloadPkg: Add FDT Paser relative LIBs.
Date: Sun, 2 Jun 2024 19:18:55 -0700 [thread overview]
Message-ID: <20240603021855.526-1-linus.liu@intel.com> (raw)
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 | 627 ++++++++++++++++++++
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, 1426 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..aa944bd1e821
--- /dev/null
+++ b/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c
@@ -0,0 +1,627 @@
+/** @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 N_NON_RELOCATABLE BIT31
+#define P_NON_PREFETCHABLE BIT30
+#define SS_CONFIGURATION_SPACE 0
+#define SS_IO_SPACE BIT24
+#define SS_32BIT_MEMORY_SPACE BIT25
+#define SS_64BIT_MEMORY_SPACE BIT24+BIT25
+
+#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) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ Attribute = Fdt32ToCpu (*(Data32 + 0));
+ StartAddress = Fdt32ToCpu (*(Data32 + 2));
+ DEBUG ((DEBUG_INFO, "\n Property(%08X) %a", Property, TempStr));
+ DEBUG ((DEBUG_INFO, " StartAddress %016lX\n", StartAddress));
+ DEBUG ((DEBUG_INFO, " Attribute %016lX\n", Attribute));
+
+ Serial->RegisterBase = StartAddress;
+ Serial->UseMmio = (Attribute&SS_32BIT_MEMORY_SPACE) == SS_32BIT_MEMORY_SPACE ? 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 (#119420): https://edk2.groups.io/g/devel/message/119420
Mute This Topic: https://groups.io/mt/106455165/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
reply other threads:[~2024-06-03 2:19 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240603021855.526-1-linus.liu@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox