/** @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>
#include <Guid/PciSegmentInfoGuid.h>

typedef enum {
  ReservedMemory = 1,
  Memory,
  FrameBuffer,
  PciRootBridge,
  Options,
  SerialPort,
  DoNothing
} FDT_NODE_TYPE;

#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)

#define UPL_ALIGN_DOWN(Addr)  ((UINT64)(Addr) & ~(UINT64)(EFI_PAGE_SIZE - 1))

extern VOID                         *mHobList;
UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES  *mPciRootBridgeInfo = NULL;
INT32                               mNode[0x500]        = { 0 };
UINT32                              mNodeIndex          = 0;
UPL_PCI_SEGMENT_INFO_HOB            *mUplPciSegmentInfoHob;

/**
  Build a Handoff Information Table HOB

  This function initializes 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 record the memory node initialized.

  @param[in]  Node           memory node is going to parsing.
**/
VOID
RecordMemoryNode (
  INT32  Node
  )
{
  DEBUG ((DEBUG_INFO, "\n RecordMemoryNode  %x , mNodeIndex :%x  \n", Node, mNodeIndex));
  mNode[mNodeIndex] = Node;
  mNodeIndex++;
}

/**
  Check the memory node if initialized.

  @param[in]  Node           memory node is going to parsing.

  @return TRUE               memory node was initialized. don't parse it again.
  @return FALSE              memory node wasn't initialized, go to parse it.
**/
BOOLEAN
CheckMemoryNodeIfInit (
  INT32  Node
  )
{
  UINT32  i;

  for (i = 0; i < mNodeIndex; i++) {
    if (mNode[i] == Node) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  It will check device node from FDT.

  @param[in]  NodeString        Device node name string.
  @param[in]  Depth             Check layer of Device node, only parse the 1st layer

  @return FDT_NODE_TYPE         what type of the device node.
**/
FDT_NODE_TYPE
CheckNodeType (
  CHAR8  *NodeString,
  INT32  Depth
  )
{
  DEBUG ((DEBUG_INFO, "\n CheckNodeType  %a   \n", NodeString));
  if (AsciiStrnCmp (NodeString, "serial@", AsciiStrLen ("serial@")) == 0) {
    return SerialPort;
  } else if (AsciiStrnCmp (NodeString, "reserved-memory", AsciiStrLen ("reserved-memory")) == 0) {
    return ReservedMemory;
  } else if (AsciiStrnCmp (NodeString, "memory@", AsciiStrLen ("memory@")) == 0) {
    return Memory;
  } else if (AsciiStrnCmp (NodeString, "framebuffer@", AsciiStrLen ("framebuffer@")) == 0) {
    return FrameBuffer;
  } else if (AsciiStrnCmp (NodeString, "pci-rb", AsciiStrLen ("pci-rb")) == 0) {
    return PciRootBridge;
  } else if (AsciiStrCmp (NodeString, "options") == 0) {
    return Options;
  } else {
    return DoNothing;
  }
}

/**
  It will ParseMemory node from FDT.

  @param[in]  Fdt               Address of the Fdt data.
  @param[in]  SubNode           first node of the PCI root bridge node.
**/
VOID
ParseMemory (
  IN VOID   *Fdt,
  IN INT32  Node
  )
{
  UINT32              Attribute;
  UINT8               ECCAttribute;
  UINT32              ECCData, ECCData2;
  INT32               Property;
  CONST FDT_PROPERTY  *PropertyPtr;
  INT32               TempLen;
  CONST CHAR8         *TempStr;
  UINT64              *Data64;
  UINT32              *Data32;
  UINT64              StartAddress;
  UINT64              NumberOfBytes;

  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 (ReadUnaligned64 (Data64));
      NumberOfBytes = Fdt64ToCpu (ReadUnaligned64 (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);
}

/**
  It will ParseReservedMemory node from FDT.

  @param[in]  Fdt               Address of the Fdt data.
  @param[in]  SubNode           first node of the PCI root bridge node.
**/
VOID
ParseReservedMemory (
  IN VOID   *Fdt,
  IN INT32  Node
  )
{
  INT32                           SubNode;
  INT32                           TempLen;
  CONST CHAR8                     *TempStr;
  CONST FDT_PROPERTY              *PropertyPtr;
  UINT64                          *Data64;
  UINT64                          StartAddress;
  UINT64                          NumberOfBytes;
  UNIVERSAL_PAYLOAD_ACPI_TABLE    *PlatformAcpiTable;
  UNIVERSAL_PAYLOAD_SMBIOS_TABLE  *SmbiosTable;
  FDT_NODE_HEADER                 *NodePtr;
  UINT32                          Attribute;

  PlatformAcpiTable = NULL;

  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);
    TempStr = (CHAR8 *)(PropertyPtr->Data);
    if (TempLen > 0) {
      Data64        = (UINT64 *)(PropertyPtr->Data);
      StartAddress  = Fdt64ToCpu (ReadUnaligned64 (Data64));
      NumberOfBytes = Fdt64ToCpu (ReadUnaligned64 (Data64 + 1));
      DEBUG ((DEBUG_INFO, "\n         Property  %a", TempStr));
      DEBUG ((DEBUG_INFO, "  %016lX  %016lX\n", StartAddress, NumberOfBytes));
    }

    RecordMemoryNode (SubNode);

    if (AsciiStrnCmp (NodePtr->Name, "mmio@", AsciiStrLen ("mmio@")) == 0) {
      DEBUG ((DEBUG_INFO, "  MemoryMappedIO"));
      BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiMemoryMappedIO);
    } else {
      PropertyPtr = FdtGetProperty (Fdt, SubNode, "compatible", &TempLen);
      TempStr     = (CHAR8 *)(PropertyPtr->Data);
      DEBUG ((DEBUG_INFO, "compatible:  %a\n", TempStr));
      if (AsciiStrnCmp (TempStr, "boot-code", AsciiStrLen ("boot-code")) == 0) {
        DEBUG ((DEBUG_INFO, "  boot-code\n"));
        BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesCode);
      } else if (AsciiStrnCmp (TempStr, "boot-data", AsciiStrLen ("boot-data")) == 0) {
        DEBUG ((DEBUG_INFO, "  boot-data\n"));
        BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesData);
      } else if (AsciiStrnCmp (TempStr, "runtime-code", AsciiStrLen ("runtime-code")) == 0) {
        DEBUG ((DEBUG_INFO, "  runtime-code\n"));
        BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiRuntimeServicesCode);
      } else if (AsciiStrnCmp (TempStr, "runtime-data", AsciiStrLen ("runtime-data")) == 0) {
        DEBUG ((DEBUG_INFO, "  runtime-data\n"));
        BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiRuntimeServicesData);
      } else if (AsciiStrnCmp (TempStr, "special-purpose", AsciiStrLen ("special-purpose")) == 0) {
        Attribute = MEMORY_ATTRIBUTE_DEFAULT | EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE;
        DEBUG ((DEBUG_INFO, "  special-purpose memory\n"));
        BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attribute, StartAddress, NumberOfBytes);
      } else if (AsciiStrnCmp (TempStr, "acpi-nvs", AsciiStrLen ("acpi-nvs")) == 0) {
        DEBUG ((DEBUG_INFO, "\n ********* acpi-nvs ********\n"));
        BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiACPIMemoryNVS);
      } else if (AsciiStrnCmp (TempStr, "acpi", AsciiStrLen ("acpi")) == 0) {
        DEBUG ((DEBUG_INFO, "  acpi, StartAddress:%x, NumberOfBytes:%x\n", StartAddress, NumberOfBytes));

        BuildMemoryAllocationHob (
          UPL_ALIGN_DOWN (StartAddress),
          ALIGN_VALUE (NumberOfBytes, EFI_PAGE_SIZE),
          EfiBootServicesData
          );
        PlatformAcpiTable = BuildGuidHob (&gUniversalPayloadAcpiTableGuid, sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE));
        if (PlatformAcpiTable != NULL) {
          DEBUG ((DEBUG_INFO, " build gUniversalPayloadAcpiTableGuid , NumberOfBytes:%x\n", 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, "smbios", AsciiStrLen ("smbios")) == 0) {
        DEBUG ((DEBUG_INFO, " build smbios, NumberOfBytes:%x\n", NumberOfBytes));
        BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesData);
        SmbiosTable = BuildGuidHob (&gUniversalPayloadSmbios3TableGuid, sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE));
        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);
        }
      } else {
        BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiReservedMemoryType);
      }
    }
  }
}

