public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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