/**
  It will ParseFrameBuffer node from FDT.

  @param[in]  Fdt               Address of the Fdt data.
  @param[in]  SubNode           first Sub node of the PCI root bridge node.

  @return     GmaStr            Graphic device node name string.
**/
CHAR8 *
ParseFrameBuffer (
  IN VOID   *Fdt,
  IN INT32  Node
  )
{
  INT32                      Property;
  INT32                      TempLen;
  CONST FDT_PROPERTY         *PropertyPtr;
  CONST CHAR8                *TempStr;
  UINT32                     *Data32;
  UINT64                     FrameBufferBase;
  UINT32                     FrameBufferSize;
  EFI_PEI_GRAPHICS_INFO_HOB  *GraphicsInfo;
  CHAR8                      *GmaStr;

  GmaStr = "Gma";
  //
  // Create GraphicInfo HOB.
  //
  GraphicsInfo = BuildGuidHob (&gEfiGraphicsInfoHobGuid, sizeof (EFI_PEI_GRAPHICS_INFO_HOB));
  ASSERT (GraphicsInfo != NULL);
  if (GraphicsInfo == NULL) {
    return GmaStr;
  }

  ZeroMem (GraphicsInfo, sizeof (EFI_PEI_GRAPHICS_INFO_HOB));

  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) {
      Data32                        = (UINT32 *)(PropertyPtr->Data);
      FrameBufferBase               = Fdt32ToCpu (*(Data32 + 0));
      FrameBufferSize               = Fdt32ToCpu (*(Data32 + 1));
      GraphicsInfo->FrameBufferBase = FrameBufferBase;
      GraphicsInfo->FrameBufferSize = (UINT32)FrameBufferSize;
    } else if (AsciiStrCmp (TempStr, "width") == 0) {
      Data32                                          = (UINT32 *)(PropertyPtr->Data);
      GraphicsInfo->GraphicsMode.HorizontalResolution = Fdt32ToCpu (*Data32);
    } else if (AsciiStrCmp (TempStr, "height") == 0) {
      Data32                                        = (UINT32 *)(PropertyPtr->Data);
      GraphicsInfo->GraphicsMode.VerticalResolution = Fdt32ToCpu (*Data32);
    } else if (AsciiStrCmp (TempStr, "format") == 0) {
      TempStr = (CHAR8 *)(PropertyPtr->Data);
      if (AsciiStrCmp (TempStr, "a8r8g8b8") == 0) {
        GraphicsInfo->GraphicsMode.PixelFormat = PixelRedGreenBlueReserved8BitPerColor;
      } else if (AsciiStrCmp (TempStr, "a8b8g8r8") == 0) {
        GraphicsInfo->GraphicsMode.PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
      } else {
        GraphicsInfo->GraphicsMode.PixelFormat = PixelFormatMax;
      }
    } else if (AsciiStrCmp (TempStr, "display") == 0) {
      GmaStr = (CHAR8 *)(PropertyPtr->Data);
      GmaStr++;
      DEBUG ((DEBUG_INFO, "  display (%s)", GmaStr));
    }

    // In most case, PixelsPerScanLine is identical to HorizontalResolution
    GraphicsInfo->GraphicsMode.PixelsPerScanLine = GraphicsInfo->GraphicsMode.HorizontalResolution;
  }

  return GmaStr;
}

/**
  It will ParseOptions node from FDT.

  @param[in]  Fdt               Address of the Fdt data.
  @param[in]  SubNode           first Sub node of the PCI root bridge node.
  @param[out] PciEnumDone       Init ParsePciRootBridge node for ParsePciRootBridge.
  @param[out] BootMode          Init the system boot mode
**/
VOID
ParseOptions (
  IN VOID            *Fdt,
  IN INT32           Node,
  OUT UINT8          *PciEnumDone,
  OUT EFI_BOOT_MODE  *BootMode
  )
{
  INT32                   SubNode;
  FDT_NODE_HEADER         *NodePtr;
  UNIVERSAL_PAYLOAD_BASE  *PayloadBase;
  CONST FDT_PROPERTY      *PropertyPtr;
  CONST CHAR8             *TempStr;
  INT32                   TempLen;
  UINT32                  *Data32;
  UINT64                  *Data64;
  UINT64                  StartAddress;
  UINT8                   SizeOfMemorySpace;

  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;
      }

      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 (ReadUnaligned64 (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, "addr-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);
        BuildCpuHob (SizeOfMemorySpace, PcdGet8 (SizeOfIoSpace));
      }

      PropertyPtr = FdtGetProperty (Fdt, SubNode, "pci-enum-done", &TempLen);
      if (TempLen > 0) {
        *PciEnumDone = 1;
        DEBUG ((DEBUG_INFO, "  Found PciEnumDone (%08X)\n", *PciEnumDone));
      } else {
        *PciEnumDone = 0;
        DEBUG ((DEBUG_INFO, "  Not Found PciEnumDone \n"));
      }

      PropertyPtr = FdtGetProperty (Fdt, SubNode, "boot-mode", &TempLen);
      if (TempLen > 0) {
        TempStr = (CHAR8 *)(PropertyPtr->Data);
        if (AsciiStrCmp (TempStr, "normal") == 0) {
          *BootMode = BOOT_WITH_FULL_CONFIGURATION;
        } else if (AsciiStrCmp (TempStr, "fast") == 0) {
          *BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
        } else if (AsciiStrCmp (TempStr, "full") == 0) {
          *BootMode = BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS;
        } else if (AsciiStrCmp (TempStr, "default") == 0) {
          *BootMode = BOOT_WITH_DEFAULT_SETTINGS;
        } else if (AsciiStrCmp (TempStr, "s4") == 0) {
          *BootMode = BOOT_ON_S4_RESUME;
        } else if (AsciiStrCmp (TempStr, "s3") == 0) {
          *BootMode = BOOT_ON_S3_RESUME;
        }
      }
    }
  }
}

/**
  It will Parsegraphic node from FDT.

  @param[in]  Fdt               Address of the Fdt data.
  @param[in]  SubNode           first Sub node of the PCI root bridge node.
**/
VOID
ParsegraphicNode (
  IN VOID   *Fdt,
  IN INT32  SubNode
  )
{
  EFI_PEI_GRAPHICS_DEVICE_INFO_HOB  *GraphicsDev;
  CONST FDT_PROPERTY                *PropertyPtr;
  UINT16                            GmaID;
  UINT32                            *Data32;
  INT32                             TempLen;

  DEBUG ((DEBUG_INFO, "  Found gma@ node \n"));
  GraphicsDev = NULL;
  //
  // Build Graphic info HOB .
  //
  GraphicsDev = BuildGuidHob (&gEfiGraphicsDeviceInfoHobGuid, sizeof (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB));
  ASSERT (GraphicsDev != NULL);
  if (GraphicsDev == NULL) {
    return;
  }

  SetMem (GraphicsDev, sizeof (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB), 0xFF);
  PropertyPtr = FdtGetProperty (Fdt, SubNode, "vendor-id", &TempLen);
  ASSERT (TempLen > 0);
  if (TempLen > 0) {
    Data32 = (UINT32 *)(PropertyPtr->Data);
    GmaID  = (UINT16)Fdt32ToCpu (*Data32);
    DEBUG ((DEBUG_INFO, "\n   vendor-id"));
    DEBUG ((DEBUG_INFO, "  %016lX\n", GmaID));
    GraphicsDev->VendorId = GmaID;
  }

  PropertyPtr = FdtGetProperty (Fdt, SubNode, "device-id", &TempLen);
  ASSERT (TempLen > 0);
  if (TempLen > 0) {
    Data32 = (UINT32 *)(PropertyPtr->Data);
    GmaID  = (UINT16)Fdt32ToCpu (*Data32);
    DEBUG ((DEBUG_INFO, "\n   device-id"));
    DEBUG ((DEBUG_INFO, "  %016lX\n", GmaID));
    GraphicsDev->DeviceId = GmaID;
  }

  PropertyPtr = FdtGetProperty (Fdt, SubNode, "revision-id", &TempLen);
  ASSERT (TempLen > 0);
  if (TempLen > 0) {
    Data32 = (UINT32 *)(PropertyPtr->Data);
    GmaID  = (UINT16)Fdt32ToCpu (*Data32);
    DEBUG ((DEBUG_INFO, "\n   revision-id"));
    DEBUG ((DEBUG_INFO, "  %016lX\n", GmaID));
    GraphicsDev->RevisionId = (UINT8)GmaID;
  }

  PropertyPtr = FdtGetProperty (Fdt, SubNode, "subsystem-vendor-id", &TempLen);
  ASSERT (TempLen > 0);
  if (TempLen > 0) {
    Data32 = (UINT32 *)(PropertyPtr->Data);
    GmaID  = (UINT16)Fdt32ToCpu (*Data32);
    DEBUG ((DEBUG_INFO, "\n   subsystem-vendor-id"));
    DEBUG ((DEBUG_INFO, "  %016lX\n", GmaID));
    GraphicsDev->SubsystemVendorId = GmaID;
  }

  PropertyPtr = FdtGetProperty (Fdt, SubNode, "subsystem-id", &TempLen);
  ASSERT (TempLen > 0);
  if (TempLen > 0) {
    Data32 = (UINT32 *)(PropertyPtr->Data);
    GmaID  = (UINT16)Fdt32ToCpu (*Data32);
    DEBUG ((DEBUG_INFO, "\n   subsystem-id"));
    DEBUG ((DEBUG_INFO, "  %016lX\n", GmaID));
    GraphicsDev->SubsystemId = GmaID;
  }
}

/**
  It will ParseSerialPort node from FDT.

  @param[in]  Fdt               Address of the Fdt data.
  @param[in]  SubNode           first Sub node of the PCI root bridge node.
  @param[in]  AddressCells      #address-cells for serial port node 'reg' property.
**/
VOID
ParseSerialPort (
  IN VOID    *Fdt,
  IN INT32   SubNode,
  IN UINT32  AddressCells
  )
{
  UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO  *Serial;
  CONST FDT_PROPERTY                  *PropertyPtr;
  INT32                               TempLen;
  UINT32                              *Data32;
  UINT32                              Value32;

  //
  // Create SerialPortInfo HOB.
  //
  Serial = BuildGuidHob (&gUniversalPayloadSerialPortInfoGuid, sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO));
  ASSERT (Serial != NULL);
  if (Serial == NULL) {
    return;
  }

  Serial->Header.Revision = UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO_REVISION;
  Serial->Header.Length   = sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO);
  Serial->RegisterStride  = 1;
  Serial->UseMmio         = TRUE;

  PropertyPtr = FdtGetProperty (Fdt, SubNode, "current-speed", &TempLen);
  ASSERT (TempLen > 0);
  if (TempLen > 0) {
    Data32           = (UINT32 *)(PropertyPtr->Data);
    Serial->BaudRate = Fdt32ToCpu (*Data32);
  }

  PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg-shift", &TempLen);
  if (TempLen > 0) {
    Data32                 = (UINT32 *)(PropertyPtr->Data);
    Serial->RegisterStride = (UINT8)(1 << Fdt32ToCpu (*Data32));
  }

  PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg", &TempLen);
  ASSERT (TempLen > 0);
  if (TempLen > 0) {
    Data32  = (UINT32 *)(PropertyPtr->Data);
    Value32 = Fdt32ToCpu (Data32[0]);
    switch (AddressCells) {
      case 1:
        Serial->RegisterBase = Value32;
        if (Value32 < SIZE_64KB) {
          Serial->UseMmio = FALSE;
        }

        break;
      case 2:
        Serial->RegisterBase = Fdt32ToCpu (Data32[1]);
        if (Value32 == 1) {
          // IO type for Legacy serial
          Serial->UseMmio = FALSE;
        } else {
          Serial->RegisterBase |= LShiftU64 (Value32, 32);
        }

        break;
      case 3:
        // First U32 format: npt000ss bbbbbbbb dddddfff rrrrrrrr
        if ((Value32 & 0x03000000) == 0x01000000) {
          Serial->UseMmio = FALSE;
        }

        Serial->RegisterBase = LShiftU64 ((UINT64)Fdt32ToCpu (Data32[1]), 32) | Fdt32ToCpu (Data32[2]);
        break;
      default:
        DEBUG ((DEBUG_INFO, "ERROR: not supported address cells %d\n", AddressCells));
        break;
    }
  }

  DEBUG ((DEBUG_INFO, "Serial->UseMmio        = %x\n", Serial->UseMmio));
  DEBUG ((DEBUG_INFO, "Serial->RegisterBase   = 0x%x\n", Serial->RegisterBase));
  DEBUG ((DEBUG_INFO, "Serial->BaudRate       = %d\n", Serial->BaudRate));
  DEBUG ((DEBUG_INFO, "Serial->RegisterStride = %x\n", Serial->RegisterStride));
}

/**
  It will ParsePciRootBridge node from FDT.

  @param[in]  Fdt               Address of the Fdt data.
  @param[in]  Node              first node of the Fdt data.
  @param[in]  PciEnumDone       To use ParsePciRootBridge node.
  @param[in]  RootBridgeCount   Number of pci RootBridge.
  @param[in]  GmaStr            Graphic device node name string.
  @param[in]  index             Index of ParsePciRootBridge node.
**/
VOID
ParsePciRootBridge (
  IN VOID   *Fdt,
  IN INT32  Node,
  IN UINT8  RootBridgeCount,
  IN CHAR8  *GmaStr,
  IN UINT8  *index
  )
{
  INT32               SubNode;
  INT32               Property;
  INT32               SSubNode;
  FDT_NODE_HEADER     *NodePtr;
  CONST FDT_PROPERTY  *PropertyPtr;
  INT32               TempLen;
  UINT32              *Data32;
  UINT32              MemType;
  CONST CHAR8         *TempStr;
  UINT8               RbIndex;
  UINTN               HobDataSize;
  UINT8               Base;
  UINT32              AddressCells;

  if (RootBridgeCount == 0) {
    return;
  }

  RbIndex     = *index;
  HobDataSize = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES) + (RootBridgeCount * sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE));
  //
  // Create PCI Root Bridge Info Hob.
  //
  if (mPciRootBridgeInfo == NULL) {
    mPciRootBridgeInfo = BuildGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid, HobDataSize);
    ASSERT (mPciRootBridgeInfo != NULL);
    if (mPciRootBridgeInfo == NULL) {
      return;
    }

    ZeroMem (mPciRootBridgeInfo, HobDataSize);
    mPciRootBridgeInfo->Header.Length    = (UINT16)HobDataSize;
    mPciRootBridgeInfo->Header.Revision  = UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION;
    mPciRootBridgeInfo->Count            = RootBridgeCount;
    mPciRootBridgeInfo->ResourceAssigned = FALSE;
  }

  if (mUplPciSegmentInfoHob == NULL) {
    HobDataSize           = sizeof (UPL_PCI_SEGMENT_INFO_HOB) + ((RootBridgeCount) * sizeof (UPL_SEGMENT_INFO));
    mUplPciSegmentInfoHob = BuildGuidHob (&gUplPciSegmentInfoHobGuid, HobDataSize);
    if (mUplPciSegmentInfoHob != NULL) {
      ZeroMem (mUplPciSegmentInfoHob, HobDataSize);
      mUplPciSegmentInfoHob->Header.Revision = UNIVERSAL_PAYLOAD_PCI_SEGMENT_INFO_REVISION;
      mUplPciSegmentInfoHob->Header.Length   = (UINT16)HobDataSize;
      mUplPciSegmentInfoHob->Count           = RootBridgeCount;
    }
  }

  AddressCells = 3;
  PropertyPtr  = FdtGetProperty (Fdt, Node, "#address-cells", &TempLen);
  if ((PropertyPtr != NULL) && (TempLen > 0)) {
    AddressCells = Fdt32ToCpu (*(UINT32 *)PropertyPtr->Data);
  }

  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, GmaStr, AsciiStrLen (GmaStr)) == 0) {
      DEBUG ((DEBUG_INFO, "  Found gma@ node \n"));
      ParsegraphicNode (Fdt, SubNode);
    }

    if (AsciiStrnCmp (NodePtr->Name, "isa", AsciiStrLen ("isa")) == 0) {
      PropertyPtr = FdtGetProperty (Fdt, SubNode, "#address-cells", &TempLen);
      if ((PropertyPtr != NULL) && (TempLen > 0)) {
        AddressCells = Fdt32ToCpu (*(UINT32 *)PropertyPtr->Data);
      }

      SSubNode = FdtFirstSubnode (Fdt, SubNode);
      ParseSerialPort (Fdt, SSubNode, AddressCells);
    }

    if (AsciiStrnCmp (NodePtr->Name, "serial@", AsciiStrLen ("serial@")) == 0) {
      ParseSerialPort (Fdt, SubNode, AddressCells);
    }
  }

  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), limit %x\n", TempLen, TempLen / sizeof (UINT32)));
      // TODO:  In future we should fetch these values from fdt and avoid using these Pcds
      mPciRootBridgeInfo->RootBridge[RbIndex].AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
      mPciRootBridgeInfo->RootBridge[RbIndex].Supports             = ROOT_BRIDGE_SUPPORTS_DEFAULT;
      mPciRootBridgeInfo->RootBridge[RbIndex].PMemAbove4G.Base     = PcdGet64 (PcdPciReservedPMemAbove4GBBase);
      mPciRootBridgeInfo->RootBridge[RbIndex].PMemAbove4G.Limit    = PcdGet64 (PcdPciReservedPMemAbove4GBLimit);
      mPciRootBridgeInfo->RootBridge[RbIndex].PMem.Base            = PcdGet32 (PcdPciReservedPMemBase);
      mPciRootBridgeInfo->RootBridge[RbIndex].PMem.Limit           = PcdGet32 (PcdPciReservedPMemLimit);
      mPciRootBridgeInfo->RootBridge[RbIndex].UID                  = RbIndex;
      mPciRootBridgeInfo->RootBridge[RbIndex].HID                  = EISA_PNP_ID (0x0A03);
      mPciRootBridgeInfo->RootBridge[RbIndex].DmaAbove4G           = PcdGetBool (PcdPciAllocateMemoryAbove4GB);

      Data32 = (UINT32 *)(PropertyPtr->Data);
      for (Base = 0; Base < TempLen / sizeof (UINT32); Base = Base + DWORDS_TO_NEXT_ADDR_TYPE) {
        DEBUG ((DEBUG_INFO, "  Base :%x \n", Base));
        MemType = Fdt32ToCpu (*(Data32 + Base));
        if (((MemType) & (SS_64BIT_MEMORY_SPACE)) == SS_64BIT_MEMORY_SPACE) {
          mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base  = Fdt32ToCpu (*(Data32 + Base + 2)) + LShiftU64 (Fdt32ToCpu (*(Data32 + Base + 1)), 32);
          mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base + LShiftU64 (Fdt32ToCpu (*(Data32 + Base + 5)), 32) + Fdt32ToCpu (*(Data32 + Base + 6)) - 1;
        } else if (((MemType) & (SS_32BIT_MEMORY_SPACE)) == SS_32BIT_MEMORY_SPACE) {
          mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base  = Fdt32ToCpu (*(Data32 + Base + 2));
          mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base + Fdt32ToCpu (*(Data32 + Base + 6)) - 1;
        } else if (((MemType) & (SS_IO_SPACE)) == SS_IO_SPACE) {
          mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base  = Fdt32ToCpu (*(Data32 + Base + 2));
          mPciRootBridgeInfo->RootBridge[RbIndex].Io.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base + Fdt32ToCpu (*(Data32 + Base + 6)) - 1;
        }
      }

      DEBUG ((DEBUG_INFO, "RootBridgeCount %x, index :%x\n", RootBridgeCount, RbIndex));

      DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base %x, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base));
      DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.limit %x, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Limit));

      DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base));
      DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.limit %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Limit));

      DEBUG ((DEBUG_INFO, "PciRootBridge->Io.Base %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base));
      DEBUG ((DEBUG_INFO, "PciRootBridge->Io.limit %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Io.Limit));
    }

    //
    // Check for the "dma-ranges" property to determine if the device supports
    // DMA (Direct Memory Access) addresses above the 4GiB boundary.
    //
    if (AsciiStrCmp (TempStr, "dma-ranges") == 0) {
      Data32 = (UINT32 *)(PropertyPtr->Data);

      if (TempLen == 0) {
        continue;
      }

      //
      // According to the device tree specification, a dma-ranges entry is a tuple of
      // (child-bus-address, parent-bus-address, size). The number of 32-bit cells
      // for each part of the tuple is defined by the '#address-cells' and '#size-cells'
      // properties.
      //
      UINT32  ChildAddrCells = AddressCells;

      UINT32  ParentAddrCells = AddressCells;
      INT32   ParentNode      = FdtParentOffset (Fdt, Node);
      if (ParentNode >= 0) {
        PropertyPtr = FdtGetProperty (Fdt, ParentNode, "#address-cells", &TempLen);
        if ((PropertyPtr != NULL) && (TempLen > 0)) {
          ParentAddrCells = Fdt32ToCpu (*(UINT32 *)PropertyPtr->Data);
        }
      }

      UINT32  SizeCells = 2;
      PropertyPtr = FdtGetProperty (Fdt, Node, "#size-cells", &TempLen);
      if ((PropertyPtr != NULL) && (TempLen > 0)) {
        SizeCells = Fdt32ToCpu (*(UINT32 *)PropertyPtr->Data);
      }

      UINT32  TripletCells = ChildAddrCells + ParentAddrCells + SizeCells;

      for (Base = 0; Base < TempLen / sizeof (UINT32); Base = Base + TripletCells) {
        UINT64  ParentBusAddress = 0;
        UINT64  DmaRangeSize     = 0;
        UINT32  ParentBase       = Base + ChildAddrCells;
        if (ParentAddrCells == 2) {
          ParentBusAddress = (UINT64)Fdt32ToCpu (*(Data32 + ParentBase)) << 32 |
                             (UINT64)Fdt32ToCpu (*(Data32 + ParentBase + 1));
        } else if (ParentAddrCells == 1) {
          ParentBusAddress = Fdt32ToCpu (*(Data32 + ParentBase));
        }

        UINT32  SizeBase = Base + ChildAddrCells + ParentAddrCells;
        if (SizeCells == 2) {
          DmaRangeSize = (UINT64)Fdt32ToCpu (*(Data32 + SizeBase)) << 32 |
                         (UINT64)Fdt32ToCpu (*(Data32 + SizeBase + 1));
        } else if (SizeCells == 1) {
          DmaRangeSize = Fdt32ToCpu (*(Data32 + SizeBase));
        }

        if ((ParentBusAddress > 0xFFFFFFFF) ||
            ((ParentBusAddress + DmaRangeSize - 1) > 0xFFFFFFFF))
        {
          mPciRootBridgeInfo->RootBridge[RbIndex].DmaAbove4G = TRUE;
          DEBUG ((
            DEBUG_INFO,
            "DMA Above 4G supported: Parent=0x%llx, Size=0x%llx\n",
            ParentBusAddress,
            DmaRangeSize
            ));
          break;
        }
      }
    }

    if (AsciiStrCmp (TempStr, "reg") == 0) {
      UINT64  *Data64 = (UINT64 *)(PropertyPtr->Data);
      mUplPciSegmentInfoHob->SegmentInfo[RbIndex].BaseAddress = Fdt64ToCpu (ReadUnaligned64 (Data64));
      DEBUG ((DEBUG_INFO, "PciRootBridge->Ecam.Base %llx, \n", mUplPciSegmentInfoHob->SegmentInfo[RbIndex].BaseAddress));
    }

    if (AsciiStrCmp (TempStr, "bus-range") == 0) {
      Data32                                                  = (UINT32 *)(PropertyPtr->Data);
      mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Base        = Fdt32ToCpu (*Data32) & 0xFF;
      mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Limit       = Fdt32ToCpu (*(Data32 + 1)) & 0xFF;
      mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Translation = 0;

      DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.Base %x, index %x\n", mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Base, RbIndex));
      DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.limit %x, index %x\n", mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Limit, RbIndex));
    }
  }

  if (RbIndex > 0) {
    RbIndex--;
  }

  *index = RbIndex;
}

/**
  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;
  UINT64                *Data64;
  UINT64                StartAddress;
  UINT64                NumberOfBytes;
  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;
  UINT8                 PciEnumDone;
  UINT8                 NodeType;
  EFI_BOOT_MODE         BootMode;
  CHAR8                 *GmaStr;
  INTN                  NumRsv;
  EFI_PHYSICAL_ADDRESS  Addr;
  UINT64                Size;
  UINT16                SegmentNumber;
  UINT64                CurrentPciBaseAddress;
  UINT64                NextPciBaseAddress;
  UINT8                 *RbSegNumAlreadyAssigned;
  UINT8                 NumberOfRbSegNumAlreadyAssigned;
  UINT32                RootAddressCells;
  INT32                 ParentNode;

  Fdt               = FdtBase;
  Depth             = 0;
  MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
  IsHobConstructed  = FALSE;
  NewHobList        = 0;
  RootBridgeCount   = 0;
  index             = 0;
  // TODO: This value comes from FDT. Currently there is a bug in implementation
  // which assumes node ordering. Which requires a fix.
  PciEnumDone      = 1;
  BootMode         = 0;
  NodeType         = 0;
  RootAddressCells = 2;

  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));

  PropertyPtr = FdtGetProperty (Fdt, 0, "#address-cells", &TempLen);
  if ((PropertyPtr != NULL) && (TempLen > 0)) {
    RootAddressCells = Fdt32ToCpu (*(UINT32 *)PropertyPtr->Data);
    DEBUG ((DEBUG_INFO, " root #address-cells = 0x%x\n", RootAddressCells));
  }

  for (Node = FdtNextNode (Fdt, 0, &Depth); Node >= 0; Node = FdtNextNode (Fdt, Node, &Depth)) {
    NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + Node + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
    DEBUG ((DEBUG_INFO, "\n   Node(%08x)  %a   Depth %x\n", 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 (ReadUnaligned64 (Data64));
          NumberOfBytes = Fdt64ToCpu (ReadUnaligned64 (Data64 + 1));
          DEBUG ((DEBUG_INFO, "\n         Property(%08X)  %a", Property, TempStr));
          DEBUG ((DEBUG_INFO, "  %016lX  %016lX", StartAddress, NumberOfBytes));
          // If parent node type is reserved-memory we are looking at special-purpose memory. Ignore it.
          ParentNode = FdtParentOffset (Fdt, Node);
          NodePtr    = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + ParentNode + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
          NodeType   = CheckNodeType (NodePtr->Name, Depth);
          if (!IsHobConstructed && (NodeType != ReservedMemory)) {
            if (NumberOfBytes > MinimalNeededSize) {
              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;
            }
          }
        }
      }
    } else {
      PropertyPtr = FdtGetProperty (Fdt, Node, "compatible", &TempLen);
      if (PropertyPtr == NULL) {
        continue;
      }

      TempStr = (CHAR8 *)(PropertyPtr->Data);
      if (AsciiStrnCmp (TempStr, "pci-rb", AsciiStrLen ("pci-rb")) == 0) {
        RootBridgeCount++;
      }
    }
  }

  NumRsv = FdtGetNumberOfReserveMapEntries (Fdt);
  /* Look for an existing entry and add it to the efi mem map. */
  for (index = 0; index < NumRsv; index++) {
    if (FdtGetReserveMapEntry (Fdt, index, &Addr, &Size) != 0) {
      continue;
    }

    BuildMemoryAllocationHob (Addr, Size, EfiReservedMemoryType);
  }

  index = RootBridgeCount - 1;
  Depth = 0;
  for (Node = FdtNextNode (Fdt, 0, &Depth); Node >= 0; Node = FdtNextNode (Fdt, Node, &Depth)) {
    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));

    NodeType = CheckNodeType (NodePtr->Name, Depth);
    DEBUG ((DEBUG_INFO, "NodeType :0x%x\n", NodeType));
    switch (NodeType) {
      case SerialPort:
        ParseSerialPort (Fdt, Node, RootAddressCells);
        break;
      case ReservedMemory:
        DEBUG ((DEBUG_INFO, "ParseReservedMemory\n"));
        ParseReservedMemory (Fdt, Node);
        break;
      case Memory:
        DEBUG ((DEBUG_INFO, "ParseMemory\n"));
        if (!CheckMemoryNodeIfInit (Node)) {
          ParseMemory (Fdt, Node);
        } else {
          DEBUG ((DEBUG_INFO, "Memory has initialized\n"));
        }

        break;
      case FrameBuffer:
        DEBUG ((DEBUG_INFO, "ParseFrameBuffer\n"));
        GmaStr = ParseFrameBuffer (Fdt, Node);
        break;
      case PciRootBridge:
        DEBUG ((DEBUG_INFO, "ParsePciRootBridge, index :%x \n", index));
        ParsePciRootBridge (Fdt, Node, RootBridgeCount, GmaStr, &index);
        DEBUG ((DEBUG_INFO, "After ParsePciRootBridge, index :%x\n", index));
        break;
      case Options:
        // FIXME: Need to ensure this node gets parsed first so that it gets
        // correct options to feed into other init like PciEnumDone etc.
        DEBUG ((DEBUG_INFO, "ParseOptions\n"));
        ParseOptions (Fdt, Node, &PciEnumDone, &BootMode);
        break;
      default:
        DEBUG ((DEBUG_INFO, "ParseNothing\n"));
        break;
    }
  }

  if ((NULL != mPciRootBridgeInfo) && (NULL != mUplPciSegmentInfoHob)) {
    // Post processing: TODO: Need to look into it. Such cross dependency on DT nodes
    // may not be good idea. Instead have this prop part of RB
    mPciRootBridgeInfo->ResourceAssigned = (BOOLEAN)PciEnumDone;

    //
    // Assign PCI Segment number after all root bridge info ready
    //
    SegmentNumber                   = 0;
    RbSegNumAlreadyAssigned         = AllocateZeroPool (sizeof (UINT8) * RootBridgeCount);
    NextPciBaseAddress              = 0;
    NumberOfRbSegNumAlreadyAssigned = 0;

    //
    // Always assign first root bridge segment number as 0
    //
    CurrentPciBaseAddress                               = mUplPciSegmentInfoHob->SegmentInfo[0].BaseAddress & ~0xFFFFFFF;
    NextPciBaseAddress                                  = CurrentPciBaseAddress;
    mUplPciSegmentInfoHob->SegmentInfo[0].SegmentNumber = SegmentNumber;
    mPciRootBridgeInfo->RootBridge[0].Segment           = SegmentNumber;
    RbSegNumAlreadyAssigned[0]                          = 1;
    NumberOfRbSegNumAlreadyAssigned++;

    while (NumberOfRbSegNumAlreadyAssigned < RootBridgeCount) {
      for (index = 1; index < RootBridgeCount; index++) {
        if (RbSegNumAlreadyAssigned[index] == 1) {
          continue;
        }

        if (CurrentPciBaseAddress == (mUplPciSegmentInfoHob->SegmentInfo[index].BaseAddress & ~0xFFFFFFF)) {
          mUplPciSegmentInfoHob->SegmentInfo[index].SegmentNumber = SegmentNumber;
          mPciRootBridgeInfo->RootBridge[index].Segment           = SegmentNumber;
          RbSegNumAlreadyAssigned[index]                          = 1;
          NumberOfRbSegNumAlreadyAssigned++;
        } else if (CurrentPciBaseAddress == NextPciBaseAddress) {
          NextPciBaseAddress = mUplPciSegmentInfoHob->SegmentInfo[index].BaseAddress & ~0xFFFFFFF;
        }
      }

      SegmentNumber++;
      CurrentPciBaseAddress = NextPciBaseAddress;
    }
  }

  ((EFI_HOB_HANDOFF_INFO_TABLE *)(mHobList))->BootMode = BootMode;
  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 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;
}
