public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [PATCH] UefiPayloadPkg: Remove PEI phase from Payload
@ 2020-11-10 18:39 Guo Dong
  0 siblings, 0 replies; 2+ messages in thread
From: Guo Dong @ 2020-11-10 18:39 UTC (permalink / raw)
  To: devel; +Cc: maurice.ma, benjamin.you

It is not necessary to have a PEI phase in the UEFI payload since no
specific PEI task is required. This patch adds a UefiPayloadEntry
driver to get UEFI Payload required information from the bootloaders,
convert them into a HOB list, load DXE core and transfer control to it.

Here is the change details:
1) Removed PEI phase, including Peicore, BlSupportPei, SecCore, etc.
2) Added UefiPayloadEntry driver. this is the only driver before DXE core.
3) Added Pure X64 support, dropped Pure IA32 (Could add later if required)
   64bit payload with 32bit entry point is still supported.
4) Use one DSC file UefiPayloadPkg.dsc to support X64 and IA32X64 build.
   Removed UefiPayloadIa32.dsc and UefiPayloadIa32X64.dsc

Tested with SBL and coreboot on QEMU.

Signed-off-by: Guo Dong <guo.dong@intel.com>
---
 UefiPayloadPkg/BlSupportPei/BlSupportPei.h                                          |  39 ---------------------------------------
 UefiPayloadPkg/BlSupportPei/BlSupportPei.inf                                        |  73 -------------------------------------------------------------------------
 UefiPayloadPkg/BuildAndIntegrationInstructions.txt                                  |  32 +++++++++++++++-----------------
 UefiPayloadPkg/Include/Library/BlParseLib.h                                         |   4 ++--
 UefiPayloadPkg/Library/HobLib/Hob.c                                                 | 680 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/Library/HobLib/HobLib.inf                                            |  39 +++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/SecCore/FindPeiCore.c                                                | 193 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 UefiPayloadPkg/SecCore/Ia32/SecEntry.nasm                                           |  78 ------------------------------------------------------------------------------
 UefiPayloadPkg/SecCore/Ia32/Stack.nasm                                              |  72 ------------------------------------------------------------------------
 UefiPayloadPkg/SecCore/SecCore.inf                                                  |  58 ----------------------------------------------------------
 UefiPayloadPkg/SecCore/SecMain.c                                                    | 288 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 UefiPayloadPkg/SecCore/SecMain.h                                                    | 131 -----------------------------------------------------------------------------------------------------------------------------------
 UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c                                  | 364 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/UefiPayloadEntry/Ia32/IdtVectorAsm.nasm                              |  71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/UefiPayloadEntry/Ia32/SecEntry.nasm                                  |  46 ++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c                                       | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c                                  | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/{BlSupportPei/BlSupportPei.c => UefiPayloadEntry/UefiPayloadEntry.c} | 446 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h                                  |  85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf                                |  91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c                                   |  98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/UefiPayloadEntry/X64/SecEntry.nasm                                   |  47 +++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c                                 | 904 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h                                 | 322 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 UefiPayloadPkg/UefiPayloadPkg.dec                                                   |   5 +++--
 UefiPayloadPkg/{UefiPayloadPkgIa32X64.dsc => UefiPayloadPkg.dsc}                    |  57 +++++++++++++++------------------------------------------
 UefiPayloadPkg/UefiPayloadPkg.fdf                                                   |  30 ++++++++----------------------
 UefiPayloadPkg/UefiPayloadPkgIa32.dsc                                               | 585 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 28 files changed, 3415 insertions(+), 1904 deletions(-)

diff --git a/UefiPayloadPkg/BlSupportPei/BlSupportPei.h b/UefiPayloadPkg/BlSupportPei/BlSupportPei.h
deleted file mode 100644
index d11a3570a1..0000000000
--- a/UefiPayloadPkg/BlSupportPei/BlSupportPei.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/** @file
-  The header file of bootloader support PEIM.
-
-Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-
-#ifndef __PEI_BOOTLOADER_SUPPORT_H__
-#define __PEI_BOOTLOADER_SUPPORT_H__
-
-#include <PiPei.h>
-#include <Library/PeimEntryPoint.h>
-#include <Library/PeiServicesLib.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/HobLib.h>
-#include <Library/PcdLib.h>
-#include <Library/BlParseLib.h>
-#include <Library/MtrrLib.h>
-#include <Library/IoLib.h>
-#include <Library/PlatformSupportLib.h>
-#include <IndustryStandard/Acpi.h>
-#include <Guid/MemoryTypeInformation.h>
-#include <Guid/FirmwareFileSystem2.h>
-#include <Guid/SystemTableInfoGuid.h>
-#include <Guid/AcpiBoardInfoGuid.h>
-#include <Guid/GraphicsInfoHob.h>
-#include <Ppi/MasterBootMode.h>
-#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
-
-typedef struct {
-  UINT32  UsableLowMemTop;
-  UINT32  SystemLowMemTop;
-} PAYLOAD_MEM_INFO;
-
-#endif
diff --git a/UefiPayloadPkg/BlSupportPei/BlSupportPei.inf b/UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
deleted file mode 100644
index 711fe63fe6..0000000000
--- a/UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
+++ /dev/null
@@ -1,73 +0,0 @@
-## @file
-# Bootloader Support PEI Module
-#
-# Parses bootloader information and report resource information into pei core. It will install
-# the memory as required.
-#
-#  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
-#
-#  SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
-  INF_VERSION                    = 0x00010005
-  BASE_NAME                      = BlSupportPeim
-  FILE_GUID                      = 352C6AF8-315B-4bd6-B04F-31D4ED1EBE57
-  MODULE_TYPE                    = PEIM
-  VERSION_STRING                 = 1.0
-  ENTRY_POINT                    = BlPeiEntryPoint
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-#  VALID_ARCHITECTURES           = IA32 X64
-#
-
-[Sources]
-  BlSupportPei.c
-  BlSupportPei.h
-
-[Packages]
-  MdePkg/MdePkg.dec
-  MdeModulePkg/MdeModulePkg.dec
-  IntelFsp2Pkg/IntelFsp2Pkg.dec
-  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
-  UefiPayloadPkg/UefiPayloadPkg.dec
-  UefiCpuPkg/UefiCpuPkg.dec
-
-[LibraryClasses]
-  PeimEntryPoint
-  PeiServicesLib
-  BaseLib
-  BaseMemoryLib
-  DebugLib
-  HobLib
-  PcdLib
-  BlParseLib
-  MtrrLib
-  IoLib
-  PlatformSupportLib
-
-[Guids]
-  gEfiMemoryTypeInformationGuid
-  gEfiFirmwareFileSystem2Guid
-  gUefiSystemTableInfoGuid
-  gEfiGraphicsInfoHobGuid
-  gEfiGraphicsDeviceInfoHobGuid
-  gUefiAcpiBoardInfoGuid
-
-[Ppis]
-  gEfiPeiMasterBootModePpiGuid
-
-[Pcd]
-  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
-  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
-  gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
-  gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
-  gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
-  gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
-  gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
-
-[Depex]
-  TRUE
diff --git a/UefiPayloadPkg/BuildAndIntegrationInstructions.txt b/UefiPayloadPkg/BuildAndIntegrationInstructions.txt
index 2cacd48904..7512486590 100644
--- a/UefiPayloadPkg/BuildAndIntegrationInstructions.txt
+++ b/UefiPayloadPkg/BuildAndIntegrationInstructions.txt
@@ -1,6 +1,6 @@
 ================================================================================
 Build And Integration Instructions
-2019 March 27th
+2020 Aug 1st
 ================================================================================
 
 ================================================================================
@@ -35,27 +35,25 @@ integrate it into coreboot or Slim Bootloader firmware.
 B. HOW TO BUILD
 ================================================================================
 1. Run the below two commands in windows command prompt window:
-   edksetup.bat
+   > edksetup.bat
 
-   For debug ia32 build:
-   build -a IA32 -p UefiPayloadPkg\UefiPayloadPkgIa32.dsc -b DEBUG -t <ToolChain> -D BOOTLOADER=<Bootloader>
+   For pure X64 build:
+   > build -a x64 -p UefiPayloadPkg\UefiPayloadPkg.dsc -b <BuildType> -t <ToolChain>
+     -D BOOTLOADER=<Bootloader>
 
-   For release ia32 build:
-   build -a IA32 -p UefiPayloadPkg\UefiPayloadPkgIa32.dsc -b RELEASE -t <ToolChain> -D BOOTLOADER=<Bootloader>
+   For X64 build with IA32 entry point:
+   > build -a IA32 -a X64 -p UefiPayloadPkg\UefiPayloadPkg.dsc -b <BuildType> -t <ToolChain>
+     -D BOOTLOADER=<Bootloader>
 
-   For debug X64 build:
-   build -a IA32 -a X64 -p UefiPayloadPkg\UefiPayloadPkgIa32X64.dsc -b DEBUG -t <ToolChain> -D BOOTLOADER=<Bootloader>
-
-   For release X64 build:
-   build -a IA32 -a X64 -p UefiPayloadPkg\UefiPayloadPkgIa32X64.dsc -b RELEASE -t <ToolChain> -D BOOTLOADER=<Bootloader>
-
-   <ToolChain> is the EDK II build environment on your host. Currently it was tested
-   with VS2015x86 toolchain.
+   <BuildType> support 'DEBUG', 'RELEASE' and 'NOOPT'.
+   <ToolChain> is the EDK II build environment on your host. Tested with VS2015x86 toolchain.
    <Bootloader> could be "SBL" for Slim Bootloader and "COREBOOT" for coreboot.
 
    Refer to https://github.com/tianocore/tianocore.github.io/wiki/UDK2018-How-to-Build for
    details about EDK II build steps.
 
+   NOTE: Pure 32bit UEFI payload support could be added if required later.
+
 2. If build is successfully, the payload image (UEFIPAYLOAD.fd) will be generated inside the
    folder of Build\UefiPayloadPkg.
 
@@ -65,9 +63,9 @@ C. HOW TO INTEGRATE INTO COREBOOT
 1. Copy the payload image (UEFIPAYLOAD.fd) into the top-level directory of Coreboot source tree.
 2. Run "make menuconfig" in linux console to start Coreboot configuration surface.
 3. In the Payload section,
-   1) Choose "An ELF executable payload" for the option of "Add a payload".
-   2) Type the path of payload image for the option of "Payload path and filename".
-   3) Select the option of "Use LZMA compression for payloads".
+   1) Choose "Tianocore Payload" for the option of "Add a payload".
+   2) Update the path of payload image for the option of "Tianocore binary".
+   3) Choose "UEFIPayload" for the option of "Tianocore Payload".
 4. If the graphics console is required in UEFI payload, enable framebuffer initialization in coreboot.
    This could be done by enabling native graphics or using VGA BIOS option rom.
 5. Build the coreboot firmware image.
diff --git a/UefiPayloadPkg/Include/Library/BlParseLib.h b/UefiPayloadPkg/Include/Library/BlParseLib.h
index 3f9e591ede..20a526d15c 100644
--- a/UefiPayloadPkg/Include/Library/BlParseLib.h
+++ b/UefiPayloadPkg/Include/Library/BlParseLib.h
@@ -2,7 +2,7 @@
   This library will parse the coreboot table in memory and extract those required
   information.
 
-  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -16,7 +16,7 @@
 #ifndef __BOOTLOADER_PARSE_LIB__
 #define __BOOTLOADER_PARSE_LIB__
 
-#define GET_BOOTLOADER_PARAMETER()      (*(UINT32 *)(UINTN)(PcdGet32(PcdPayloadStackTop) - sizeof(UINT32)))
+#define GET_BOOTLOADER_PARAMETER()      (*(UINTN *)(UINTN)(PcdGet32(PcdPayloadStackTop) - sizeof(UINT64)))
 #define SET_BOOTLOADER_PARAMETER(Value) GET_BOOTLOADER_PARAMETER()=Value
 
 typedef RETURN_STATUS \
diff --git a/UefiPayloadPkg/Library/HobLib/Hob.c b/UefiPayloadPkg/Library/HobLib/Hob.c
new file mode 100644
index 0000000000..308fca5c23
--- /dev/null
+++ b/UefiPayloadPkg/Library/HobLib/Hob.c
@@ -0,0 +1,680 @@
+/** @file
+
+  Copyright (c) 2010, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2017 - 2020, 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/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+
+VOID      *mHobList;
+
+/**
+  Returns the pointer to the HOB list.
+
+  This function returns the pointer to first HOB in the list.
+
+  @return The pointer to the HOB list.
+
+**/
+VOID *
+EFIAPI
+GetHobList (
+  VOID
+  )
+{
+  ASSERT (mHobList != NULL);
+  return mHobList;
+}
+
+EFI_HOB_HANDOFF_INFO_TABLE*
+EFIAPI
+HobConstructor (
+  IN VOID   *EfiMemoryBegin,
+  IN UINTN  EfiMemoryLength,
+  IN VOID   *EfiFreeMemoryBottom,
+  IN VOID   *EfiFreeMemoryTop
+  )
+{
+  EFI_HOB_HANDOFF_INFO_TABLE  *Hob;
+  EFI_HOB_GENERIC_HEADER      *HobEnd;
+
+  Hob    = EfiFreeMemoryBottom;
+  HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
+
+  Hob->Header.HobType      = EFI_HOB_TYPE_HANDOFF;
+  Hob->Header.HobLength    = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
+  Hob->Header.Reserved     = 0;
+
+  HobEnd->HobType          = EFI_HOB_TYPE_END_OF_HOB_LIST;
+  HobEnd->HobLength        = sizeof(EFI_HOB_GENERIC_HEADER);
+  HobEnd->Reserved         = 0;
+
+  Hob->Version             = EFI_HOB_HANDOFF_TABLE_VERSION;
+  Hob->BootMode            = BOOT_WITH_FULL_CONFIGURATION;
+
+  Hob->EfiMemoryTop        = (UINTN)EfiMemoryBegin + EfiMemoryLength;
+  Hob->EfiMemoryBottom     = (UINTN)EfiMemoryBegin;
+  Hob->EfiFreeMemoryTop    = (UINTN)EfiFreeMemoryTop;
+  Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
+  Hob->EfiEndOfHobList     = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
+
+  mHobList = Hob;
+  return Hob;
+}
+
+VOID *
+EFIAPI
+CreateHob (
+  IN  UINT16    HobType,
+  IN  UINT16    HobLength
+  )
+{
+  EFI_HOB_HANDOFF_INFO_TABLE  *HandOffHob;
+  EFI_HOB_GENERIC_HEADER      *HobEnd;
+  EFI_PHYSICAL_ADDRESS        FreeMemory;
+  VOID                        *Hob;
+
+  HandOffHob = GetHobList ();
+
+  HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
+
+  FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
+
+  if (FreeMemory < HobLength) {
+      return NULL;
+  }
+
+  Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
+  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
+  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
+  ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
+
+  HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
+  HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+  HobEnd->HobType   = EFI_HOB_TYPE_END_OF_HOB_LIST;
+  HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+  HobEnd->Reserved  = 0;
+  HobEnd++;
+  HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+  return Hob;
+}
+
+/**
+  Builds a HOB that describes a chunk of system memory.
+
+  This function builds a HOB that describes a chunk of system memory.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  ResourceType        The type of resource described by this HOB.
+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorHob (
+  IN EFI_RESOURCE_TYPE            ResourceType,
+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
+  IN UINT64                       NumberOfBytes
+  )
+{
+  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;
+
+  Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
+  ASSERT(Hob != NULL);
+
+  Hob->ResourceType      = ResourceType;
+  Hob->ResourceAttribute = ResourceAttribute;
+  Hob->PhysicalStart     = PhysicalStart;
+  Hob->ResourceLength    = NumberOfBytes;
+}
+
+VOID
+EFIAPI
+BuildFvHobs (
+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
+  IN UINT64                       NumberOfBytes,
+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  *ResourceAttribute
+  )
+{
+
+  EFI_RESOURCE_ATTRIBUTE_TYPE Resource;
+
+  BuildFvHob (PhysicalStart, NumberOfBytes);
+
+  if (ResourceAttribute == NULL) {
+    Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
+                EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+                EFI_RESOURCE_ATTRIBUTE_TESTED |
+                EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);
+  } else {
+    Resource = *ResourceAttribute;
+  }
+
+  BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes);
+}
+
+/**
+  Returns the next instance of a HOB type from the starting HOB.
+
+  This function searches the first instance of a HOB type from the starting HOB pointer.
+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
+  If HobStart is NULL, then ASSERT().
+
+  @param  Type          The HOB type to return.
+  @param  HobStart      The starting HOB pointer to search from.
+
+  @return The next instance of a HOB type from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetNextHob (
+  IN UINT16                 Type,
+  IN CONST VOID             *HobStart
+  )
+{
+  EFI_PEI_HOB_POINTERS  Hob;
+
+  ASSERT (HobStart != NULL);
+
+  Hob.Raw = (UINT8 *) HobStart;
+  //
+  // Parse the HOB list until end of list or matching type is found.
+  //
+  while (!END_OF_HOB_LIST (Hob)) {
+    if (Hob.Header->HobType == Type) {
+      return Hob.Raw;
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+  return NULL;
+}
+
+
+
+/**
+  Returns the first instance of a HOB type among the whole HOB list.
+
+  This function searches the first instance of a HOB type among the whole HOB list.
+  If there does not exist such HOB type in the HOB list, it will return NULL.
+
+  @param  Type          The HOB type to return.
+
+  @return The next instance of a HOB type from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetFirstHob (
+  IN UINT16                 Type
+  )
+{
+  VOID      *HobList;
+
+  HobList = GetHobList ();
+  return GetNextHob (Type, HobList);
+}
+
+
+/**
+  This function searches the first instance of a HOB from the starting HOB pointer.
+  Such HOB should satisfy two conditions:
+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
+  If there does not exist such HOB from the starting HOB pointer, it will return NULL.
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
+  to extract the data section and its size info respectively.
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
+  If Guid is NULL, then ASSERT().
+  If HobStart is NULL, then ASSERT().
+
+  @param  Guid          The GUID to match with in the HOB list.
+  @param  HobStart      A pointer to a Guid.
+
+  @return The next instance of the matched GUID HOB from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetNextGuidHob (
+  IN CONST EFI_GUID         *Guid,
+  IN CONST VOID             *HobStart
+  ){
+  EFI_PEI_HOB_POINTERS  GuidHob;
+
+  GuidHob.Raw = (UINT8 *) HobStart;
+  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
+    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
+      break;
+    }
+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);
+  }
+  return GuidHob.Raw;
+}
+
+
+/**
+  This function searches the first instance of a HOB among the whole HOB list.
+  Such HOB should satisfy two conditions:
+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
+  If there does not exist such HOB from the starting HOB pointer, it will return NULL.
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
+  to extract the data section and its size info respectively.
+  If Guid is NULL, then ASSERT().
+
+  @param  Guid          The GUID to match with in the HOB list.
+
+  @return The first instance of the matched GUID HOB among the whole HOB list.
+
+**/
+VOID *
+EFIAPI
+GetFirstGuidHob (
+  IN CONST EFI_GUID         *Guid
+  )
+{
+  VOID      *HobList;
+
+  HobList = GetHobList ();
+  return GetNextGuidHob (Guid, HobList);
+}
+
+
+
+
+/**
+  Builds a HOB for a loaded PE32 module.
+
+  This function builds a HOB for a loaded PE32 module.
+  It can only be invoked during PEI phase;
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+  If ModuleName is NULL, then ASSERT().
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  ModuleName              The GUID File Name of the module.
+  @param  MemoryAllocationModule  The 64 bit physical address of the module.
+  @param  ModuleLength            The length of the module in bytes.
+  @param  EntryPoint              The 64 bit physical address of the module entry point.
+
+**/
+VOID
+EFIAPI
+BuildModuleHob (
+  IN CONST EFI_GUID         *ModuleName,
+  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,
+  IN UINT64                 ModuleLength,
+  IN EFI_PHYSICAL_ADDRESS   EntryPoint
+  )
+{
+  EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;
+
+  ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
+          ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
+
+  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
+
+  CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
+  Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
+  Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;
+  Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;
+
+  //
+  // Zero the reserved space to match HOB spec
+  //
+  ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
+
+  CopyGuid (&Hob->ModuleName, ModuleName);
+  Hob->EntryPoint = EntryPoint;
+}
+
+/**
+  Builds a GUID HOB with a certain data length.
+
+  This function builds a customized HOB tagged with a GUID for identification
+  and returns the start address of GUID HOB data so that caller can fill the customized data.
+  The HOB Header and Name field is already stripped.
+  It can only be invoked during PEI phase;
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+  If Guid is NULL, then ASSERT().
+  If there is no additional space for HOB creation, then ASSERT().
+  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
+
+  @param  Guid          The GUID to tag the customized HOB.
+  @param  DataLength    The size of the data payload for the GUID HOB.
+
+  @return The start address of GUID HOB data.
+
+**/
+VOID *
+EFIAPI
+BuildGuidHob (
+  IN CONST EFI_GUID              *Guid,
+  IN UINTN                       DataLength
+  )
+{
+  EFI_HOB_GUID_TYPE *Hob;
+
+  //
+  // Make sure that data length is not too long.
+  //
+  ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
+
+  Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
+  CopyGuid (&Hob->Name, Guid);
+  return Hob + 1;
+}
+
+
+/**
+  Copies a data buffer to a newly-built HOB.
+
+  This function builds a customized HOB tagged with a GUID for identification,
+  copies the input data to the HOB data field and returns the start address of the GUID HOB data.
+  The HOB Header and Name field is already stripped.
+  It can only be invoked during PEI phase;
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+  If Guid is NULL, then ASSERT().
+  If Data is NULL and DataLength > 0, then ASSERT().
+  If there is no additional space for HOB creation, then ASSERT().
+  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
+
+  @param  Guid          The GUID to tag the customized HOB.
+  @param  Data          The data to be copied into the data field of the GUID HOB.
+  @param  DataLength    The size of the data payload for the GUID HOB.
+
+  @return The start address of GUID HOB data.
+
+**/
+VOID *
+EFIAPI
+BuildGuidDataHob (
+  IN CONST EFI_GUID              *Guid,
+  IN VOID                        *Data,
+  IN UINTN                       DataLength
+  )
+{
+  VOID  *HobData;
+
+  ASSERT (Data != NULL || DataLength == 0);
+
+  HobData = BuildGuidHob (Guid, DataLength);
+
+  return CopyMem (HobData, Data, DataLength);
+}
+
+
+/**
+  Builds a Firmware Volume HOB.
+
+  This function builds a Firmware Volume HOB.
+  It can only be invoked during PEI phase;
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  BaseAddress   The base address of the Firmware Volume.
+  @param  Length        The size of the Firmware Volume in bytes.
+
+**/
+VOID
+EFIAPI
+BuildFvHob (
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                      Length
+  )
+{
+  EFI_HOB_FIRMWARE_VOLUME  *Hob;
+
+  Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
+
+  Hob->BaseAddress = BaseAddress;
+  Hob->Length      = Length;
+}
+
+
+/**
+  Builds a EFI_HOB_TYPE_FV2 HOB.
+
+  This function builds a EFI_HOB_TYPE_FV2 HOB.
+  It can only be invoked during PEI phase;
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  BaseAddress   The base address of the Firmware Volume.
+  @param  Length        The size of the Firmware Volume in bytes.
+  @param  FvName       The name of the Firmware Volume.
+  @param  FileName      The name of the file.
+
+**/
+VOID
+EFIAPI
+BuildFv2Hob (
+  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN          UINT64                      Length,
+  IN CONST    EFI_GUID                    *FvName,
+  IN CONST    EFI_GUID                    *FileName
+  )
+{
+  EFI_HOB_FIRMWARE_VOLUME2  *Hob;
+
+  Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
+
+  Hob->BaseAddress = BaseAddress;
+  Hob->Length      = Length;
+  CopyGuid (&Hob->FvName, FvName);
+  CopyGuid (&Hob->FileName, FileName);
+}
+
+/**
+  Builds a EFI_HOB_TYPE_FV3 HOB.
+
+  This function builds a EFI_HOB_TYPE_FV3 HOB.
+  It can only be invoked during PEI phase;
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param BaseAddress            The base address of the Firmware Volume.
+  @param Length                 The size of the Firmware Volume in bytes.
+  @param AuthenticationStatus   The authentication status.
+  @param ExtractedFv            TRUE if the FV was extracted as a file within
+                                another firmware volume. FALSE otherwise.
+  @param FvName                 The name of the Firmware Volume.
+                                Valid only if IsExtractedFv is TRUE.
+  @param FileName               The name of the file.
+                                Valid only if IsExtractedFv is TRUE.
+
+**/
+VOID
+EFIAPI
+BuildFv3Hob (
+  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN          UINT64                      Length,
+  IN          UINT32                      AuthenticationStatus,
+  IN          BOOLEAN                     ExtractedFv,
+  IN CONST    EFI_GUID                    *FvName, OPTIONAL
+  IN CONST    EFI_GUID                    *FileName OPTIONAL
+  )
+{
+  EFI_HOB_FIRMWARE_VOLUME3  *Hob;
+
+  Hob = CreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3));
+
+  Hob->BaseAddress          = BaseAddress;
+  Hob->Length               = Length;
+  Hob->AuthenticationStatus = AuthenticationStatus;
+  Hob->ExtractedFv          = ExtractedFv;
+  if (ExtractedFv) {
+    CopyGuid (&Hob->FvName, FvName);
+    CopyGuid (&Hob->FileName, FileName);
+  }
+}
+
+
+/**
+  Builds a HOB for the CPU.
+
+  This function builds a HOB for the CPU.
+  It can only be invoked during PEI phase;
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.
+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.
+
+**/
+VOID
+EFIAPI
+BuildCpuHob (
+  IN UINT8                       SizeOfMemorySpace,
+  IN UINT8                       SizeOfIoSpace
+  )
+{
+  EFI_HOB_CPU  *Hob;
+
+  Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
+
+  Hob->SizeOfMemorySpace = SizeOfMemorySpace;
+  Hob->SizeOfIoSpace     = SizeOfIoSpace;
+
+  //
+  // Zero the reserved space to match HOB spec
+  //
+  ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
+}
+
+
+/**
+  Builds a HOB for the Stack.
+
+  This function builds a HOB for the stack.
+  It can only be invoked during PEI phase;
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  BaseAddress   The 64 bit physical address of the Stack.
+  @param  Length        The length of the stack in bytes.
+
+**/
+VOID
+EFIAPI
+BuildStackHob (
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                      Length
+  )
+{
+  EFI_HOB_MEMORY_ALLOCATION_STACK  *Hob;
+
+  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
+          ((Length & (EFI_PAGE_SIZE - 1)) == 0));
+
+  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
+
+  CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
+  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+  Hob->AllocDescriptor.MemoryLength      = Length;
+  Hob->AllocDescriptor.MemoryType        = EfiBootServicesData;
+
+  //
+  // Zero the reserved space to match HOB spec
+  //
+  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
+}
+
+
+/**
+  Update the Stack Hob if the stack has been moved
+
+  @param  BaseAddress   The 64 bit physical address of the Stack.
+  @param  Length        The length of the stack in bytes.
+
+**/
+VOID
+EFIAPI
+UpdateStackHob (
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                      Length
+  )
+{
+  EFI_PEI_HOB_POINTERS           Hob;
+
+  Hob.Raw = GetHobList ();
+  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
+    if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
+      //
+      // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
+      // to be reclaimed by DXE core.
+      //
+      BuildMemoryAllocationHob (
+        Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
+        Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
+        EfiConventionalMemory
+        );
+      //
+      // Update the BSP Stack Hob to reflect the new stack info.
+      //
+      Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+      Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
+      break;
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+}
+
+
+
+/**
+  Builds a HOB for the memory allocation.
+
+  This function builds a HOB for the memory allocation.
+  It can only be invoked during PEI phase;
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+  If there is no additional space for HOB creation, then ASSERT().
+
+  @param  BaseAddress   The 64 bit physical address of the memory.
+  @param  Length        The length of the memory allocation in bytes.
+  @param  MemoryType    Type of memory allocated by this HOB.
+
+**/
+VOID
+EFIAPI
+BuildMemoryAllocationHob (
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                      Length,
+  IN EFI_MEMORY_TYPE             MemoryType
+  )
+{
+  EFI_HOB_MEMORY_ALLOCATION  *Hob;
+
+  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
+          ((Length & (EFI_PAGE_SIZE - 1)) == 0));
+
+  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
+
+  ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
+  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+  Hob->AllocDescriptor.MemoryLength      = Length;
+  Hob->AllocDescriptor.MemoryType        = MemoryType;
+  //
+  // Zero the reserved space to match HOB spec
+  //
+  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
+}
+
diff --git a/UefiPayloadPkg/Library/HobLib/HobLib.inf b/UefiPayloadPkg/Library/HobLib/HobLib.inf
new file mode 100644
index 0000000000..030e22a810
--- /dev/null
+++ b/UefiPayloadPkg/Library/HobLib/HobLib.inf
@@ -0,0 +1,39 @@
+#/** @file
+#
+#  Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = HobLib
+  FILE_GUID                      = AD6B4D55-8DBE-48C8-88E3-CFDBB6E9D193
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = HobLib
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources.common]
+  Hob.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiPayloadPkg/UefiPayloadPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+
+[Guids]
+  gEfiHobMemoryAllocModuleGuid
+  gEfiHobMemoryAllocStackGuid
+
diff --git a/UefiPayloadPkg/SecCore/FindPeiCore.c b/UefiPayloadPkg/SecCore/FindPeiCore.c
deleted file mode 100644
index f67d1afb96..0000000000
--- a/UefiPayloadPkg/SecCore/FindPeiCore.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/** @file
-  Locate the entry point for the PEI Core
-
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <PiPei.h>
-#include <Library/BaseLib.h>
-#include <Library/PeCoffGetEntryPointLib.h>
-
-#include "SecMain.h"
-
-/**
-  Find core image base.
-
-  @param   BootFirmwareVolumePtr    Point to the boot firmware volume.
-  @param   SecCoreImageBase         The base address of the SEC core image.
-  @param   PeiCoreImageBase         The base address of the PEI core image.
-
-**/
-EFI_STATUS
-EFIAPI
-FindImageBase (
-  IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
-  OUT EFI_PHYSICAL_ADDRESS             *SecCoreImageBase,
-  OUT EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
-  )
-{
-  EFI_PHYSICAL_ADDRESS        CurrentAddress;
-  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
-  EFI_FFS_FILE_HEADER         *File;
-  UINT32                      Size;
-  EFI_PHYSICAL_ADDRESS        EndOfFile;
-  EFI_COMMON_SECTION_HEADER   *Section;
-  EFI_PHYSICAL_ADDRESS        EndOfSection;
-
-  *SecCoreImageBase = 0;
-  *PeiCoreImageBase = 0;
-
-  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
-  EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
-
-  //
-  // Loop through the FFS files in the Boot Firmware Volume
-  //
-  for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
-
-    CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
-    if (CurrentAddress > EndOfFirmwareVolume) {
-      return EFI_NOT_FOUND;
-    }
-
-    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
-    if (IS_FFS_FILE2 (File)) {
-      Size = FFS_FILE2_SIZE (File);
-      if (Size <= 0x00FFFFFF) {
-        return EFI_NOT_FOUND;
-      }
-    } else {
-      Size = FFS_FILE_SIZE (File);
-      if (Size < sizeof (EFI_FFS_FILE_HEADER)) {
-        return EFI_NOT_FOUND;
-      }
-    }
-
-    EndOfFile = CurrentAddress + Size;
-    if (EndOfFile > EndOfFirmwareVolume) {
-      return EFI_NOT_FOUND;
-    }
-
-    //
-    // Look for SEC Core / PEI Core files
-    //
-    if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
-        File->Type != EFI_FV_FILETYPE_PEI_CORE) {
-      continue;
-    }
-
-    //
-    // Loop through the FFS file sections within the FFS file
-    //
-    if (IS_FFS_FILE2 (File)) {
-      EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER2));
-    } else {
-      EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER));
-    }
-    for (;;) {
-      CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
-      Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
-
-      if (IS_SECTION2 (Section)) {
-        Size = SECTION2_SIZE (Section);
-        if (Size <= 0x00FFFFFF) {
-          return EFI_NOT_FOUND;
-        }
-      } else {
-        Size = SECTION_SIZE (Section);
-        if (Size < sizeof (EFI_COMMON_SECTION_HEADER)) {
-          return EFI_NOT_FOUND;
-        }
-      }
-
-      EndOfSection = CurrentAddress + Size;
-      if (EndOfSection > EndOfFile) {
-        return EFI_NOT_FOUND;
-      }
-
-      //
-      // Look for executable sections
-      //
-      if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) {
-        if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
-          if (IS_SECTION2 (Section)) {
-            *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
-          } else {
-            *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
-          }
-        } else {
-          if (IS_SECTION2 (Section)) {
-            *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
-          } else {
-            *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
-          }
-        }
-        break;
-      }
-    }
-
-    //
-    // Both SEC Core and PEI Core images found
-    //
-    if (*SecCoreImageBase != 0 && *PeiCoreImageBase != 0) {
-      return EFI_SUCCESS;
-    }
-  }
-}
-
-/**
-  Find and return Pei Core entry point.
-
-  It also find SEC and PEI Core file debug information. It will report them if
-  remote debug is enabled.
-
-  @param   BootFirmwareVolumePtr    Point to the boot firmware volume.
-  @param   PeiCoreEntryPoint        The entry point of the PEI core.
-
-**/
-VOID
-EFIAPI
-FindAndReportEntryPoints (
-  IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
-  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
-  )
-{
-  EFI_STATUS                       Status;
-  EFI_PHYSICAL_ADDRESS             SecCoreImageBase;
-  EFI_PHYSICAL_ADDRESS             PeiCoreImageBase;
-  PE_COFF_LOADER_IMAGE_CONTEXT     ImageContext;
-
-  //
-  // Find SEC Core and PEI Core image base
-  //
-  Status = FindImageBase (BootFirmwareVolumePtr, &SecCoreImageBase, &PeiCoreImageBase);
-  ASSERT_EFI_ERROR (Status);
-
-  ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
-  //
-  // Report SEC Core debug information when remote debug is enabled
-  //
-  ImageContext.ImageAddress = SecCoreImageBase;
-  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
-  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
-
-  //
-  // Report PEI Core debug information when remote debug is enabled
-  //
-  ImageContext.ImageAddress = PeiCoreImageBase;
-  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
-  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
-
-  //
-  // Find PEI Core entry point
-  //
-  Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
-  if (EFI_ERROR (Status)) {
-    *PeiCoreEntryPoint = 0;
-  }
-
-  return;
-}
-
diff --git a/UefiPayloadPkg/SecCore/Ia32/SecEntry.nasm b/UefiPayloadPkg/SecCore/Ia32/SecEntry.nasm
deleted file mode 100644
index 877fc61ef0..0000000000
--- a/UefiPayloadPkg/SecCore/Ia32/SecEntry.nasm
+++ /dev/null
@@ -1,78 +0,0 @@
-;------------------------------------------------------------------------------
-;
-; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
-; SPDX-License-Identifier: BSD-2-Clause-Patent
-;
-; Abstract:
-;
-;   Entry point for the coreboot UEFI payload.
-;
-;------------------------------------------------------------------------------
-
-SECTION .text
-
-; C Functions
-extern  ASM_PFX(SecStartup)
-
-; Pcds
-extern  ASM_PFX(PcdGet32 (PcdPayloadFdMemBase))
-extern  ASM_PFX(PcdGet32 (PcdPayloadStackTop))
-
-;
-; SecCore Entry Point
-;
-; Processor is in flat protected mode
-;
-; @param[in]  EAX   Initial value of the EAX register (BIST: Built-in Self Test)
-; @param[in]  DI    'BP': boot-strap processor, or 'AP': application processor
-; @param[in]  EBP   Pointer to the start of the Boot Firmware Volume
-;
-; @return     None  This routine does not return
-;
-global ASM_PFX(_ModuleEntryPoint)
-ASM_PFX(_ModuleEntryPoint):
-  ;
-  ; Disable all the interrupts
-  ;
-  cli
-
-  ;
-  ; Save the Payload HOB base address before switching the stack
-  ;
-  mov     eax, [esp + 4]
-
-  ;
-  ; Construct the temporary memory at 0x80000, length 0x10000
-  ;
-  mov     esp, DWORD [ASM_PFX(PcdGet32 (PcdPayloadStackTop))]
-
-  ;
-  ; Push the Payload HOB base address onto new stack
-  ;
-  push    eax
-
-  ;
-  ; Pass BFV into the PEI Core
-  ;
-  push    DWORD [ASM_PFX(PcdGet32 (PcdPayloadFdMemBase))]
-
-  ;
-  ; Pass stack base into the PEI Core
-  ;
-  push    BASE_512KB
-
-  ;
-  ; Pass stack size into the PEI Core
-  ;
-  push    SIZE_64KB
-
-  ;
-  ; Pass Control into the PEI Core
-  ;
-  call    ASM_PFX(SecStartup)
-
-  ;
-  ; Should never return
-  ;
-  jmp     $
-
diff --git a/UefiPayloadPkg/SecCore/Ia32/Stack.nasm b/UefiPayloadPkg/SecCore/Ia32/Stack.nasm
deleted file mode 100644
index 55fd2243c8..0000000000
--- a/UefiPayloadPkg/SecCore/Ia32/Stack.nasm
+++ /dev/null
@@ -1,72 +0,0 @@
-;------------------------------------------------------------------------------
-;
-; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
-; SPDX-License-Identifier: BSD-2-Clause-Patent
-;
-; Abstract:
-;
-;   Switch the stack from temporary memory to permanent memory.
-;
-;------------------------------------------------------------------------------
-
-SECTION .text
-
-;------------------------------------------------------------------------------
-; VOID
-; EFIAPI
-; SecSwitchStack (
-;   UINT32   TemporaryMemoryBase,
-;   UINT32   PermenentMemoryBase
-;   );
-;------------------------------------------------------------------------------
-global ASM_PFX(SecSwitchStack)
-ASM_PFX(SecSwitchStack):
-    ;
-    ; Save three register: eax, ebx, ecx
-    ;
-    push  eax
-    push  ebx
-    push  ecx
-    push  edx
-
-    ;
-    ; !!CAUTION!! this function address's is pushed into stack after
-    ; migration of whole temporary memory, so need save it to permanent
-    ; memory at first!
-    ;
-
-    mov   ebx,  [esp + 20]          ; Save the first parameter
-    mov   ecx,  [esp + 24]          ; Save the second parameter
-
-    ;
-    ; Save this function's return address into permanent memory at first.
-    ; Then, Fixup the esp point to permanent memory
-    ;
-    mov   eax,  esp
-    sub   eax,  ebx
-    add   eax,  ecx
-    mov   edx,  [esp]               ; copy pushed register's value to permanent memory
-    mov   [eax], edx
-    mov   edx,  [esp + 4]
-    mov   [eax + 4], edx
-    mov   edx,  [esp + 8]
-    mov   [eax + 8], edx
-    mov   edx,  [esp + 12]
-    mov   [eax + 12], edx
-    mov   edx,  [esp + 16]          ; Update return address into permanent memory
-    mov   [eax + 16], edx
-    mov   esp,  eax                 ; From now, esp is pointed to permanent memory
-
-    ;
-    ; Fixup the ebp point to permanent memory
-    ;
-    mov   eax,  ebp
-    sub   eax,  ebx
-    add   eax,  ecx
-    mov   ebp,  eax                 ; From now, ebp is pointed to permanent memory
-
-    pop   edx
-    pop   ecx
-    pop   ebx
-    pop   eax
-    ret
diff --git a/UefiPayloadPkg/SecCore/SecCore.inf b/UefiPayloadPkg/SecCore/SecCore.inf
deleted file mode 100644
index 82ca7f567f..0000000000
--- a/UefiPayloadPkg/SecCore/SecCore.inf
+++ /dev/null
@@ -1,58 +0,0 @@
-## @file
-# This is the first module taking control from the coreboot.
-#
-#  Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.<BR>
-#
-#  SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
-  INF_VERSION                    = 0x00010005
-  BASE_NAME                      = SecCore
-  FILE_GUID                      = BA7BE337-6CFB-4dbb-B26C-21EC2FC16073
-  MODULE_TYPE                    = SEC
-  VERSION_STRING                 = 1.0
-
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-#  VALID_ARCHITECTURES           = IA32 X64 EBC
-#
-
-[Sources]
-  SecMain.c
-  SecMain.h
-  FindPeiCore.c
-
-[Sources.IA32]
-  Ia32/Stack.nasm
-  Ia32/SecEntry.nasm
-
-[Packages]
-  MdePkg/MdePkg.dec
-  MdeModulePkg/MdeModulePkg.dec
-  UefiCpuPkg/UefiCpuPkg.dec
-  UefiPayloadPkg/UefiPayloadPkg.dec
-
-[LibraryClasses]
-  BaseMemoryLib
-  DebugLib
-  BaseLib
-  PcdLib
-  DebugAgentLib
-  UefiCpuLib
-  PeCoffGetEntryPointLib
-  PeCoffExtraActionLib
-
-[Ppis]
-  gEfiSecPlatformInformationPpiGuid             # PPI ALWAYS_PRODUCED
-  gEfiTemporaryRamSupportPpiGuid                # PPI ALWAYS_PRODUCED
-  gEfiPayLoadHobBasePpiGuid                     # PPI ALWAYS_PRODUCED
-
-[Pcd]
-  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
-  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
-  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadStackTop
diff --git a/UefiPayloadPkg/SecCore/SecMain.c b/UefiPayloadPkg/SecCore/SecMain.c
deleted file mode 100644
index c0ca0e7d40..0000000000
--- a/UefiPayloadPkg/SecCore/SecMain.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/** @file
-  C functions in SEC
-
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-
-#include "SecMain.h"
-
-EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {
-  SecTemporaryRamSupport
-};
-
-EFI_PEI_PPI_DESCRIPTOR            mPeiSecPlatformInformationPpi[] = {
-  {
-    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
-    &gEfiTemporaryRamSupportPpiGuid,
-    &gSecTemporaryRamSupportPpi
-  }
-};
-
-//
-// These are IDT entries pointing to 10:FFFFFFE4h.
-//
-UINT64  mIdtEntryTemplate = 0xffff8e000010ffe4ULL;
-
-/**
-  Caller provided function to be invoked at the end of InitializeDebugAgent().
-
-  Entry point to the C language phase of SEC. After the SEC assembly
-  code has initialized some temporary memory and set up the stack,
-  the control is transferred to this function.
-
-  @param[in] Context    The first input parameter of InitializeDebugAgent().
-
-**/
-VOID
-EFIAPI
-SecStartupPhase2(
-  IN VOID                     *Context
-  );
-
-
-/**
-
-  Entry point to the C language phase of SEC. After the SEC assembly
-  code has initialized some temporary memory and set up the stack,
-  the control is transferred to this function.
-
-
-  @param SizeOfRam           Size of the temporary memory available for use.
-  @param TempRamBase         Base address of temporary ram
-  @param BootFirmwareVolume  Base address of the Boot Firmware Volume.
-  @param BootloaderParameter A parameter from bootloader, e.g. HobList from SlimBootloader
-
-**/
-VOID
-EFIAPI
-SecStartup (
-  IN UINT32                   SizeOfRam,
-  IN UINT32                   TempRamBase,
-  IN VOID                     *BootFirmwareVolume,
-  IN UINT32                   BootloaderParameter
-  )
-{
-  EFI_SEC_PEI_HAND_OFF        SecCoreData;
-  IA32_DESCRIPTOR             IdtDescriptor;
-  SEC_IDT_TABLE               IdtTableInStack;
-  UINT32                      Index;
-  UINT32                      PeiStackSize;
-
-  PeiStackSize = (SizeOfRam >> 1);
-
-  ASSERT (PeiStackSize < SizeOfRam);
-
-  //
-  // Process all libraries constructor function linked to SecCore.
-  //
-  ProcessLibraryConstructorList ();
-
-  //
-  // Initialize floating point operating environment
-  // to be compliant with UEFI spec.
-  //
-  InitializeFloatingPointUnits ();
-
-
-  // |-------------------|---->
-  // |Idt Table          |
-  // |-------------------|
-  // |PeiService Pointer |    PeiStackSize
-  // |-------------------|
-  // |                   |
-  // |      Stack        |
-  // |-------------------|---->
-  // |                   |
-  // |                   |
-  // |      Heap         |    PeiTemporaryRamSize
-  // |                   |
-  // |                   |
-  // |-------------------|---->  TempRamBase
-
-  IdtTableInStack.PeiService = 0;
-  for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
-    CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&mIdtEntryTemplate, sizeof (UINT64));
-  }
-
-  IdtDescriptor.Base  = (UINTN) &IdtTableInStack.IdtTable;
-  IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
-
-  AsmWriteIdtr (&IdtDescriptor);
-
-  //
-  // Update the base address and length of Pei temporary memory
-  //
-  SecCoreData.DataSize               = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF);
-  SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;
-  SecCoreData.BootFirmwareVolumeSize = (UINTN)(0x100000000ULL - (UINTN) BootFirmwareVolume);
-  SecCoreData.TemporaryRamBase       = (VOID*)(UINTN) TempRamBase;
-  SecCoreData.TemporaryRamSize       = SizeOfRam;
-  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;
-  SecCoreData.PeiTemporaryRamSize    = SizeOfRam - PeiStackSize;
-  SecCoreData.StackBase              = (VOID*)(UINTN)(TempRamBase + SecCoreData.PeiTemporaryRamSize);
-  SecCoreData.StackSize              = PeiStackSize;
-
-  //
-  // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
-  //
-  InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);
-
-}
-
-/**
-  Caller provided function to be invoked at the end of InitializeDebugAgent().
-
-  Entry point to the C language phase of SEC. After the SEC assembly
-  code has initialized some temporary memory and set up the stack,
-  the control is transferred to this function.
-
-  @param[in] Context    The first input parameter of InitializeDebugAgent().
-
-**/
-VOID
-EFIAPI
-SecStartupPhase2(
-  IN VOID                     *Context
-  )
-{
-  EFI_SEC_PEI_HAND_OFF        *SecCoreData;
-  EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;
-
-  SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
-  //
-  // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug
-  // is enabled.
-  //
-  FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint);
-  if (PeiCoreEntryPoint == NULL)
-  {
-    CpuDeadLoop ();
-  }
-
-  //
-  // Transfer the control to the PEI core
-  //
-  ASSERT (PeiCoreEntryPoint != NULL);
-  (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPeiSecPlatformInformationPpi);
-
-  //
-  // Should not come here.
-  //
-  return ;
-}
-
-/**
-  This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
-  permanent memory.
-
-  @param PeiServices            Pointer to the PEI Services Table.
-  @param TemporaryMemoryBase    Source Address in temporary memory from which the SEC or PEIM will copy the
-                                Temporary RAM contents.
-  @param PermanentMemoryBase    Destination Address in permanent memory into which the SEC or PEIM will copy the
-                                Temporary RAM contents.
-  @param CopySize               Amount of memory to migrate from temporary to permanent memory.
-
-  @retval EFI_SUCCESS           The data was successfully returned.
-  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
-                                TemporaryMemoryBase > PermanentMemoryBase.
-
-**/
-EFI_STATUS
-EFIAPI
-SecTemporaryRamSupport (
-  IN CONST EFI_PEI_SERVICES   **PeiServices,
-  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
-  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
-  IN UINTN                    CopySize
-  )
-{
-  IA32_DESCRIPTOR   IdtDescriptor;
-  VOID*             OldHeap;
-  VOID*             NewHeap;
-  VOID*             OldStack;
-  VOID*             NewStack;
-  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  DebugAgentContext;
-  BOOLEAN           OldStatus;
-  UINTN             PeiStackSize;
-
-  PeiStackSize = (CopySize >> 1);
-
-  ASSERT (PeiStackSize < CopySize);
-
-  //
-  // |-------------------|---->
-  // |      Stack        |    PeiStackSize
-  // |-------------------|---->
-  // |      Heap         |    PeiTemporaryRamSize
-  // |-------------------|---->  TempRamBase
-  //
-  // |-------------------|---->
-  // |      Heap         |    PeiTemporaryRamSize
-  // |-------------------|---->
-  // |      Stack        |    PeiStackSize
-  // |-------------------|---->  PermanentMemoryBase
-  //
-
-  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
-  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + PeiStackSize);
-
-  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize - PeiStackSize);
-  NewStack = (VOID*)(UINTN)PermanentMemoryBase;
-
-  DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
-  DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;
-
-  OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
-  //
-  // Initialize Debug Agent to support source level debug in PEI phase after memory ready.
-  // It will build HOB and fix up the pointer in IDT table.
-  //
-  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);
-
-  //
-  // Migrate Heap
-  //
-  CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize);
-
-  //
-  // Migrate Stack
-  //
-  CopyMem (NewStack, OldStack, PeiStackSize);
-
-
-  //
-  // We need *not* fix the return address because currently,
-  // The PeiCore is executed in flash.
-  //
-
-  //
-  // Rebase IDT table in permanent memory
-  //
-  AsmReadIdtr (&IdtDescriptor);
-  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
-
-  AsmWriteIdtr (&IdtDescriptor);
-
-
-  //
-  // Program MTRR
-  //
-
-  //
-  // SecSwitchStack function must be invoked after the memory migration
-  // immediately, also we need fixup the stack change caused by new call into
-  // permanent memory.
-  //
-  SecSwitchStack (
-    (UINT32) (UINTN) OldStack,
-    (UINT32) (UINTN) NewStack
-    );
-
-  SaveAndSetDebugTimerInterrupt (OldStatus);
-
-  return EFI_SUCCESS;
-}
-
diff --git a/UefiPayloadPkg/SecCore/SecMain.h b/UefiPayloadPkg/SecCore/SecMain.h
deleted file mode 100644
index ca0a95d03e..0000000000
--- a/UefiPayloadPkg/SecCore/SecMain.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/** @file
-  Master header file for SecCore.
-
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _SEC_CORE_H_
-#define _SEC_CORE_H_
-
-
-#include <PiPei.h>
-
-#include <Ppi/SecPlatformInformation.h>
-#include <Ppi/TemporaryRamSupport.h>
-
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/PcdLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiCpuLib.h>
-#include <Library/PeCoffGetEntryPointLib.h>
-#include <Library/PeCoffExtraActionLib.h>
-#include <Library/DebugAgentLib.h>
-
-
-#define SEC_IDT_ENTRY_COUNT  34
-
-typedef struct _SEC_IDT_TABLE {
-  //
-  // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base
-  // address should be 8-byte alignment.
-  // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store
-  // EFI_PEI_SERVICES**
-  //
-  UINT64            PeiService;
-  UINT64            IdtTable[SEC_IDT_ENTRY_COUNT];
-} SEC_IDT_TABLE;
-
-/**
-  Switch the stack in the temporary memory to the one in the permanent memory.
-
-  This function must be invoked after the memory migration immediately. The relative
-  position of the stack in the temporary and permanent memory is same.
-
-  @param TemporaryMemoryBase  Base address of the temporary memory.
-  @param PermenentMemoryBase  Base address of the permanent memory.
-**/
-VOID
-EFIAPI
-SecSwitchStack (
-  UINT32   TemporaryMemoryBase,
-  UINT32   PermenentMemoryBase
-  );
-
-/**
-  This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
-  permanent memory.
-
-  @param PeiServices            Pointer to the PEI Services Table.
-  @param TemporaryMemoryBase    Source Address in temporary memory from which the SEC or PEIM will copy the
-                                Temporary RAM contents.
-  @param PermanentMemoryBase    Destination Address in permanent memory into which the SEC or PEIM will copy the
-                                Temporary RAM contents.
-  @param CopySize               Amount of memory to migrate from temporary to permanent memory.
-
-  @retval EFI_SUCCESS           The data was successfully returned.
-  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
-                                TemporaryMemoryBase > PermanentMemoryBase.
-
-**/
-EFI_STATUS
-EFIAPI
-SecTemporaryRamSupport (
-  IN CONST EFI_PEI_SERVICES   **PeiServices,
-  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
-  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
-  IN UINTN                    CopySize
-  );
-
-/**
-  Entry point to the C language phase of SEC. After the SEC assembly
-  code has initialized some temporary memory and set up the stack,
-  the control is transferred to this function.
-
-  @param SizeOfRam           Size of the temporary memory available for use.
-  @param TempRamBase         Base address of temporary ram
-  @param BootFirmwareVolume  Base address of the Boot Firmware Volume.
-  @param BootloaderParameter A parameter from bootloader, e.g. HobList from SlimBootloader
-
-**/
-VOID
-EFIAPI
-SecStartup (
-  IN UINT32                   SizeOfRam,
-  IN UINT32                   TempRamBase,
-  IN VOID                     *BootFirmwareVolume,
-  IN UINT32                   BootloaderParameter
-  );
-
-/**
-  Find and return Pei Core entry point.
-
-  It also find SEC and PEI Core file debug information. It will report them if
-  remote debug is enabled.
-
-  @param  BootFirmwareVolumePtr  Point to the boot firmware volume.
-  @param  PeiCoreEntryPoint      Point to the PEI core entry point.
-
-**/
-VOID
-EFIAPI
-FindAndReportEntryPoints (
-  IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
-  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
-  );
-
-/**
-  Autogenerated function that calls the library constructors for all of the module's
-  dependent libraries.  This function must be called by the SEC Core once a stack has
-  been established.
-
-**/
-VOID
-EFIAPI
-ProcessLibraryConstructorList (
-  VOID
-  );
-
-#endif
diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
new file mode 100644
index 0000000000..73abe56982
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
@@ -0,0 +1,364 @@
+/** @file
+  Ia32-specific functionality for DxeLoad.
+
+Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include "VirtualMemory.h"
+#include "UefiPayloadEntry.h"
+
+#define STACK_SIZE            0x20000
+#define IDT_ENTRY_COUNT       32
+
+typedef struct _X64_IDT_TABLE {
+  //
+  // Reserved 4 bytes preceding PeiService and IdtTable,
+  // since IDT base address should be 8-byte alignment.
+  //
+  UINT32                   Reserved;
+  CONST EFI_PEI_SERVICES   **PeiService;
+  X64_IDT_GATE_DESCRIPTOR  IdtTable[IDT_ENTRY_COUNT];
+} X64_IDT_TABLE;
+
+//
+// Global Descriptor Table (GDT)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT gGdtEntries[] = {
+/* selector { Global Segment Descriptor                              } */
+/* 0x00 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, //null descriptor
+/* 0x08 */  {{0xffff, 0,  0,  0x2,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, //linear data segment descriptor
+/* 0x10 */  {{0xffff, 0,  0,  0xf,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, //linear code segment descriptor
+/* 0x18 */  {{0xffff, 0,  0,  0x3,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, //system data segment descriptor
+/* 0x20 */  {{0xffff, 0,  0,  0xa,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, //system code segment descriptor
+/* 0x28 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, //spare segment descriptor
+/* 0x30 */  {{0xffff, 0,  0,  0x2,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, //system data segment descriptor
+/* 0x38 */  {{0xffff, 0,  0,  0xa,  1,  0,  1,  0xf,  0,  1, 0,  1,  0}}, //system code segment descriptor
+/* 0x40 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, //spare segment descriptor
+};
+
+//
+// IA32 Gdt register
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR gGdt = {
+  sizeof (gGdtEntries) - 1,
+  (UINTN) gGdtEntries
+  };
+
+GLOBAL_REMOVE_IF_UNREFERENCED  IA32_DESCRIPTOR gLidtDescriptor = {
+  sizeof (X64_IDT_GATE_DESCRIPTOR) * IDT_ENTRY_COUNT - 1,
+  0
+};
+
+/**
+  Allocates and fills in the Page Directory and Page Table Entries to
+  establish a 4G page table.
+
+  @param[in] StackBase  Stack base address.
+  @param[in] StackSize  Stack size.
+
+  @return The address of page table.
+
+**/
+UINTN
+Create4GPageTablesIa32Pae (
+  IN EFI_PHYSICAL_ADDRESS   StackBase,
+  IN UINTN                  StackSize
+  )
+{
+  UINT8                                         PhysicalAddressBits;
+  EFI_PHYSICAL_ADDRESS                          PhysicalAddress;
+  UINTN                                         IndexOfPdpEntries;
+  UINTN                                         IndexOfPageDirectoryEntries;
+  UINT32                                        NumberOfPdpEntriesNeeded;
+  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMap;
+  PAGE_MAP_AND_DIRECTORY_POINTER                *PageDirectoryPointerEntry;
+  PAGE_TABLE_ENTRY                              *PageDirectoryEntry;
+  UINTN                                         TotalPagesNum;
+  UINTN                                         PageAddress;
+  UINT64                                        AddressEncMask;
+
+  //
+  // Make sure AddressEncMask is contained to smallest supported address field
+  //
+  AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
+
+  PhysicalAddressBits = 32;
+
+  //
+  // Calculate the table entries needed.
+  //
+  NumberOfPdpEntriesNeeded = (UINT32) LShiftU64 (1, (PhysicalAddressBits - 30));
+
+  TotalPagesNum = NumberOfPdpEntriesNeeded + 1;
+  PageAddress = (UINTN) AllocatePageTableMemory (TotalPagesNum);
+  ASSERT (PageAddress != 0);
+
+  PageMap = (VOID *) PageAddress;
+  PageAddress += SIZE_4KB;
+
+  PageDirectoryPointerEntry = PageMap;
+  PhysicalAddress = 0;
+
+  for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
+    //
+    // Each Directory Pointer entries points to a page of Page Directory entires.
+    // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
+    //
+    PageDirectoryEntry = (VOID *) PageAddress;
+    PageAddress += SIZE_4KB;
+
+    //
+    // Fill in a Page Directory Pointer Entries
+    //
+    PageDirectoryPointerEntry->Uint64 = (UINT64) (UINTN) PageDirectoryEntry | AddressEncMask;
+    PageDirectoryPointerEntry->Bits.Present = 1;
+
+    for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) {
+      if ((IsNullDetectionEnabled () && PhysicalAddress == 0)
+          || ((PhysicalAddress < StackBase + StackSize)
+              && ((PhysicalAddress + SIZE_2MB) > StackBase))) {
+        //
+        // Need to split this 2M page that covers stack range.
+        //
+        Split2MPageTo4K (PhysicalAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
+      } else {
+        //
+        // Fill in the Page Directory entries
+        //
+        PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress | AddressEncMask;
+        PageDirectoryEntry->Bits.ReadWrite = 1;
+        PageDirectoryEntry->Bits.Present = 1;
+        PageDirectoryEntry->Bits.MustBe1 = 1;
+      }
+    }
+  }
+
+  for (; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
+    ZeroMem (
+      PageDirectoryPointerEntry,
+      sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
+      );
+  }
+
+  //
+  // Protect the page table by marking the memory used for page table to be
+  // read-only.
+  //
+  EnablePageTableProtection ((UINTN)PageMap, FALSE);
+
+  return (UINTN) PageMap;
+}
+
+/**
+  The function will check if IA32 PAE is supported.
+
+  @retval TRUE      IA32 PAE is supported.
+  @retval FALSE     IA32 PAE is not supported.
+
+**/
+BOOLEAN
+IsIa32PaeSupport (
+  VOID
+  )
+{
+  UINT32            RegEax;
+  UINT32            RegEdx;
+  BOOLEAN           Ia32PaeSupport;
+
+  Ia32PaeSupport = FALSE;
+  AsmCpuid (0x0, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= 0x1) {
+    AsmCpuid (0x1, NULL, NULL, NULL, &RegEdx);
+    if ((RegEdx & BIT6) != 0) {
+      Ia32PaeSupport = TRUE;
+    }
+  }
+
+  return Ia32PaeSupport;
+}
+
+/**
+  The function will check if page table should be setup or not.
+
+  @retval TRUE      Page table should be created.
+  @retval FALSE     Page table should not be created.
+
+**/
+BOOLEAN
+ToBuildPageTable (
+  VOID
+  )
+{
+  if (!IsIa32PaeSupport ()) {
+    return FALSE;
+  }
+
+  if (IsNullDetectionEnabled ()) {
+    return TRUE;
+  }
+
+  if (PcdGet8 (PcdHeapGuardPropertyMask) != 0) {
+    return TRUE;
+  }
+
+  if (PcdGetBool (PcdCpuStackGuard)) {
+    return TRUE;
+  }
+
+  if (IsEnableNonExecNeeded ()) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+   Transfers control to DxeCore.
+
+   This function performs a CPU architecture specific operations to execute
+   the entry point of DxeCore with the parameters of HobList.
+
+   @param DxeCoreEntryPoint         The entry point of DxeCore.
+   @param HobList                   The start of HobList passed to DxeCore.
+
+**/
+VOID
+HandOffToDxeCore (
+  IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,
+  IN EFI_PEI_HOB_POINTERS   HobList
+  )
+{
+  EFI_PHYSICAL_ADDRESS      BaseOfStack;
+  EFI_PHYSICAL_ADDRESS      TopOfStack;
+  UINTN                     PageTables;
+  X64_IDT_GATE_DESCRIPTOR   *IdtTable;
+  UINTN                     SizeOfTemplate;
+  VOID                      *TemplateBase;
+  EFI_PHYSICAL_ADDRESS      VectorAddress;
+  UINT32                    Index;
+  X64_IDT_TABLE             *IdtTableForX64;
+
+  //
+  // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
+  //
+  if (IsNullDetectionEnabled ()) {
+    ClearFirst4KPage (HobList.Raw);
+    BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
+  }
+
+  BaseOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
+  ASSERT (BaseOfStack != 0);
+
+  if (FeaturePcdGet(PcdDxeIplSwitchToLongMode)) {
+    //
+    // Compute the top of the stack we were allocated, which is used to load X64 dxe core.
+    // Pre-allocate a 32 bytes which confroms to x64 calling convention.
+    //
+    // The first four parameters to a function are passed in rcx, rdx, r8 and r9.
+    // Any further parameters are pushed on the stack. Furthermore, space (4 * 8bytes) for the
+    // register parameters is reserved on the stack, in case the called function
+    // wants to spill them; this is important if the function is variadic.
+    //
+    TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32;
+
+    //
+    //  x64 Calling Conventions requires that the stack must be aligned to 16 bytes
+    //
+    TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, 16);
+
+    //
+    // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA
+    // memory, it may be corrupted when copying FV to high-end memory
+    //
+    AsmWriteGdtr (&gGdt);
+    //
+    // Create page table and save PageMapLevel4 to CR3
+    //
+    PageTables = CreateIdentityMappingPageTables (BaseOfStack, STACK_SIZE);
+
+    //
+    // Paging might be already enabled. To avoid conflict configuration,
+    // disable paging first anyway.
+    //
+    AsmWriteCr0 (AsmReadCr0 () & (~BIT31));
+    AsmWriteCr3 (PageTables);
+
+    //
+    // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
+    //
+    UpdateStackHob (BaseOfStack, STACK_SIZE);
+
+    SizeOfTemplate = AsmGetVectorTemplatInfo (&TemplateBase);
+
+  VectorAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocatePages (EFI_SIZE_TO_PAGES(sizeof (X64_IDT_TABLE) + SizeOfTemplate * IDT_ENTRY_COUNT));
+  ASSERT (VectorAddress != 0);
+
+    //
+    // Store EFI_PEI_SERVICES** in the 4 bytes immediately preceding IDT to avoid that
+    // it may not be gotten correctly after IDT register is re-written.
+    //
+    IdtTableForX64 = (X64_IDT_TABLE *) (UINTN) VectorAddress;
+    IdtTableForX64->PeiService = NULL;
+
+    VectorAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) (IdtTableForX64 + 1);
+    IdtTable      = IdtTableForX64->IdtTable;
+    for (Index = 0; Index < IDT_ENTRY_COUNT; Index++) {
+      IdtTable[Index].Ia32IdtEntry.Bits.GateType    =  0x8e;
+      IdtTable[Index].Ia32IdtEntry.Bits.Reserved_0  =  0;
+      IdtTable[Index].Ia32IdtEntry.Bits.Selector    =  SYS_CODE64_SEL;
+
+      IdtTable[Index].Ia32IdtEntry.Bits.OffsetLow   = (UINT16) VectorAddress;
+      IdtTable[Index].Ia32IdtEntry.Bits.OffsetHigh  = (UINT16) (RShiftU64 (VectorAddress, 16));
+      IdtTable[Index].Offset32To63                  = (UINT32) (RShiftU64 (VectorAddress, 32));
+      IdtTable[Index].Reserved                      = 0;
+
+      CopyMem ((VOID *) (UINTN) VectorAddress, TemplateBase, SizeOfTemplate);
+      AsmVectorFixup ((VOID *) (UINTN) VectorAddress, (UINT8) Index);
+
+      VectorAddress += SizeOfTemplate;
+    }
+
+    gLidtDescriptor.Base = (UINTN) IdtTable;
+
+
+    AsmWriteIdtr (&gLidtDescriptor);
+
+    DEBUG ((
+      DEBUG_INFO,
+      "%a() Stack Base: 0x%lx, Stack Size: 0x%x\n",
+      __FUNCTION__,
+      BaseOfStack,
+      STACK_SIZE
+      ));
+
+    //
+    // Go to Long Mode and transfer control to DxeCore.
+    // Interrupts will not get turned on until the CPU AP is loaded.
+    // Call x64 drivers passing in single argument, a pointer to the HOBs.
+    //
+    AsmEnablePaging64 (
+      SYS_CODE64_SEL,
+      DxeCoreEntryPoint,
+      (EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw),
+      0,
+      TopOfStack
+      );
+  } else {
+    // 32bit UEFI payload could be supported if required later.
+    DEBUG ((DEBUG_ERROR, "NOT support 32bit UEFI payload\n"));
+    ASSERT (FALSE);
+  }
+
+}
+
diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/IdtVectorAsm.nasm b/UefiPayloadPkg/UefiPayloadEntry/Ia32/IdtVectorAsm.nasm
new file mode 100644
index 0000000000..4f9b98f18b
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/IdtVectorAsm.nasm
@@ -0,0 +1,71 @@
+;/** @file
+;
+;    IDT vector entry.
+;
+;  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+;  SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;**/
+
+    SECTION .text
+
+;
+;------------------------------------------------------------------------------
+;  Generic IDT Vector Handlers for the Host.
+;
+;------------------------------------------------------------------------------
+
+ALIGN   8
+global ASM_PFX(AsmGetVectorTemplatInfo)
+global ASM_PFX(AsmVectorFixup)
+
+@VectorTemplateBase:
+        push  eax
+        db    0x6a       ; push #VectorNumber
+@VectorNum:
+        db    0
+        mov   eax, CommonInterruptEntry
+        jmp   eax
+@VectorTemplateEnd:
+
+global ASM_PFX(AsmGetVectorTemplatInfo)
+ASM_PFX(AsmGetVectorTemplatInfo):
+        mov   ecx, [esp + 4]
+        mov   dword [ecx], @VectorTemplateBase
+        mov   eax, (@VectorTemplateEnd - @VectorTemplateBase)
+        ret
+
+global ASM_PFX(AsmVectorFixup)
+ASM_PFX(AsmVectorFixup):
+        mov   eax, dword [esp + 8]
+        mov   ecx, [esp + 4]
+        mov   [ecx + (@VectorNum - @VectorTemplateBase)], al
+        ret
+
+;---------------------------------------;
+; CommonInterruptEntry                  ;
+;---------------------------------------;
+; The follow algorithm is used for the common interrupt routine.
+
+;
+; +---------------------+ <-- 16-byte aligned ensured by processor
+; +    Old SS           +
+; +---------------------+
+; +    Old RSP          +
+; +---------------------+
+; +    RFlags           +
+; +---------------------+
+; +    CS               +
+; +---------------------+
+; +    RIP              +
+; +---------------------+
+; +    Error Code       +
+; +---------------------+
+; +    Vector Number    +
+; +---------------------+
+
+CommonInterruptEntry:
+  cli
+
+  jmp $
+
diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/SecEntry.nasm b/UefiPayloadPkg/UefiPayloadEntry/Ia32/SecEntry.nasm
new file mode 100644
index 0000000000..fa5ed159c6
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/SecEntry.nasm
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------
+;*
+;*   Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
+;*   SPDX-License-Identifier: BSD-2-Clause-Patent
+
+;------------------------------------------------------------------------------
+
+#include <Base.h>
+
+SECTION .text
+
+extern ASM_PFX(PayloadEntry)
+extern  ASM_PFX(PcdGet32 (PcdPayloadStackTop))
+
+;
+; SecCore Entry Point
+;
+; Processor is in flat protected mode
+
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+  ;
+  ; Disable all the interrupts
+  ;
+  cli
+
+  ;
+  ; Save the bootloader parameter base address
+  ;
+  mov   eax, [esp + 4]
+
+  mov   esp, FixedPcdGet32 (PcdPayloadStackTop)
+
+  ;
+  ; Push the bootloader parameter address onto new stack
+  ;
+  push  0
+  push  eax
+
+  ;
+  ; Call into C code
+  ;
+  call  ASM_PFX(PayloadEntry)
+  jmp   $
+
diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
new file mode 100644
index 0000000000..d1c9cecd93
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
@@ -0,0 +1,280 @@
+/** @file
+
+  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiPayloadEntry.h"
+
+VOID*
+AllocateCodePages (
+  IN  UINTN     Pages
+  )
+{
+  VOID                    *Alloc;
+  EFI_PEI_HOB_POINTERS    Hob;
+
+  Alloc = AllocatePages (Pages);
+  if (Alloc == NULL) {
+    return NULL;
+  }
+
+  // find the HOB we just created, and change the type to EfiBootServicesCode
+  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
+  while (Hob.Raw != NULL) {
+    if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == (UINTN)Alloc) {
+      Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiBootServicesCode;
+      return Alloc;
+    }
+    Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob));
+  }
+
+  ASSERT (FALSE);
+
+  FreePages (Alloc, Pages);
+  return NULL;
+}
+
+
+EFI_STATUS
+LoadPeCoffImage (
+  IN  VOID                          *PeCoffImage,
+  OUT EFI_PHYSICAL_ADDRESS          *ImageAddress,
+  OUT UINT64                        *ImageSize,
+  OUT EFI_PHYSICAL_ADDRESS          *EntryPoint
+  )
+{
+  RETURN_STATUS                     Status;
+  PE_COFF_LOADER_IMAGE_CONTEXT      ImageContext;
+  VOID                              *Buffer;
+
+  ZeroMem (&ImageContext, sizeof (ImageContext));
+
+  ImageContext.Handle    = PeCoffImage;
+  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+  Status = PeCoffLoaderGetImageInfo (&ImageContext);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Allocate Memory for the image
+  //
+  Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES((UINT32)ImageContext.ImageSize));
+  ASSERT (Buffer != 0);
+
+  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
+
+  //
+  // Load the image to our new buffer
+  //
+  Status = PeCoffLoaderLoadImage (&ImageContext);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Relocate the image in our new buffer
+  //
+  Status = PeCoffLoaderRelocateImage (&ImageContext);
+  ASSERT_EFI_ERROR (Status);
+
+
+  *ImageAddress = ImageContext.ImageAddress;
+  *ImageSize    = ImageContext.ImageSize;
+  *EntryPoint   = ImageContext.EntryPoint;
+
+  return Status;
+}
+
+/**
+  This function searchs a given file type within a valid FV.
+
+  @param FvHeader        A pointer to firmware volume header that contains the set of files
+                         to be searched.
+  @param FileType        File type to be searched.
+  @param FileHeader      A pointer to the discovered file, if successful.
+
+  @retval EFI_SUCCESS    Successfully found FileType
+  @retval EFI_NOT_FOUND  File type can't be found.
+**/
+EFI_STATUS
+FvFindFile (
+  IN  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader,
+  IN  EFI_FV_FILETYPE             FileType,
+  OUT EFI_FFS_FILE_HEADER         **FileHeader
+  )
+{
+  EFI_PHYSICAL_ADDRESS        CurrentAddress;
+  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
+  EFI_FFS_FILE_HEADER         *File;
+  UINT32                      Size;
+  EFI_PHYSICAL_ADDRESS        EndOfFile;
+
+  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader;
+  EndOfFirmwareVolume = CurrentAddress + FvHeader->FvLength;
+
+  //
+  // Loop through the FFS files
+  //
+  for (EndOfFile = CurrentAddress + FvHeader->HeaderLength; ; ) {
+    CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
+    if (CurrentAddress > EndOfFirmwareVolume) {
+      break;
+    }
+
+    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+    if (IS_FFS_FILE2 (File)) {
+      Size = FFS_FILE2_SIZE (File);
+      if (Size <= 0x00FFFFFF) {
+        break;
+      }
+    } else {
+      Size = FFS_FILE_SIZE (File);
+      if (Size < sizeof (EFI_FFS_FILE_HEADER)) {
+        break;
+      }
+    }
+
+    EndOfFile = CurrentAddress + Size;
+    if (EndOfFile > EndOfFirmwareVolume) {
+      break;
+    }
+
+    //
+    // Look for file type
+    //
+    if (File->Type == FileType) {
+      *FileHeader = File;
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+
+/**
+  This function searchs a given section type within a valid FFS file.
+
+  @param  FileHeader            A pointer to the file header that contains the set of sections to
+                                be searched.
+  @param  SearchType            The value of the section type to search.
+  @param  SectionData           A pointer to the discovered section, if successful.
+
+  @retval EFI_SUCCESS           The section was found.
+  @retval EFI_NOT_FOUND         The section was not found.
+
+**/
+EFI_STATUS
+FileFindSection (
+  IN EFI_FFS_FILE_HEADER        *FileHeader,
+  IN EFI_SECTION_TYPE           SectionType,
+  OUT VOID                      **SectionData
+  )
+{
+  UINT32                        FileSize;
+  EFI_COMMON_SECTION_HEADER     *Section;
+  UINT32                        SectionSize;
+  UINT32                        Index;
+
+  if (IS_FFS_FILE2 (FileHeader)) {
+    FileSize = FFS_FILE2_SIZE (FileHeader);
+  } else {
+    FileSize = FFS_FILE_SIZE (FileHeader);
+  }
+  FileSize  -= sizeof (EFI_FFS_FILE_HEADER);
+
+  Section    = (EFI_COMMON_SECTION_HEADER *)(FileHeader + 1);
+  Index      = 0;
+  while (Index < FileSize) {
+    if (Section->Type == SectionType) {
+      if (IS_SECTION2 (Section)) {
+        *SectionData = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
+      } else {
+        *SectionData = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
+      }
+      return EFI_SUCCESS;
+    }
+
+    if (IS_SECTION2 (Section)) {
+      SectionSize = SECTION2_SIZE (Section);
+    } else {
+      SectionSize = SECTION_SIZE (Section);
+    }
+
+    SectionSize = GET_OCCUPIED_SIZE (SectionSize, 4);
+    ASSERT (SectionSize != 0);
+    Index += SectionSize;
+
+    Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionSize);
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+
+/**
+  Find DXE core from FV and build DXE core HOBs.
+
+  @param[out]  DxeCoreEntryPoint     DXE core entry point
+
+  @retval EFI_SUCCESS        If it completed successfully.
+  @retval EFI_NOT_FOUND      If it failed to load DXE FV.
+**/
+EFI_STATUS
+LoadDxeCore (
+  OUT PHYSICAL_ADDRESS        *DxeCoreEntryPoint
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_FIRMWARE_VOLUME_HEADER  *PayloadFv;
+  EFI_FIRMWARE_VOLUME_HEADER  *DxeCoreFv;
+  EFI_FFS_FILE_HEADER         *FileHeader;
+  VOID                        *PeCoffImage;
+  EFI_PHYSICAL_ADDRESS        ImageAddress;
+  UINT64                      ImageSize;
+
+  PayloadFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdPayloadFdMemBase);
+
+  //
+  // DXE FV is inside Payload FV. Here find DXE FV from Payload FV
+  //
+  Status = FvFindFile (PayloadFv, EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &FileHeader);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Status = FileFindSection (FileHeader, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, (VOID **)&DxeCoreFv);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Report DXE FV to DXE core
+  //
+  BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) DxeCoreFv, DxeCoreFv->FvLength);
+
+  //
+  // Find DXE core file from DXE FV
+  //
+  Status = FvFindFile (DxeCoreFv, EFI_FV_FILETYPE_DXE_CORE, &FileHeader);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = FileFindSection (FileHeader, EFI_SECTION_PE32, (VOID **)&PeCoffImage);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Get DXE core info
+  //
+  Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, DxeCoreEntryPoint);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  BuildModuleHob (&FileHeader->Name, ImageAddress, EFI_SIZE_TO_PAGES ((UINT32) ImageSize) * EFI_PAGE_SIZE, *DxeCoreEntryPoint);
+
+  return EFI_SUCCESS;
+}
diff --git a/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c
new file mode 100644
index 0000000000..1204573b3e
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c
@@ -0,0 +1,201 @@
+/** @file
+
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiPayloadEntry.h"
+
+/**
+  Allocates one or more pages of type EfiBootServicesData.
+
+  Allocates the number of pages of MemoryType and returns a pointer to the
+  allocated buffer.  The buffer returned is aligned on a 4KB boundary.
+  If Pages is 0, then NULL is returned.
+  If there is not enough memory availble to satisfy the request, then NULL
+  is returned.
+
+  @param   Pages                 The number of 4 KB pages to allocate.
+  @return  A pointer to the allocated buffer or NULL if allocation fails.
+**/
+VOID *
+EFIAPI
+AllocatePages (
+  IN UINTN                                Pages
+  )
+{
+  EFI_PEI_HOB_POINTERS                    Hob;
+  EFI_PHYSICAL_ADDRESS                    Offset;
+  EFI_HOB_HANDOFF_INFO_TABLE              *HobTable;
+
+  Hob.Raw  = GetHobList ();
+  HobTable = Hob.HandoffInformationTable;
+
+  if (Pages == 0) {
+    return NULL;
+  }
+
+  // Make sure allocation address is page alligned.
+  Offset = HobTable->EfiFreeMemoryTop & EFI_PAGE_MASK;
+  if (Offset != 0) {
+    HobTable->EfiFreeMemoryTop -= Offset;
+  }
+
+  //
+  // Check available memory for the allocation
+  //
+  if (HobTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < HobTable->EfiFreeMemoryBottom) {
+    return NULL;
+  }
+
+  HobTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;
+  BuildMemoryAllocationHob (HobTable->EfiFreeMemoryTop, Pages * EFI_PAGE_SIZE, EfiBootServicesData);
+
+  return (VOID *)(UINTN)HobTable->EfiFreeMemoryTop;
+}
+
+/**
+  Frees one or more 4KB pages that were previously allocated with one of the page allocation
+  functions in the Memory Allocation Library.
+
+  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
+  must have been allocated on a previous call to the page allocation services of the Memory
+  Allocation Library.  If it is not possible to free allocated pages, then this function will
+  perform no actions.
+
+  If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
+  then ASSERT().
+  If Pages is zero, then ASSERT().
+
+  @param  Buffer                Pointer to the buffer of pages to free.
+  @param  Pages                 The number of 4 KB pages to free.
+
+**/
+VOID
+EFIAPI
+FreePages (
+  IN VOID   *Buffer,
+  IN UINTN  Pages
+  )
+{
+}
+
+/**
+  Allocates one or more pages of type EfiBootServicesData at a specified alignment.
+
+  Allocates the number of pages specified by Pages of type EfiBootServicesData with an
+  alignment specified by Alignment.
+  If Pages is 0, then NULL is returned.
+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+  If there is no enough memory at the specified alignment available to satisfy the
+  request, then NULL is returned.
+
+  @param  Pages          The number of 4 KB pages to allocate.
+  @param  Alignment      The requested alignment of the allocation.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+**/
+VOID *
+EFIAPI
+AllocateAlignedPages (
+  IN UINTN                    Pages,
+  IN UINTN                    Alignment
+  )
+{
+  VOID                        *Memory;
+  UINTN                       AlignmentMask;
+
+  //
+  // Alignment must be a power of two or zero.
+  //
+  ASSERT ((Alignment & (Alignment - 1)) == 0);
+
+  if (Pages == 0) {
+    return NULL;
+  }
+
+  //
+  // Check overflow.
+  //
+  ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment)));
+
+  Memory = (VOID *)(UINTN)AllocatePages (Pages + EFI_SIZE_TO_PAGES (Alignment));
+  if (Memory == NULL) {
+    return NULL;
+  }
+
+  if (Alignment == 0) {
+    AlignmentMask = Alignment;
+  } else {
+    AlignmentMask = Alignment - 1;
+  }
+
+  return (VOID *) (UINTN) (((UINTN) Memory + AlignmentMask) & ~AlignmentMask);
+}
+
+
+/**
+  Allocates a buffer of type EfiBootServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
+  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
+  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocatePool (
+  IN UINTN  AllocationSize
+  )
+{
+  EFI_HOB_MEMORY_POOL      *Hob;
+
+  if (AllocationSize > 0x4000) {
+    // Please use AllocatePages for big allocations
+    return NULL;
+  }
+
+  Hob = (EFI_HOB_MEMORY_POOL *)CreateHob (EFI_HOB_TYPE_MEMORY_POOL, (UINT16)(sizeof (EFI_HOB_TYPE_MEMORY_POOL) + AllocationSize));
+  return (VOID *)(Hob + 1);
+}
+
+/**
+  Allocates and zeros a buffer of type EfiBootServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
+  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
+  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
+  request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateZeroPool (
+  IN UINTN  AllocationSize
+  )
+{
+  VOID *Buffer;
+
+  Buffer = AllocatePool (AllocationSize);
+  if (Buffer == NULL) {
+    return NULL;
+  }
+
+  ZeroMem (Buffer, AllocationSize);
+
+  return Buffer;
+}
+
+
diff --git a/UefiPayloadPkg/BlSupportPei/BlSupportPei.c b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
similarity index 52%
rename from UefiPayloadPkg/BlSupportPei/BlSupportPei.c
rename to UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
index a7e99f9ec6..4be2122a4f 100644
--- a/UefiPayloadPkg/BlSupportPei/BlSupportPei.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
@@ -1,144 +1,66 @@
 /** @file
-  This PEIM will parse bootloader information and report resource information into pei core.
-  This file contains the main entrypoint of the PEIM.
 
-Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
+  Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
-#include "BlSupportPei.h"
-
-#define LEGACY_8259_MASK_REGISTER_MASTER  0x21
-#define LEGACY_8259_MASK_REGISTER_SLAVE   0xA1
-
-EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
-  { EfiACPIReclaimMemory,   FixedPcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory) },
-  { EfiACPIMemoryNVS,       FixedPcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS) },
-  { EfiReservedMemoryType,  FixedPcdGet32 (PcdMemoryTypeEfiReservedMemoryType) },
-  { EfiRuntimeServicesData, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesData) },
-  { EfiRuntimeServicesCode, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode) },
-  { EfiMaxMemoryType,       0     }
-};
-
-EFI_PEI_PPI_DESCRIPTOR   mPpiBootMode[] = {
-  {
-    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
-    &gEfiPeiMasterBootModePpiGuid,
-    NULL
-  }
-};
 
-EFI_PEI_GRAPHICS_DEVICE_INFO_HOB mDefaultGraphicsDeviceInfo = {
-  MAX_UINT16, MAX_UINT16, MAX_UINT16, MAX_UINT16, MAX_UINT8,  MAX_UINT8
-};
+#include "UefiPayloadEntry.h"
+
 
 /**
-  Create memory mapped io resource hob.
+   Transfers control to DxeCore.
+
+   This function performs a CPU architecture specific operations to execute
+   the entry point of DxeCore with the parameters of HobList.
 
-  @param  MmioBase    Base address of the memory mapped io range
-  @param  MmioSize    Length of the memory mapped io range
+   @param DxeCoreEntryPoint         The entry point of DxeCore.
+   @param HobList                   The start of HobList passed to DxeCore.
 
 **/
 VOID
-BuildMemoryMappedIoRangeHob (
-  EFI_PHYSICAL_ADDRESS        MmioBase,
-  UINT64                      MmioSize
-  )
-{
-  BuildResourceDescriptorHob (
-    EFI_RESOURCE_MEMORY_MAPPED_IO,
-    (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
-    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
-    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
-    EFI_RESOURCE_ATTRIBUTE_TESTED),
-    MmioBase,
-    MmioSize
-    );
-
-  BuildMemoryAllocationHob (
-    MmioBase,
-    MmioSize,
-    EfiMemoryMappedIO
-    );
-}
+HandOffToDxeCore (
+  IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,
+  IN EFI_PEI_HOB_POINTERS   HobList
+  );
 
-/**
-  Check the integrity of firmware volume header
-
-  @param[in]  FwVolHeader   A pointer to a firmware volume header
-
-  @retval     TRUE          The firmware volume is consistent
-  @retval     FALSE         The firmware volume has corrupted.
 
-**/
-STATIC
-BOOLEAN
-IsFvHeaderValid (
-  IN EFI_FIRMWARE_VOLUME_HEADER    *FwVolHeader
+EFI_STATUS
+MemInfoCallback (
+  IN MEMROY_MAP_ENTRY          *MemoryMapEntry,
+  IN VOID                      *Params
   )
 {
-  UINT16 Checksum;
+  EFI_PHYSICAL_ADDRESS         Base;
+  EFI_RESOURCE_TYPE            Type;
+  UINT64                       Size;
+  EFI_RESOURCE_ATTRIBUTE_TYPE  Attribue;
 
-  // Skip nv storage fv
-  if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {
-    return FALSE;
-  }
+  Type    = (MemoryMapEntry->Type == 1) ? EFI_RESOURCE_SYSTEM_MEMORY : EFI_RESOURCE_MEMORY_RESERVED;
+  Base    = MemoryMapEntry->Base;
+  Size    = MemoryMapEntry->Size;
 
-  if ( (FwVolHeader->Revision != EFI_FVH_REVISION)   ||
-     (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
-     (FwVolHeader->FvLength == ((UINTN) -1))       ||
-     ((FwVolHeader->HeaderLength & 0x01 ) !=0) )  {
-    return FALSE;
-  }
+  Attribue = 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;
 
-  Checksum = CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength);
-  if (Checksum != 0) {
-    DEBUG (( DEBUG_ERROR,
-              "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n",
-              FwVolHeader->Checksum,
-              (UINT16)( Checksum + FwVolHeader->Checksum )));
-    return TRUE; //FALSE; Need update UEFI build tool when patching entrypoin @start of fd.
+  if (Base >= BASE_4GB ) {
+    // Remove tested attribute to avoid DXE core to dispatch driver to memory above 4GB
+    Attribue &= ~EFI_RESOURCE_ATTRIBUTE_TESTED;
   }
 
-  return TRUE;
-}
-
-/**
-  Install FvInfo PPI and create fv hobs for remained fvs
+  BuildResourceDescriptorHob (Type, Attribue, (EFI_PHYSICAL_ADDRESS)Base, Size);
+  DEBUG ((DEBUG_INFO , "buildhob: base = 0x%lx, size = 0x%lx, type = 0x%x\n", Base, Size, Type));
 
-**/
-VOID
-PeiReportRemainedFvs (
-  VOID
-  )
-{
-  UINT8*  TempPtr;
-  UINT8*  EndPtr;
-
-  TempPtr = (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase);
-  EndPtr = (UINT8* )(UINTN) (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize));
-
-  for (;TempPtr < EndPtr;) {
-    if (IsFvHeaderValid ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)) {
-      if (TempPtr != (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase))  {
-        // Skip the PEI FV
-        DEBUG((DEBUG_INFO, "Found one valid fv : 0x%lx.\n", TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength));
-
-        PeiServicesInstallFvInfoPpi (
-          NULL,
-          (VOID *) (UINTN) TempPtr,
-          (UINT32) (UINTN) ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength,
-          NULL,
-          NULL
-          );
-        BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN) TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength);
-      }
-    }
-    TempPtr += ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength;
-  }
+  return EFI_SUCCESS;
 }
 
 
+
 /**
   Find the board related info from ACPI table
 
@@ -299,91 +221,19 @@ Done:
   return RETURN_SUCCESS;
 }
 
-EFI_STATUS
-MemInfoCallback (
-  IN MEMROY_MAP_ENTRY             *MemoryMapEntry,
-  IN VOID                         *Params
-  )
-{
-  PAYLOAD_MEM_INFO        *MemInfo;
-  UINTN                   Attribue;
-  EFI_PHYSICAL_ADDRESS    Base;
-  EFI_RESOURCE_TYPE       Type;
-  UINT64                  Size;
-  UINT32                  SystemLowMemTop;
-
-  Attribue = 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;
-
-  MemInfo = (PAYLOAD_MEM_INFO *)Params;
-  Type    = (MemoryMapEntry->Type == 1) ? EFI_RESOURCE_SYSTEM_MEMORY : EFI_RESOURCE_MEMORY_RESERVED;
-  Base    = MemoryMapEntry->Base;
-  Size    = MemoryMapEntry->Size;
-
-  if ((Base  < 0x100000) && ((Base + Size) > 0x100000)) {
-    Size -= (0x100000 - Base);
-    Base  = 0x100000;
-  }
-
-  if (Base >= 0x100000) {
-    if (Type == EFI_RESOURCE_SYSTEM_MEMORY) {
-      if (Base < 0x100000000ULL) {
-        MemInfo->UsableLowMemTop = (UINT32)(Base + Size);
-      } else {
-        Attribue &= ~EFI_RESOURCE_ATTRIBUTE_TESTED;
-      }
-      BuildResourceDescriptorHob (
-        EFI_RESOURCE_SYSTEM_MEMORY,
-        Attribue,
-        (EFI_PHYSICAL_ADDRESS)Base,
-        Size
-        );
-    } else if (Type == EFI_RESOURCE_MEMORY_RESERVED) {
-      BuildResourceDescriptorHob (
-        EFI_RESOURCE_MEMORY_RESERVED,
-        Attribue,
-        (EFI_PHYSICAL_ADDRESS)Base,
-        Size
-        );
-      if (Base < 0x100000000ULL) {
-        SystemLowMemTop = ((UINT32)(Base + Size) + 0x0FFFFFFF) & 0xF0000000;
-        if (SystemLowMemTop > MemInfo->SystemLowMemTop) {
-          MemInfo->SystemLowMemTop = SystemLowMemTop;
-        }
-      }
-    }
-  }
-
-  return EFI_SUCCESS;
-}
 
 /**
-  This is the entrypoint of PEIM
-
-  @param  FileHandle  Handle of the file being invoked.
-  @param  PeiServices Describes the list of possible PEI Services.
+  It will build HOBs based on information from bootloaders.
 
-  @retval EFI_SUCCESS if it completed successfully.
+  @retval EFI_SUCCESS        If it completed successfully.
+  @retval Others             If it failed to build required HOBs.
 **/
 EFI_STATUS
-EFIAPI
-BlPeiEntryPoint (
-  IN       EFI_PEI_FILE_HANDLE     FileHandle,
-  IN CONST EFI_PEI_SERVICES        **PeiServices
+BuildHobFromBl (
+  VOID
   )
 {
   EFI_STATUS                       Status;
-  UINT64                           LowMemorySize;
-  UINT64                           PeiMemSize = SIZE_64MB;
-  EFI_PHYSICAL_ADDRESS             PeiMemBase = 0;
-  UINT32                           RegEax;
-  UINT8                            PhysicalAddressBits;
-  PAYLOAD_MEM_INFO                 PldMemInfo;
   SYSTEM_TABLE_INFO                SysTableInfo;
   SYSTEM_TABLE_INFO                *NewSysTableInfo;
   ACPI_BOARD_INFO                  AcpiBoardInfo;
@@ -393,119 +243,14 @@ BlPeiEntryPoint (
   EFI_PEI_GRAPHICS_DEVICE_INFO_HOB GfxDeviceInfo;
   EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *NewGfxDeviceInfo;
 
-
-  //
-  // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED
-  // is intentionally omitted to prevent erasing of the coreboot header
-  // record before it is processed by ParseMemoryInfo.
-  //
-  BuildResourceDescriptorHob (
-    EFI_RESOURCE_SYSTEM_MEMORY,
-    (
-    EFI_RESOURCE_ATTRIBUTE_PRESENT |
-    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
-    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
-    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
-    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
-    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
-    ),
-    (EFI_PHYSICAL_ADDRESS)(0),
-    (UINT64)(0xA0000)
-    );
-
-  BuildResourceDescriptorHob (
-    EFI_RESOURCE_MEMORY_RESERVED,
-    (
-    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
-    ),
-    (EFI_PHYSICAL_ADDRESS)(0xA0000),
-    (UINT64)(0x60000)
-    );
-
-
   //
-  // Parse memory info
+  // Parse memory info and build memory HOBs
   //
-  ZeroMem (&PldMemInfo, sizeof(PldMemInfo));
-  Status = ParseMemoryInfo (MemInfoCallback, &PldMemInfo);
+  Status = ParseMemoryInfo (MemInfoCallback, NULL);
   if (EFI_ERROR(Status)) {
     return Status;
   }
 
-  //
-  // Install memory
-  //
-  LowMemorySize = PldMemInfo.UsableLowMemTop;
-  PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));
-  DEBUG ((DEBUG_INFO, "Low memory 0x%lx\n", LowMemorySize));
-  DEBUG ((DEBUG_INFO, "SystemLowMemTop 0x%x\n", PldMemInfo.SystemLowMemTop));
-  DEBUG ((DEBUG_INFO, "PeiMemBase: 0x%lx.\n", PeiMemBase));
-  DEBUG ((DEBUG_INFO, "PeiMemSize: 0x%lx.\n", PeiMemSize));
-  Status = PeiServicesInstallPeiMemory (PeiMemBase, PeiMemSize);
-  ASSERT_EFI_ERROR (Status);
-
-  //
-  // Set cache on the physical memory
-  //
-  MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);
-  MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);
-
-  //
-  // Create Memory Type Information HOB
-  //
-  BuildGuidDataHob (
-    &gEfiMemoryTypeInformationGuid,
-    mDefaultMemoryTypeInformation,
-    sizeof(mDefaultMemoryTypeInformation)
-    );
-
-  //
-  // Create Fv hob
-  //
-  PeiReportRemainedFvs ();
-
-  BuildMemoryAllocationHob (
-    PcdGet32 (PcdPayloadFdMemBase),
-    PcdGet32 (PcdPayloadFdMemSize),
-    EfiBootServicesData
-    );
-
-  //
-  // Build CPU memory space and IO space hob
-  //
-  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
-  if (RegEax >= 0x80000008) {
-    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
-    PhysicalAddressBits = (UINT8) RegEax;
-  } else {
-    PhysicalAddressBits  = 36;
-  }
-
-  //
-  // Create a CPU hand-off information
-  //
-  BuildCpuHob (PhysicalAddressBits, 16);
-
-  //
-  // Report Local APIC range
-  //
-  BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);
-
-  //
-  // Boot mode
-  //
-  Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
-  ASSERT_EFI_ERROR (Status);
-
-  Status = PeiServicesInstallPpi (mPpiBootMode);
-  ASSERT_EFI_ERROR (Status);
-
   //
   // Create guid hob for frame buffer information
   //
@@ -561,12 +306,109 @@ BlPeiEntryPoint (
     return Status;
   }
 
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function will build some generic HOBs that doesn't depend on information from bootloaders.
+
+**/
+VOID
+BuildGenericHob (
+  VOID
+  )
+{
+  UINT32                           RegEax;
+  UINT8                            PhysicalAddressBits;
+  EFI_RESOURCE_ATTRIBUTE_TYPE      ResourceAttribute;
+
+  // The UEFI payload FV
+  BuildMemoryAllocationHob (PcdGet32 (PcdPayloadFdMemBase), PcdGet32 (PcdPayloadFdMemSize), EfiBootServicesData);
+
+  //
+  // Build CPU memory space and IO space hob
+  //
+  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= 0x80000008) {
+    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+    PhysicalAddressBits = (UINT8) RegEax;
+  } else {
+    PhysicalAddressBits  = 36;
+  }
+
+  BuildCpuHob (PhysicalAddressBits, 16);
+
+  //
+  // Report Local APIC range, cause sbl HOB to be NULL, comment now
+  //
+  ResourceAttribute = (
+      EFI_RESOURCE_ATTRIBUTE_PRESENT |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_TESTED
+  );
+  BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_MAPPED_IO, ResourceAttribute, 0xFEC80000, SIZE_512KB);
+  BuildMemoryAllocationHob ( 0xFEC80000, SIZE_512KB, EfiMemoryMappedIO);
+
+}
+
+
+/**
+  Entry point to the C language phase of UEFI payload.
+
+  @retval      It will not return if SUCCESS, and return error when passing bootloader parameter.
+**/
+EFI_STATUS
+EFIAPI
+PayloadEntry (
+  IN UINTN                     BootloaderParameter
+  )
+{
+  EFI_STATUS                    Status;
+  PHYSICAL_ADDRESS              DxeCoreEntryPoint;
+  EFI_HOB_HANDOFF_INFO_TABLE    *HandoffHobTable;
+  UINTN                         HobMemBase;
+  UINTN                         HobMemSize;
+  EFI_PEI_HOB_POINTERS          Hob;
+
+  DEBUG ((DEBUG_INFO, "GET_BOOTLOADER_PARAMETER() = 0x%lx\n", GET_BOOTLOADER_PARAMETER()));
+  DEBUG ((DEBUG_INFO, "sizeof(UINTN) = 0x%x\n", sizeof(UINTN)));
+
+  // Initialize floating point operating environment to be compliant with UEFI spec.
+  InitializeFloatingPointUnits ();
+
+  // Init the region for HOB and memory allocation for this module
+  HobMemBase      = ALIGN_VALUE (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize), SIZE_1MB);
+  HobMemSize      = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
+  HandoffHobTable = HobConstructor ((VOID *)HobMemBase, HobMemSize, (VOID *)HobMemBase, (VOID *)(HobMemBase + HobMemSize));
+
+  // Build HOB based on information from Bootloader
+  Status = BuildHobFromBl ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "BuildHobFromBl Status = %r\n", Status));
+    return Status;
+  }
+
+  // Build other HOBs required by DXE
+  BuildGenericHob ();
+
+  // Load the DXE Core
+  Status = LoadDxeCore (&DxeCoreEntryPoint);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "DxeCoreEntryPoint = 0x%lx\n", DxeCoreEntryPoint));
+
   //
   // Mask off all legacy 8259 interrupt sources
   //
   IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
   IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE,  0xFF);
 
+  Hob.HandoffInformationTable = HandoffHobTable;
+  HandOffToDxeCore (DxeCoreEntryPoint, Hob);
+
+  // Should not get here
+  CpuDeadLoop ();
   return EFI_SUCCESS;
 }
-
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
new file mode 100644
index 0000000000..6ae111fa00
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
@@ -0,0 +1,85 @@
+/** @file
+*
+* Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef __UEFI_PAYLOAD_ENTRY_H__
+#define __UEFI_PAYLOAD_ENTRY_H__
+
+#include <PiPei.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Guid/MemoryAllocationHob.h>
+#include <Library/IoLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/BlParseLib.h>
+#include <Library/PlatformSupportLib.h>
+#include <Library/UefiCpuLib.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <Guid/SerialPortInfoGuid.h>
+#include <Guid/SystemTableInfoGuid.h>
+#include <Guid/MemoryMapInfoGuid.h>
+#include <Guid/AcpiBoardInfoGuid.h>
+#include <Guid/GraphicsInfoHob.h>
+
+
+#define LEGACY_8259_MASK_REGISTER_MASTER  0x21
+#define LEGACY_8259_MASK_REGISTER_SLAVE   0xA1
+#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
+  ((ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1)))
+
+VOID *
+EFIAPI
+CreateHob (
+  IN  UINT16    HobType,
+  IN  UINT16    HobLength
+  );
+
+/**
+  Update the Stack Hob if the stack has been moved
+
+  @param  BaseAddress   The 64 bit physical address of the Stack.
+  @param  Length        The length of the stack in bytes.
+
+**/
+VOID
+EFIAPI
+UpdateStackHob (
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                      Length
+  );
+
+EFI_HOB_HANDOFF_INFO_TABLE*
+EFIAPI
+HobConstructor (
+  IN VOID   *EfiMemoryBegin,
+  IN UINTN  EfiMemoryLength,
+  IN VOID   *EfiFreeMemoryBottom,
+  IN VOID   *EfiFreeMemoryTop
+  );
+
+/**
+  Find DXE core from FV and build DXE core HOBs.
+
+  @param[out]  DxeCoreEntryPoint     DXE core entry point
+
+  @retval EFI_SUCCESS        If it completed successfully.
+  @retval EFI_NOT_FOUND      If it failed to load DXE FV.
+**/
+EFI_STATUS
+LoadDxeCore (
+  OUT PHYSICAL_ADDRESS        *DxeCoreEntryPoint
+  );
+
+
+#endif
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
new file mode 100644
index 0000000000..6718d53b68
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
@@ -0,0 +1,91 @@
+## @file
+#  This is the first module for UEFI payload.
+#
+#  Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PayloadEntry
+  FILE_GUID                      = 2119BBD7-9432-4f47-B5E2-5C4EA31B6BDC
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  UefiPayloadEntry.c
+  LoadDxeCore.c
+  MemoryAllocation.c
+
+[Sources.Ia32]
+  X64/VirtualMemory.h
+  X64/VirtualMemory.c
+  Ia32/DxeLoadFunc.c
+  Ia32/IdtVectorAsm.nasm
+  Ia32/SecEntry.nasm
+
+[Sources.X64]
+  X64/VirtualMemory.h
+  X64/VirtualMemory.c
+  X64/DxeLoadFunc.c
+  X64/SecEntry.nasm
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  UefiPayloadPkg/UefiPayloadPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  BaseLib
+  SerialPortLib
+  IoLib
+  BlParseLib
+  HobLib
+  PeCoffLib
+  PlatformSupportLib
+  UefiCpuLib
+
+[Guids]
+  gEfiMemoryTypeInformationGuid
+  gEfiFirmwareFileSystem2Guid
+  gUefiSystemTableInfoGuid
+  gEfiGraphicsInfoHobGuid
+  gEfiGraphicsDeviceInfoHobGuid
+  gUefiAcpiBoardInfoGuid
+
+[FeaturePcd.IA32]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode      ## CONSUMES
+
+[FeaturePcd.X64]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables       ## CONSUMES
+
+
+[Pcd.IA32,Pcd.X64]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable                      ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask    ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable                  ## SOMETIMES_CONSUMES
+
+  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
+  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
+  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadStackTop
+  gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack               ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy       ## SOMETIMES_CONSUMES
+
diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
new file mode 100644
index 0000000000..d2d339d514
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
@@ -0,0 +1,98 @@
+/** @file
+  x64-specifc functionality for DxeLoad.
+
+Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include "X64/VirtualMemory.h"
+#include "UefiPayloadEntry.h"
+#define STACK_SIZE            0x20000
+
+
+/**
+   Transfers control to DxeCore.
+
+   This function performs a CPU architecture specific operations to execute
+   the entry point of DxeCore with the parameters of HobList.
+   It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.
+
+   @param DxeCoreEntryPoint         The entry point of DxeCore.
+   @param HobList                   The start of HobList passed to DxeCore.
+
+**/
+VOID
+HandOffToDxeCore (
+  IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,
+  IN EFI_PEI_HOB_POINTERS   HobList
+  )
+{
+  VOID                            *BaseOfStack;
+  VOID                            *TopOfStack;
+  UINTN                           PageTables;
+
+  //
+  // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
+  //
+  if (IsNullDetectionEnabled ()) {
+    ClearFirst4KPage (HobList.Raw);
+    BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
+  }
+
+
+  //
+  // Allocate 128KB for the Stack
+  //
+  BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
+  ASSERT (BaseOfStack != NULL);
+
+  //
+  // Compute the top of the stack we were allocated. Pre-allocate a UINTN
+  // for safety.
+  //
+  TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
+  TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
+
+  PageTables = 0;
+  if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
+    //
+    // Create page table and save PageMapLevel4 to CR3
+    //
+    PageTables = CreateIdentityMappingPageTables ((EFI_PHYSICAL_ADDRESS) (UINTN) BaseOfStack, STACK_SIZE);
+  } else {
+    //
+    // Set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE
+    // for the DxeIpl and the DxeCore are both X64.
+    //
+    ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE);
+    ASSERT (PcdGetBool (PcdCpuStackGuard) == FALSE);
+  }
+
+
+  if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
+    AsmWriteCr3 (PageTables);
+  }
+
+  //
+  // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
+  //
+  UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, STACK_SIZE);
+
+  //
+  // Transfer the control to the entry point of DxeCore.
+  //
+  SwitchStack (
+    (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
+    HobList.Raw,
+    NULL,
+    TopOfStack
+    );
+}
diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/SecEntry.nasm b/UefiPayloadPkg/UefiPayloadEntry/X64/SecEntry.nasm
new file mode 100644
index 0000000000..974cf77771
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/X64/SecEntry.nasm
@@ -0,0 +1,47 @@
+;------------------------------------------------------------------------------
+;*
+;*   Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
+;*   SPDX-License-Identifier: BSD-2-Clause-Patent
+
+;------------------------------------------------------------------------------
+
+#include <Base.h>
+
+DEFAULT REL
+SECTION .text
+
+extern ASM_PFX(PayloadEntry)
+extern  ASM_PFX(PcdGet32 (PcdPayloadStackTop))
+
+;
+; SecCore Entry Point
+;
+; Processor is in flat protected mode
+
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+  ;
+  ; Disable all the interrupts
+  ;
+  cli
+
+
+  mov   rsp, FixedPcdGet32 (PcdPayloadStackTop)
+
+  ;
+  ; Push the bootloader parameter address onto new stack
+  ;
+  push  rcx
+  mov   rax, 0
+  push  rax ; shadow space
+  push  rax
+  push  rax
+  push  rax
+
+  ;
+  ; Call into C code
+  ;
+  call  ASM_PFX(PayloadEntry)
+  jmp   $
+
diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c
new file mode 100644
index 0000000000..329274b1b6
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c
@@ -0,0 +1,904 @@
+/** @file
+  x64 Virtual Memory Management Services in the form of an IA-32 driver.
+  Used to establish a 1:1 Virtual to Physical Mapping that is required to
+  enter Long Mode (x64 64-bit mode).
+
+  While we make a 1:1 mapping (identity mapping) for all physical pages
+  we still need to use the MTRR's to ensure that the cachability attributes
+  for all memory regions is correct.
+
+  The basic idea is to use 2MB page table entries where ever possible. If
+  more granularity of cachability is required then 4K page tables are used.
+
+  References:
+    1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic Architecture, Intel
+    2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
+    3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
+
+Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Register/Intel/Cpuid.h>
+#include "VirtualMemory.h"
+
+//
+// Global variable to keep track current available memory used as page table.
+//
+PAGE_TABLE_POOL   *mPageTablePool = NULL;
+
+/**
+  Clear legacy memory located at the first 4K-page, if available.
+
+  This function traverses the whole HOB list to check if memory from 0 to 4095
+  exists and has not been allocated, and then clear it if so.
+
+  @param HobStart                  The start of HobList passed to DxeCore.
+
+**/
+VOID
+ClearFirst4KPage (
+  IN  VOID *HobStart
+  )
+{
+  EFI_PEI_HOB_POINTERS          RscHob;
+  EFI_PEI_HOB_POINTERS          MemHob;
+  BOOLEAN                       DoClear;
+
+  RscHob.Raw = HobStart;
+  MemHob.Raw = HobStart;
+  DoClear = FALSE;
+
+  //
+  // Check if page 0 exists and free
+  //
+  while ((RscHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
+                                   RscHob.Raw)) != NULL) {
+    if (RscHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&
+        RscHob.ResourceDescriptor->PhysicalStart == 0) {
+      DoClear = TRUE;
+      //
+      // Make sure memory at 0-4095 has not been allocated.
+      //
+      while ((MemHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION,
+                                       MemHob.Raw)) != NULL) {
+        if (MemHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress
+            < EFI_PAGE_SIZE) {
+          DoClear = FALSE;
+          break;
+        }
+        MemHob.Raw = GET_NEXT_HOB (MemHob);
+      }
+      break;
+    }
+    RscHob.Raw = GET_NEXT_HOB (RscHob);
+  }
+
+  if (DoClear) {
+    DEBUG ((DEBUG_INFO, "Clearing first 4K-page!\r\n"));
+    SetMem (NULL, EFI_PAGE_SIZE, 0);
+  }
+
+  return;
+}
+
+/**
+  Return configure status of NULL pointer detection feature.
+
+  @return TRUE   NULL pointer detection feature is enabled
+  @return FALSE  NULL pointer detection feature is disabled
+
+**/
+BOOLEAN
+IsNullDetectionEnabled (
+  VOID
+  )
+{
+  return ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) != 0);
+}
+
+/**
+  The function will check if Execute Disable Bit is available.
+
+  @retval TRUE      Execute Disable Bit is available.
+  @retval FALSE     Execute Disable Bit is not available.
+
+**/
+BOOLEAN
+IsExecuteDisableBitAvailable (
+  VOID
+  )
+{
+  UINT32            RegEax;
+  UINT32            RegEdx;
+  BOOLEAN           Available;
+
+  Available = FALSE;
+  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+  if (RegEax >= 0x80000001) {
+    AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+    if ((RegEdx & BIT20) != 0) {
+      //
+      // Bit 20: Execute Disable Bit available.
+      //
+      Available = TRUE;
+    }
+  }
+
+  return Available;
+}
+
+/**
+  Check if Execute Disable Bit (IA32_EFER.NXE) should be enabled or not.
+
+  @retval TRUE    IA32_EFER.NXE should be enabled.
+  @retval FALSE   IA32_EFER.NXE should not be enabled.
+
+**/
+BOOLEAN
+IsEnableNonExecNeeded (
+  VOID
+  )
+{
+  if (!IsExecuteDisableBitAvailable ()) {
+    return FALSE;
+  }
+
+  //
+  // XD flag (BIT63) in page table entry is only valid if IA32_EFER.NXE is set.
+  // Features controlled by Following PCDs need this feature to be enabled.
+  //
+  return (PcdGetBool (PcdSetNxForStack) ||
+          PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0 ||
+          PcdGet32 (PcdImageProtectionPolicy) != 0);
+}
+
+/**
+  Enable Execute Disable Bit.
+
+**/
+VOID
+EnableExecuteDisableBit (
+  VOID
+  )
+{
+  UINT64           MsrRegisters;
+
+  MsrRegisters = AsmReadMsr64 (0xC0000080);
+  MsrRegisters |= BIT11;
+  AsmWriteMsr64 (0xC0000080, MsrRegisters);
+}
+
+/**
+  The function will check if page table entry should be splitted to smaller
+  granularity.
+
+  @param Address      Physical memory address.
+  @param Size         Size of the given physical memory.
+  @param StackBase    Base address of stack.
+  @param StackSize    Size of stack.
+
+  @retval TRUE      Page table should be split.
+  @retval FALSE     Page table should not be split.
+**/
+BOOLEAN
+ToSplitPageTable (
+  IN EFI_PHYSICAL_ADDRESS               Address,
+  IN UINTN                              Size,
+  IN EFI_PHYSICAL_ADDRESS               StackBase,
+  IN UINTN                              StackSize
+  )
+{
+  if (IsNullDetectionEnabled () && Address == 0) {
+    return TRUE;
+  }
+
+  if (PcdGetBool (PcdCpuStackGuard)) {
+    if (StackBase >= Address && StackBase < (Address + Size)) {
+      return TRUE;
+    }
+  }
+
+  if (PcdGetBool (PcdSetNxForStack)) {
+    if ((Address < StackBase + StackSize) && ((Address + Size) > StackBase)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+/**
+  Initialize a buffer pool for page table use only.
+
+  To reduce the potential split operation on page table, the pages reserved for
+  page table should be allocated in the times of PAGE_TABLE_POOL_UNIT_PAGES and
+  at the boundary of PAGE_TABLE_POOL_ALIGNMENT. So the page pool is always
+  initialized with number of pages greater than or equal to the given PoolPages.
+
+  Once the pages in the pool are used up, this method should be called again to
+  reserve at least another PAGE_TABLE_POOL_UNIT_PAGES. But usually this won't
+  happen in practice.
+
+  @param PoolPages  The least page number of the pool to be created.
+
+  @retval TRUE    The pool is initialized successfully.
+  @retval FALSE   The memory is out of resource.
+**/
+BOOLEAN
+InitializePageTablePool (
+  IN UINTN           PoolPages
+  )
+{
+  VOID          *Buffer;
+
+  //
+  // Always reserve at least PAGE_TABLE_POOL_UNIT_PAGES, including one page for
+  // header.
+  //
+  PoolPages += 1;   // Add one page for header.
+  PoolPages = ((PoolPages - 1) / PAGE_TABLE_POOL_UNIT_PAGES + 1) *
+              PAGE_TABLE_POOL_UNIT_PAGES;
+  Buffer = AllocateAlignedPages (PoolPages, PAGE_TABLE_POOL_ALIGNMENT);
+  if (Buffer == NULL) {
+    DEBUG ((DEBUG_ERROR, "ERROR: Out of aligned pages\r\n"));
+    return FALSE;
+  }
+
+  //
+  // Link all pools into a list for easier track later.
+  //
+  if (mPageTablePool == NULL) {
+    mPageTablePool = Buffer;
+    mPageTablePool->NextPool = mPageTablePool;
+  } else {
+    ((PAGE_TABLE_POOL *)Buffer)->NextPool = mPageTablePool->NextPool;
+    mPageTablePool->NextPool = Buffer;
+    mPageTablePool = Buffer;
+  }
+
+  //
+  // Reserve one page for pool header.
+  //
+  mPageTablePool->FreePages  = PoolPages - 1;
+  mPageTablePool->Offset = EFI_PAGES_TO_SIZE (1);
+
+  return TRUE;
+}
+
+/**
+  This API provides a way to allocate memory for page table.
+
+  This API can be called more than once to allocate memory for page tables.
+
+  Allocates the number of 4KB pages and returns a pointer to the allocated
+  buffer. The buffer returned is aligned on a 4KB boundary.
+
+  If Pages is 0, then NULL is returned.
+  If there is not enough memory remaining to satisfy the request, then NULL is
+  returned.
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+AllocatePageTableMemory (
+  IN UINTN           Pages
+  )
+{
+  VOID          *Buffer;
+
+  if (Pages == 0) {
+    return NULL;
+  }
+
+  //
+  // Renew the pool if necessary.
+  //
+  if (mPageTablePool == NULL ||
+      Pages > mPageTablePool->FreePages) {
+    if (!InitializePageTablePool (Pages)) {
+      return NULL;
+    }
+  }
+
+  Buffer = (UINT8 *)mPageTablePool + mPageTablePool->Offset;
+
+  mPageTablePool->Offset     += EFI_PAGES_TO_SIZE (Pages);
+  mPageTablePool->FreePages  -= Pages;
+
+  return Buffer;
+}
+
+/**
+  Split 2M page to 4K.
+
+  @param[in]      PhysicalAddress       Start physical address the 2M page covered.
+  @param[in, out] PageEntry2M           Pointer to 2M page entry.
+  @param[in]      StackBase             Stack base address.
+  @param[in]      StackSize             Stack size.
+
+**/
+VOID
+Split2MPageTo4K (
+  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
+  IN OUT UINT64                         *PageEntry2M,
+  IN EFI_PHYSICAL_ADDRESS               StackBase,
+  IN UINTN                              StackSize
+  )
+{
+  EFI_PHYSICAL_ADDRESS                  PhysicalAddress4K;
+  UINTN                                 IndexOfPageTableEntries;
+  PAGE_TABLE_4K_ENTRY                   *PageTableEntry;
+  UINT64                                AddressEncMask;
+
+  //
+  // Make sure AddressEncMask is contained to smallest supported address field
+  //
+  AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
+
+  PageTableEntry = AllocatePageTableMemory (1);
+  ASSERT (PageTableEntry != NULL);
+
+  //
+  // Fill in 2M page entry.
+  //
+  *PageEntry2M = (UINT64) (UINTN) PageTableEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW;
+
+  PhysicalAddress4K = PhysicalAddress;
+  for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512; IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB) {
+    //
+    // Fill in the Page Table entries
+    //
+    PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask;
+    PageTableEntry->Bits.ReadWrite = 1;
+
+    if ((IsNullDetectionEnabled () && PhysicalAddress4K == 0) ||
+        (PcdGetBool (PcdCpuStackGuard) && PhysicalAddress4K == StackBase)) {
+      PageTableEntry->Bits.Present = 0;
+    } else {
+      PageTableEntry->Bits.Present = 1;
+    }
+
+    if (PcdGetBool (PcdSetNxForStack)
+        && (PhysicalAddress4K >= StackBase)
+        && (PhysicalAddress4K < StackBase + StackSize)) {
+      //
+      // Set Nx bit for stack.
+      //
+      PageTableEntry->Bits.Nx = 1;
+    }
+  }
+}
+
+/**
+  Split 1G page to 2M.
+
+  @param[in]      PhysicalAddress       Start physical address the 1G page covered.
+  @param[in, out] PageEntry1G           Pointer to 1G page entry.
+  @param[in]      StackBase             Stack base address.
+  @param[in]      StackSize             Stack size.
+
+**/
+VOID
+Split1GPageTo2M (
+  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
+  IN OUT UINT64                         *PageEntry1G,
+  IN EFI_PHYSICAL_ADDRESS               StackBase,
+  IN UINTN                              StackSize
+  )
+{
+  EFI_PHYSICAL_ADDRESS                  PhysicalAddress2M;
+  UINTN                                 IndexOfPageDirectoryEntries;
+  PAGE_TABLE_ENTRY                      *PageDirectoryEntry;
+  UINT64                                AddressEncMask;
+
+  //
+  // Make sure AddressEncMask is contained to smallest supported address field
+  //
+  AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
+
+  PageDirectoryEntry = AllocatePageTableMemory (1);
+  ASSERT (PageDirectoryEntry != NULL);
+
+  //
+  // Fill in 1G page entry.
+  //
+  *PageEntry1G = (UINT64) (UINTN) PageDirectoryEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW;
+
+  PhysicalAddress2M = PhysicalAddress;
+  for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) {
+    if (ToSplitPageTable (PhysicalAddress2M, SIZE_2MB, StackBase, StackSize)) {
+      //
+      // Need to split this 2M page that covers NULL or stack range.
+      //
+      Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
+    } else {
+      //
+      // Fill in the Page Directory entries
+      //
+      PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress2M | AddressEncMask;
+      PageDirectoryEntry->Bits.ReadWrite = 1;
+      PageDirectoryEntry->Bits.Present = 1;
+      PageDirectoryEntry->Bits.MustBe1 = 1;
+    }
+  }
+}
+
+/**
+  Set one page of page table pool memory to be read-only.
+
+  @param[in] PageTableBase    Base address of page table (CR3).
+  @param[in] Address          Start address of a page to be set as read-only.
+  @param[in] Level4Paging     Level 4 paging flag.
+
+**/
+VOID
+SetPageTablePoolReadOnly (
+  IN  UINTN                             PageTableBase,
+  IN  EFI_PHYSICAL_ADDRESS              Address,
+  IN  BOOLEAN                           Level4Paging
+  )
+{
+  UINTN                 Index;
+  UINTN                 EntryIndex;
+  UINT64                AddressEncMask;
+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;
+  UINT64                *PageTable;
+  UINT64                *NewPageTable;
+  UINT64                PageAttr;
+  UINT64                LevelSize[5];
+  UINT64                LevelMask[5];
+  UINTN                 LevelShift[5];
+  UINTN                 Level;
+  UINT64                PoolUnitSize;
+
+  ASSERT (PageTableBase != 0);
+
+  //
+  // Since the page table is always from page table pool, which is always
+  // located at the boundary of PcdPageTablePoolAlignment, we just need to
+  // set the whole pool unit to be read-only.
+  //
+  Address = Address & PAGE_TABLE_POOL_ALIGN_MASK;
+
+  LevelShift[1] = PAGING_L1_ADDRESS_SHIFT;
+  LevelShift[2] = PAGING_L2_ADDRESS_SHIFT;
+  LevelShift[3] = PAGING_L3_ADDRESS_SHIFT;
+  LevelShift[4] = PAGING_L4_ADDRESS_SHIFT;
+
+  LevelMask[1] = PAGING_4K_ADDRESS_MASK_64;
+  LevelMask[2] = PAGING_2M_ADDRESS_MASK_64;
+  LevelMask[3] = PAGING_1G_ADDRESS_MASK_64;
+  LevelMask[4] = PAGING_1G_ADDRESS_MASK_64;
+
+  LevelSize[1] = SIZE_4KB;
+  LevelSize[2] = SIZE_2MB;
+  LevelSize[3] = SIZE_1GB;
+  LevelSize[4] = SIZE_512GB;
+
+  AddressEncMask  = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &
+                    PAGING_1G_ADDRESS_MASK_64;
+  PageTable       = (UINT64 *)(UINTN)PageTableBase;
+  PoolUnitSize    = PAGE_TABLE_POOL_UNIT_SIZE;
+
+  for (Level = (Level4Paging) ? 4 : 3; Level > 0; --Level) {
+    Index = ((UINTN)RShiftU64 (Address, LevelShift[Level]));
+    Index &= PAGING_PAE_INDEX_MASK;
+
+    PageAttr = PageTable[Index];
+    if ((PageAttr & IA32_PG_PS) == 0) {
+      //
+      // Go to next level of table.
+      //
+      PageTable = (UINT64 *)(UINTN)(PageAttr & ~AddressEncMask &
+                                    PAGING_4K_ADDRESS_MASK_64);
+      continue;
+    }
+
+    if (PoolUnitSize >= LevelSize[Level]) {
+      //
+      // Clear R/W bit if current page granularity is not larger than pool unit
+      // size.
+      //
+      if ((PageAttr & IA32_PG_RW) != 0) {
+        while (PoolUnitSize > 0) {
+          //
+          // PAGE_TABLE_POOL_UNIT_SIZE and PAGE_TABLE_POOL_ALIGNMENT are fit in
+          // one page (2MB). Then we don't need to update attributes for pages
+          // crossing page directory. ASSERT below is for that purpose.
+          //
+          ASSERT (Index < EFI_PAGE_SIZE/sizeof (UINT64));
+
+          PageTable[Index] &= ~(UINT64)IA32_PG_RW;
+          PoolUnitSize    -= LevelSize[Level];
+
+          ++Index;
+        }
+      }
+
+      break;
+
+    } else {
+      //
+      // The smaller granularity of page must be needed.
+      //
+      ASSERT (Level > 1);
+
+      NewPageTable = AllocatePageTableMemory (1);
+      ASSERT (NewPageTable != NULL);
+
+      PhysicalAddress = PageAttr & LevelMask[Level];
+      for (EntryIndex = 0;
+            EntryIndex < EFI_PAGE_SIZE/sizeof (UINT64);
+            ++EntryIndex) {
+        NewPageTable[EntryIndex] = PhysicalAddress  | AddressEncMask |
+                                   IA32_PG_P | IA32_PG_RW;
+        if (Level > 2) {
+          NewPageTable[EntryIndex] |= IA32_PG_PS;
+        }
+        PhysicalAddress += LevelSize[Level - 1];
+      }
+
+      PageTable[Index] = (UINT64)(UINTN)NewPageTable | AddressEncMask |
+                                        IA32_PG_P | IA32_PG_RW;
+      PageTable = NewPageTable;
+    }
+  }
+}
+
+/**
+  Prevent the memory pages used for page table from been overwritten.
+
+  @param[in] PageTableBase    Base address of page table (CR3).
+  @param[in] Level4Paging     Level 4 paging flag.
+
+**/
+VOID
+EnablePageTableProtection (
+  IN  UINTN     PageTableBase,
+  IN  BOOLEAN   Level4Paging
+  )
+{
+  PAGE_TABLE_POOL         *HeadPool;
+  PAGE_TABLE_POOL         *Pool;
+  UINT64                  PoolSize;
+  EFI_PHYSICAL_ADDRESS    Address;
+
+  if (mPageTablePool == NULL) {
+    return;
+  }
+
+  //
+  // Disable write protection, because we need to mark page table to be write
+  // protected.
+  //
+  AsmWriteCr0 (AsmReadCr0() & ~CR0_WP);
+
+  //
+  // SetPageTablePoolReadOnly might update mPageTablePool. It's safer to
+  // remember original one in advance.
+  //
+  HeadPool = mPageTablePool;
+  Pool = HeadPool;
+  do {
+    Address  = (EFI_PHYSICAL_ADDRESS)(UINTN)Pool;
+    PoolSize = Pool->Offset + EFI_PAGES_TO_SIZE (Pool->FreePages);
+
+    //
+    // The size of one pool must be multiple of PAGE_TABLE_POOL_UNIT_SIZE, which
+    // is one of page size of the processor (2MB by default). Let's apply the
+    // protection to them one by one.
+    //
+    while (PoolSize > 0) {
+      SetPageTablePoolReadOnly(PageTableBase, Address, Level4Paging);
+      Address   += PAGE_TABLE_POOL_UNIT_SIZE;
+      PoolSize  -= PAGE_TABLE_POOL_UNIT_SIZE;
+    }
+
+    Pool = Pool->NextPool;
+  } while (Pool != HeadPool);
+
+  //
+  // Enable write protection, after page table attribute updated.
+  //
+  AsmWriteCr0 (AsmReadCr0() | CR0_WP);
+}
+
+/**
+  Allocates and fills in the Page Directory and Page Table Entries to
+  establish a 1:1 Virtual to Physical mapping.
+
+  @param[in] StackBase  Stack base address.
+  @param[in] StackSize  Stack size.
+
+  @return The address of 4 level page map.
+
+**/
+UINTN
+CreateIdentityMappingPageTables (
+  IN EFI_PHYSICAL_ADDRESS   StackBase,
+  IN UINTN                  StackSize
+  )
+{
+  UINT32                                        RegEax;
+  CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX   EcxFlags;
+  UINT32                                        RegEdx;
+  UINT8                                         PhysicalAddressBits;
+  EFI_PHYSICAL_ADDRESS                          PageAddress;
+  UINTN                                         IndexOfPml5Entries;
+  UINTN                                         IndexOfPml4Entries;
+  UINTN                                         IndexOfPdpEntries;
+  UINTN                                         IndexOfPageDirectoryEntries;
+  UINT32                                        NumberOfPml5EntriesNeeded;
+  UINT32                                        NumberOfPml4EntriesNeeded;
+  UINT32                                        NumberOfPdpEntriesNeeded;
+  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMapLevel5Entry;
+  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMapLevel4Entry;
+  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMap;
+  PAGE_MAP_AND_DIRECTORY_POINTER                *PageDirectoryPointerEntry;
+  PAGE_TABLE_ENTRY                              *PageDirectoryEntry;
+  UINTN                                         TotalPagesNum;
+  UINTN                                         BigPageAddress;
+  VOID                                          *Hob;
+  BOOLEAN                                       Page5LevelSupport;
+  BOOLEAN                                       Page1GSupport;
+  PAGE_TABLE_1G_ENTRY                           *PageDirectory1GEntry;
+  UINT64                                        AddressEncMask;
+  IA32_CR4                                      Cr4;
+
+  //
+  // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings
+  //
+  PageMapLevel5Entry = NULL;
+
+  //
+  // Make sure AddressEncMask is contained to smallest supported address field
+  //
+  AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
+
+  Page1GSupport = FALSE;
+  if (PcdGetBool(PcdUse1GPageTable)) {
+    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+    if (RegEax >= 0x80000001) {
+      AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+      if ((RegEdx & BIT26) != 0) {
+        Page1GSupport = TRUE;
+      }
+    }
+  }
+
+  //
+  // Get physical address bits supported.
+  //
+  Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
+  if (Hob != NULL) {
+    PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
+  } else {
+    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+    if (RegEax >= 0x80000008) {
+      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+      PhysicalAddressBits = (UINT8) RegEax;
+    } else {
+      PhysicalAddressBits = 36;
+    }
+  }
+
+  Page5LevelSupport = FALSE;
+  if (PcdGetBool (PcdUse5LevelPageTable)) {
+    AsmCpuidEx (
+      CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, NULL,
+      &EcxFlags.Uint32, NULL, NULL
+      );
+    if (EcxFlags.Bits.FiveLevelPage != 0) {
+      Page5LevelSupport = TRUE;
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "AddressBits=%u 5LevelPaging=%u 1GPage=%u\n", PhysicalAddressBits, Page5LevelSupport, Page1GSupport));
+
+  //
+  // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses
+  //  when 5-Level Paging is disabled,
+  //  due to either unsupported by HW, or disabled by PCD.
+  //
+  ASSERT (PhysicalAddressBits <= 52);
+  if (!Page5LevelSupport && PhysicalAddressBits > 48) {
+    PhysicalAddressBits = 48;
+  }
+
+  //
+  // Calculate the table entries needed.
+  //
+  NumberOfPml5EntriesNeeded = 1;
+  if (PhysicalAddressBits > 48) {
+    NumberOfPml5EntriesNeeded = (UINT32) LShiftU64 (1, PhysicalAddressBits - 48);
+    PhysicalAddressBits = 48;
+  }
+
+  NumberOfPml4EntriesNeeded = 1;
+  if (PhysicalAddressBits > 39) {
+    NumberOfPml4EntriesNeeded = (UINT32) LShiftU64 (1, PhysicalAddressBits - 39);
+    PhysicalAddressBits = 39;
+  }
+
+  NumberOfPdpEntriesNeeded = 1;
+  ASSERT (PhysicalAddressBits > 30);
+  NumberOfPdpEntriesNeeded = (UINT32) LShiftU64 (1, PhysicalAddressBits - 30);
+
+  //
+  // Pre-allocate big pages to avoid later allocations.
+  //
+  if (!Page1GSupport) {
+    TotalPagesNum = ((NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1) * NumberOfPml5EntriesNeeded + 1;
+  } else {
+    TotalPagesNum = (NumberOfPml4EntriesNeeded + 1) * NumberOfPml5EntriesNeeded + 1;
+  }
+
+  //
+  // Substract the one page occupied by PML5 entries if 5-Level Paging is disabled.
+  //
+  if (!Page5LevelSupport) {
+    TotalPagesNum--;
+  }
+
+  DEBUG ((DEBUG_INFO, "Pml5=%u Pml4=%u Pdp=%u TotalPage=%Lu\n",
+    NumberOfPml5EntriesNeeded, NumberOfPml4EntriesNeeded,
+    NumberOfPdpEntriesNeeded, (UINT64)TotalPagesNum));
+
+  BigPageAddress = (UINTN) AllocatePageTableMemory (TotalPagesNum);
+  ASSERT (BigPageAddress != 0);
+
+  //
+  // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
+  //
+  PageMap         = (VOID *) BigPageAddress;
+  if (Page5LevelSupport) {
+    //
+    // By architecture only one PageMapLevel5 exists - so lets allocate storage for it.
+    //
+    PageMapLevel5Entry = PageMap;
+    BigPageAddress    += SIZE_4KB;
+  }
+  PageAddress        = 0;
+
+  for ( IndexOfPml5Entries = 0
+      ; IndexOfPml5Entries < NumberOfPml5EntriesNeeded
+      ; IndexOfPml5Entries++) {
+    //
+    // Each PML5 entry points to a page of PML4 entires.
+    // So lets allocate space for them and fill them in in the IndexOfPml4Entries loop.
+    // When 5-Level Paging is disabled, below allocation happens only once.
+    //
+    PageMapLevel4Entry = (VOID *) BigPageAddress;
+    BigPageAddress    += SIZE_4KB;
+
+    if (Page5LevelSupport) {
+      //
+      // Make a PML5 Entry
+      //
+      PageMapLevel5Entry->Uint64 = (UINT64) (UINTN) PageMapLevel4Entry | AddressEncMask;
+      PageMapLevel5Entry->Bits.ReadWrite = 1;
+      PageMapLevel5Entry->Bits.Present   = 1;
+      PageMapLevel5Entry++;
+    }
+
+    for ( IndexOfPml4Entries = 0
+        ; IndexOfPml4Entries < (NumberOfPml5EntriesNeeded == 1 ? NumberOfPml4EntriesNeeded : 512)
+        ; IndexOfPml4Entries++, PageMapLevel4Entry++) {
+      //
+      // Each PML4 entry points to a page of Page Directory Pointer entires.
+      // So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
+      //
+      PageDirectoryPointerEntry = (VOID *) BigPageAddress;
+      BigPageAddress += SIZE_4KB;
+
+      //
+      // Make a PML4 Entry
+      //
+      PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask;
+      PageMapLevel4Entry->Bits.ReadWrite = 1;
+      PageMapLevel4Entry->Bits.Present = 1;
+
+      if (Page1GSupport) {
+        PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;
+
+        for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
+          if (ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSize)) {
+            Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize);
+          } else {
+            //
+            // Fill in the Page Directory entries
+            //
+            PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | AddressEncMask;
+            PageDirectory1GEntry->Bits.ReadWrite = 1;
+            PageDirectory1GEntry->Bits.Present = 1;
+            PageDirectory1GEntry->Bits.MustBe1 = 1;
+          }
+        }
+      } else {
+        for ( IndexOfPdpEntries = 0
+            ; IndexOfPdpEntries < (NumberOfPml4EntriesNeeded == 1 ? NumberOfPdpEntriesNeeded : 512)
+            ; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
+          //
+          // Each Directory Pointer entries points to a page of Page Directory entires.
+          // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
+          //
+          PageDirectoryEntry = (VOID *) BigPageAddress;
+          BigPageAddress += SIZE_4KB;
+
+          //
+          // Fill in a Page Directory Pointer Entries
+          //
+          PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask;
+          PageDirectoryPointerEntry->Bits.ReadWrite = 1;
+          PageDirectoryPointerEntry->Bits.Present = 1;
+
+          for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
+            if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSize)) {
+              //
+              // Need to split this 2M page that covers NULL or stack range.
+              //
+              Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
+            } else {
+              //
+              // Fill in the Page Directory entries
+              //
+              PageDirectoryEntry->Uint64 = (UINT64)PageAddress | AddressEncMask;
+              PageDirectoryEntry->Bits.ReadWrite = 1;
+              PageDirectoryEntry->Bits.Present = 1;
+              PageDirectoryEntry->Bits.MustBe1 = 1;
+            }
+          }
+        }
+
+        //
+        // Fill with null entry for unused PDPTE
+        //
+        ZeroMem (PageDirectoryPointerEntry, (512 - IndexOfPdpEntries) * sizeof(PAGE_MAP_AND_DIRECTORY_POINTER));
+      }
+    }
+
+    //
+    // For the PML4 entries we are not using fill in a null entry.
+    //
+    ZeroMem (PageMapLevel4Entry, (512 - IndexOfPml4Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER));
+  }
+
+  if (Page5LevelSupport) {
+    Cr4.UintN = AsmReadCr4 ();
+    Cr4.Bits.LA57 = 1;
+    AsmWriteCr4 (Cr4.UintN);
+    //
+    // For the PML5 entries we are not using fill in a null entry.
+    //
+    ZeroMem (PageMapLevel5Entry, (512 - IndexOfPml5Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER));
+  }
+
+  //
+  // Protect the page table by marking the memory used for page table to be
+  // read-only.
+  //
+  EnablePageTableProtection ((UINTN)PageMap, TRUE);
+
+  //
+  // Set IA32_EFER.NXE if necessary.
+  //
+  if (IsEnableNonExecNeeded ()) {
+    EnableExecuteDisableBit ();
+  }
+
+  return (UINTN)PageMap;
+}
+
diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h
new file mode 100644
index 0000000000..2d0493f109
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h
@@ -0,0 +1,322 @@
+/** @file
+  x64 Long Mode Virtual Memory Management Definitions
+
+  References:
+    1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic Architecture, Intel
+    2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
+    3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
+    4) AMD64 Architecture Programmer's Manual Volume 2: System Programming
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _VIRTUAL_MEMORY_H_
+#define _VIRTUAL_MEMORY_H_
+
+
+#define SYS_CODE64_SEL 0x38
+
+
+#pragma pack(1)
+
+typedef union {
+  struct {
+    UINT32  LimitLow    : 16;
+    UINT32  BaseLow     : 16;
+    UINT32  BaseMid     : 8;
+    UINT32  Type        : 4;
+    UINT32  System      : 1;
+    UINT32  Dpl         : 2;
+    UINT32  Present     : 1;
+    UINT32  LimitHigh   : 4;
+    UINT32  Software    : 1;
+    UINT32  Reserved    : 1;
+    UINT32  DefaultSize : 1;
+    UINT32  Granularity : 1;
+    UINT32  BaseHigh    : 8;
+  } Bits;
+  UINT64  Uint64;
+} IA32_GDT;
+
+typedef struct {
+  IA32_IDT_GATE_DESCRIPTOR  Ia32IdtEntry;
+  UINT32                    Offset32To63;
+  UINT32                    Reserved;
+} X64_IDT_GATE_DESCRIPTOR;
+
+//
+// Page-Map Level-4 Offset (PML4) and
+// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
+//
+
+typedef union {
+  struct {
+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
+    UINT64  Reserved:1;               // Reserved
+    UINT64  MustBeZero:2;             // Must Be Zero
+    UINT64  Available:3;              // Available for use by system software
+    UINT64  PageTableBaseAddress:40;  // Page Table Base Address
+    UINT64  AvabilableHigh:11;        // Available for use by system software
+    UINT64  Nx:1;                     // No Execute bit
+  } Bits;
+  UINT64    Uint64;
+} PAGE_MAP_AND_DIRECTORY_POINTER;
+
+//
+// Page Table Entry 4KB
+//
+typedef union {
+  struct {
+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
+    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page
+    UINT64  PAT:1;                    //
+    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
+    UINT64  Available:3;              // Available for use by system software
+    UINT64  PageTableBaseAddress:40;  // Page Table Base Address
+    UINT64  AvabilableHigh:11;        // Available for use by system software
+    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
+  } Bits;
+  UINT64    Uint64;
+} PAGE_TABLE_4K_ENTRY;
+
+//
+// Page Table Entry 2MB
+//
+typedef union {
+  struct {
+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
+    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page
+    UINT64  MustBe1:1;                // Must be 1
+    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
+    UINT64  Available:3;              // Available for use by system software
+    UINT64  PAT:1;                    //
+    UINT64  MustBeZero:8;             // Must be zero;
+    UINT64  PageTableBaseAddress:31;  // Page Table Base Address
+    UINT64  AvabilableHigh:11;        // Available for use by system software
+    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
+  } Bits;
+  UINT64    Uint64;
+} PAGE_TABLE_ENTRY;
+
+//
+// Page Table Entry 1GB
+//
+typedef union {
+  struct {
+    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in memory
+    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
+    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
+    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through caching
+    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
+    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
+    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access to page
+    UINT64  MustBe1:1;                // Must be 1
+    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
+    UINT64  Available:3;              // Available for use by system software
+    UINT64  PAT:1;                    //
+    UINT64  MustBeZero:17;            // Must be zero;
+    UINT64  PageTableBaseAddress:22;  // Page Table Base Address
+    UINT64  AvabilableHigh:11;        // Available for use by system software
+    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
+  } Bits;
+  UINT64    Uint64;
+} PAGE_TABLE_1G_ENTRY;
+
+#pragma pack()
+
+#define CR0_WP                      BIT16
+
+#define IA32_PG_P                   BIT0
+#define IA32_PG_RW                  BIT1
+#define IA32_PG_PS                  BIT7
+
+#define PAGING_PAE_INDEX_MASK       0x1FF
+
+#define PAGING_4K_ADDRESS_MASK_64   0x000FFFFFFFFFF000ull
+#define PAGING_2M_ADDRESS_MASK_64   0x000FFFFFFFE00000ull
+#define PAGING_1G_ADDRESS_MASK_64   0x000FFFFFC0000000ull
+
+#define PAGING_L1_ADDRESS_SHIFT     12
+#define PAGING_L2_ADDRESS_SHIFT     21
+#define PAGING_L3_ADDRESS_SHIFT     30
+#define PAGING_L4_ADDRESS_SHIFT     39
+
+#define PAGING_PML4E_NUMBER         4
+
+#define PAGE_TABLE_POOL_ALIGNMENT   BASE_2MB
+#define PAGE_TABLE_POOL_UNIT_SIZE   SIZE_2MB
+#define PAGE_TABLE_POOL_UNIT_PAGES  EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE)
+#define PAGE_TABLE_POOL_ALIGN_MASK  \
+  (~(EFI_PHYSICAL_ADDRESS)(PAGE_TABLE_POOL_ALIGNMENT - 1))
+
+typedef struct {
+  VOID            *NextPool;
+  UINTN           Offset;
+  UINTN           FreePages;
+} PAGE_TABLE_POOL;
+
+/**
+  Check if Execute Disable Bit (IA32_EFER.NXE) should be enabled or not.
+
+  @retval TRUE    IA32_EFER.NXE should be enabled.
+  @retval FALSE   IA32_EFER.NXE should not be enabled.
+
+**/
+BOOLEAN
+IsEnableNonExecNeeded (
+  VOID
+  );
+
+/**
+  Enable Execute Disable Bit.
+
+**/
+VOID
+EnableExecuteDisableBit (
+  VOID
+  );
+
+/**
+  Split 2M page to 4K.
+
+  @param[in]      PhysicalAddress       Start physical address the 2M page covered.
+  @param[in, out] PageEntry2M           Pointer to 2M page entry.
+  @param[in]      StackBase             Stack base address.
+  @param[in]      StackSize             Stack size.
+
+**/
+VOID
+Split2MPageTo4K (
+  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
+  IN OUT UINT64                         *PageEntry2M,
+  IN EFI_PHYSICAL_ADDRESS               StackBase,
+  IN UINTN                              StackSize
+  );
+
+/**
+  Allocates and fills in the Page Directory and Page Table Entries to
+  establish a 1:1 Virtual to Physical mapping.
+
+  @param[in] StackBase  Stack base address.
+  @param[in] StackSize  Stack size.
+
+  @return The address of 4 level page map.
+
+**/
+UINTN
+CreateIdentityMappingPageTables (
+  IN EFI_PHYSICAL_ADDRESS   StackBase,
+  IN UINTN                  StackSize
+  );
+
+
+/**
+
+  Fix up the vector number in the vector code.
+
+  @param VectorBase   Base address of the vector handler.
+  @param VectorNum    Index of vector.
+
+**/
+VOID
+EFIAPI
+AsmVectorFixup (
+  VOID    *VectorBase,
+  UINT8   VectorNum
+  );
+
+
+/**
+
+  Get the information of vector template.
+
+  @param TemplateBase   Base address of the template code.
+
+  @return               Size of the Template code.
+
+**/
+UINTN
+EFIAPI
+AsmGetVectorTemplatInfo (
+  OUT   VOID  **TemplateBase
+  );
+
+/**
+  Clear legacy memory located at the first 4K-page.
+
+  This function traverses the whole HOB list to check if memory from 0 to 4095
+  exists and has not been allocated, and then clear it if so.
+
+  @param HobStart         The start of HobList passed to DxeCore.
+
+**/
+VOID
+ClearFirst4KPage (
+  IN  VOID *HobStart
+  );
+
+/**
+  Return configure status of NULL pointer detection feature.
+
+  @return TRUE   NULL pointer detection feature is enabled
+  @return FALSE  NULL pointer detection feature is disabled
+**/
+BOOLEAN
+IsNullDetectionEnabled (
+  VOID
+  );
+
+/**
+  Prevent the memory pages used for page table from been overwritten.
+
+  @param[in] PageTableBase    Base address of page table (CR3).
+  @param[in] Level4Paging     Level 4 paging flag.
+
+**/
+VOID
+EnablePageTableProtection (
+  IN  UINTN     PageTableBase,
+  IN  BOOLEAN   Level4Paging
+  );
+
+/**
+  This API provides a way to allocate memory for page table.
+
+  This API can be called more than once to allocate memory for page tables.
+
+  Allocates the number of 4KB pages and returns a pointer to the allocated
+  buffer. The buffer returned is aligned on a 4KB boundary.
+
+  If Pages is 0, then NULL is returned.
+  If there is not enough memory remaining to satisfy the request, then NULL is
+  returned.
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+AllocatePageTableMemory (
+  IN UINTN           Pages
+  );
+
+#endif
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec
index 1559735db2..99cb3311a6 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dec
+++ b/UefiPayloadPkg/UefiPayloadPkg.dec
@@ -3,7 +3,7 @@
 #
 # Provides drivers and definitions to create uefi payload for bootloaders.
 #
-# Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 ##
@@ -68,4 +68,5 @@ gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0x04|UINT32|0x0
 gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|0xC0|UINT32|0x00000015
 gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|0x80|UINT32|0x00000016
 
-
+# Size of the region used by UEFI in permanent memory
+gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x02000000|UINT32|0x00000017
diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
similarity index 90%
rename from UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
rename to UefiPayloadPkg/UefiPayloadPkg.dsc
index e18c4678e8..b772c8456e 100644
--- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -92,6 +92,12 @@
   INTEL:RELEASE_*_*_CC_FLAGS     = /D MDEPKG_NDEBUG
   MSFT:RELEASE_*_*_CC_FLAGS      = /D MDEPKG_NDEBUG
 
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  GCC:*_*_*_DLINK_FLAGS      = -z common-page-size=0x1000
+  XCODE:*_*_*_DLINK_FLAGS    = -seg1addr 0x1000 -segalign 0x1000
+  XCODE:*_*_*_MTOC_FLAGS     = -align 0x1000
+  CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096
+  MSFT:*_*_*_DLINK_FLAGS     = /ALIGN:4096
 
 ################################################################################
 #
@@ -110,8 +116,6 @@
   #
   # Entry point
   #
-  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
-  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
   DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
   UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
   UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
@@ -149,8 +153,6 @@
   HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
   DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
   UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
-  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
-  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
   DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
   DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
   UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
@@ -210,23 +212,9 @@
   TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
   VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
 
-[LibraryClasses.IA32.SEC]
-  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+[LibraryClasses.common.SEC]
+  HobLib|UefiPayloadPkg/Library/HobLib/HobLib.inf
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
-  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
-  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
-  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
-  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
-
-[LibraryClasses.IA32.PEI_CORE, LibraryClasses.IA32.PEIM]
-  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
-  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
-  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
-  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
-  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
-!if $(SOURCE_DEBUG_ENABLE)
-  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
-!endif
 
 [LibraryClasses.common.DXE_CORE]
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
@@ -372,29 +360,14 @@
 # Components Section - list of all EDK II Modules needed by this Platform.
 #
 ################################################################################
-[Components.IA32]
-  #
-  # SEC Core
-  #
-  UefiPayloadPkg/SecCore/SecCore.inf
-
-  #
-  # PEI Core
-  #
-  MdeModulePkg/Core/Pei/PeiMain.inf
 
-  #
-  # PEIM
-  #
-  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
-    <LibraryClasses>
-      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
-  }
-  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
-  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
-
-  UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
-  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+!if "IA32" in $(ARCH)
+  [Components.IA32]
+    UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
+!else
+  [Components.X64]
+    UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
+!endif
 
 [Components.X64]
   #
diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf
index 570a8ee7fd..c81b405c6e 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.fdf
+++ b/UefiPayloadPkg/UefiPayloadPkg.fdf
@@ -13,13 +13,10 @@ DEFINE FD_BASE       = 0x00800000
 DEFINE FD_BLOCK_SIZE = 0x00001000
 
 !if $(TARGET) == "NOOPT"
-DEFINE PEI_FV_SIZE = 0x00050000
-DEFINE DXE_FV_SIZE = 0x00800000
 DEFINE FD_SIZE     = 0x00850000
 DEFINE NUM_BLOCKS  = 0x850
 !else
-DEFINE PEI_FV_SIZE = 0x30000
-DEFINE DXE_FV_SIZE = 0x3E0000
+
 DEFINE FD_SIZE     = 0x00410000
 DEFINE NUM_BLOCKS  = 0x410
 !endif
@@ -32,14 +29,11 @@ ErasePolarity = 1
 BlockSize     = $(FD_BLOCK_SIZE)
 NumBlocks     = $(NUM_BLOCKS)
 
-0x00000000|$(PEI_FV_SIZE)
-FV = PEIFV
-
-$(PEI_FV_SIZE)|$(DXE_FV_SIZE)
-FV = DXEFV
+0x00000000|$(FD_SIZE)
+FV = PLDFV
 
 ################################################################################
-[FV.PEIFV]
+[FV.PLDFV]
 BlockSize          = $(FD_BLOCK_SIZE)
 FvAlignment        = 16
 ERASE_POLARITY     = 1
@@ -58,14 +52,11 @@ READ_STATUS        = TRUE
 READ_LOCK_CAP      = TRUE
 READ_LOCK_STATUS   = TRUE
 
-INF UefiPayloadPkg/SecCore/SecCore.inf
+INF UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
 
-INF MdeModulePkg/Core/Pei/PeiMain.inf
-INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
-INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
-INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
-INF UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
-INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+FILE FV_IMAGE = 4E35FD93-9C72-4c15-8C4B-E77F1DB2D793 {
+    SECTION FV_IMAGE = DXEFV
+}
 
 ################################################################################
 
@@ -89,11 +80,6 @@ READ_STATUS        = TRUE
 READ_LOCK_CAP      = TRUE
 READ_LOCK_STATUS   = TRUE
 
-APRIORI DXE {
-  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
-  INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
-  INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
-}
 
 #
 # DXE Phase modules
diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
deleted file mode 100644
index 12d7ffe814..0000000000
--- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
+++ /dev/null
@@ -1,585 +0,0 @@
-## @file
-# Bootloader Payload Package
-#
-# Provides drivers and definitions to create uefi payload for bootloaders.
-#
-# Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-################################################################################
-#
-# Defines Section - statements that will be processed to create a Makefile.
-#
-################################################################################
-[Defines]
-  PLATFORM_NAME                       = UefiPayloadPkg
-  PLATFORM_GUID                       = F71608AB-D63D-4491-B744-A99998C8CD96
-  PLATFORM_VERSION                    = 0.1
-  DSC_SPECIFICATION                   = 0x00010005
-  SUPPORTED_ARCHITECTURES             = IA32
-  BUILD_TARGETS                       = DEBUG|RELEASE|NOOPT
-  SKUID_IDENTIFIER                    = DEFAULT
-  OUTPUT_DIRECTORY                    = Build/UefiPayloadPkgIA32
-  FLASH_DEFINITION                    = UefiPayloadPkg/UefiPayloadPkg.fdf
-
-  DEFINE SOURCE_DEBUG_ENABLE          = FALSE
-
-  #
-  # SBL:      UEFI payload for Slim Bootloader
-  # COREBOOT: UEFI payload for coreboot
-  #
-  DEFINE   BOOTLOADER = SBL
-
-  #
-  # CPU options
-  #
-  DEFINE MAX_LOGICAL_PROCESSORS       = 64
-
-  #
-  # PCI options
-  #
-  DEFINE PCIE_BASE_SUPPORT            = TRUE
-
-  #
-  # Serial port set up
-  #
-  DEFINE BAUD_RATE                    = 115200
-  DEFINE SERIAL_CLOCK_RATE            = 1843200
-  DEFINE SERIAL_LINE_CONTROL          = 3 # 8-bits, no parity
-  DEFINE SERIAL_HARDWARE_FLOW_CONTROL = FALSE
-  DEFINE SERIAL_DETECT_CABLE          = FALSE
-  DEFINE SERIAL_FIFO_CONTROL          = 7 # Enable FIFO
-  DEFINE SERIAL_EXTENDED_TX_FIFO_SIZE = 16
-  DEFINE UART_DEFAULT_BAUD_RATE       = $(BAUD_RATE)
-  DEFINE UART_DEFAULT_DATA_BITS       = 8
-  DEFINE UART_DEFAULT_PARITY          = 1
-  DEFINE UART_DEFAULT_STOP_BITS       = 1
-  DEFINE DEFAULT_TERMINAL_TYPE        = 0
-
-  # Enabling the serial terminal will slow down the boot menu redering!
-  DEFINE DISABLE_SERIAL_TERMINAL      = FALSE
-
-  #
-  #  typedef struct {
-  #    UINT16  VendorId;          ///< Vendor ID to match the PCI device.  The value 0xFFFF terminates the list of entries.
-  #    UINT16  DeviceId;          ///< Device ID to match the PCI device
-  #    UINT32  ClockRate;         ///< UART clock rate.  Set to 0 for default clock rate of 1843200 Hz
-  #    UINT64  Offset;            ///< The byte offset into to the BAR
-  #    UINT8   BarIndex;          ///< Which BAR to get the UART base address
-  #    UINT8   RegisterStride;    ///< UART register stride in bytes.  Set to 0 for default register stride of 1 byte.
-  #    UINT16  ReceiveFifoDepth;  ///< UART receive FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes.
-  #    UINT16  TransmitFifoDepth; ///< UART transmit FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes.
-  #    UINT8   Reserved[2];
-  #  } PCI_SERIAL_PARAMETER;
-  #
-  # Vendor FFFF Device 0000 Prog Interface 1, BAR #0, Offset 0, Stride = 1, Clock 1843200 (0x1c2000)
-  #
-  #                                       [Vendor]   [Device]  [----ClockRate---]  [------------Offset-----------] [Bar] [Stride] [RxFifo] [TxFifo]   [Rsvd]   [Vendor]
-  DEFINE PCI_SERIAL_PARAMETERS        = {0xff,0xff, 0x00,0x00, 0x0,0x20,0x1c,0x00, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x00,    0x01, 0x0,0x0, 0x0,0x0, 0x0,0x0, 0xff,0xff}
-
-  #
-  # Shell options: [BUILD_SHELL, MIN_BIN, NONE, UEFI_BIN]
-  #
-  DEFINE SHELL_TYPE                   = BUILD_SHELL
-
-[BuildOptions]
-  *_*_*_CC_FLAGS                 = -D DISABLE_NEW_DEPRECATED_INTERFACES
-  GCC:*_UNIXGCC_*_CC_FLAGS       = -DMDEPKG_NDEBUG
-  GCC:RELEASE_*_*_CC_FLAGS       = -DMDEPKG_NDEBUG
-  INTEL:RELEASE_*_*_CC_FLAGS     = /D MDEPKG_NDEBUG
-  MSFT:RELEASE_*_*_CC_FLAGS      = /D MDEPKG_NDEBUG
-
-
-################################################################################
-#
-# SKU Identification section - list of all SKU IDs supported by this Platform.
-#
-################################################################################
-[SkuIds]
-  0|DEFAULT
-
-################################################################################
-#
-# Library Class section - list of all Library Classes needed by this Platform.
-#
-################################################################################
-[LibraryClasses]
-  #
-  # Entry point
-  #
-  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
-  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
-  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
-  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
-  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
-
-  #
-  # Basic
-  #
-  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
-  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
-  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
-  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
-  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
-  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
-!if $(PCIE_BASE_SUPPORT) == FALSE
-  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
-  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
-!else
-  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
-  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
-!endif
-  PciSegmentLib|MdePkg/Library/PciSegmentLibSegmentInfo/BasePciSegmentLibSegmentInfo.inf
-  PciSegmentInfoLib|UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf
-  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
-  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
-  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
-
-  #
-  # UEFI & PI
-  #
-  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
-  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
-  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
-  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
-  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
-  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
-  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
-  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
-  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
-  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
-  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
-  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
-  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
-  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
-
-  #
-  # Generic Modules
-  #
-  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
-  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
-  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
-  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
-  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
-  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
-  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
-  FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
-
-  #
-  # CPU
-  #
-  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
-  LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
-
-  #
-  # Platform
-  #
-  TimerLib|UefiPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
-  ResetSystemLib|UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.inf
-  SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
-  PlatformHookLib|UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf
-  PlatformBootManagerLib|UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
-  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
-
-  #
-  # Misc
-  #
-  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
-  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
-!if $(SOURCE_DEBUG_ENABLE) == TRUE
-  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
-  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
-!else
-  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
-  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
-!endif
-  PlatformSupportLib|UefiPayloadPkg/Library/PlatformSupportLibNull/PlatformSupportLibNull.inf
-!if $(BOOTLOADER) == "COREBOOT"
-  BlParseLib|UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf
-!else
-  BlParseLib|UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf
-!endif
-
-  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
-  LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
-  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
-  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
-  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
-  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
-
-[LibraryClasses.IA32.SEC]
-  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
-  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
-  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
-  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
-  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
-  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
-
-[LibraryClasses.IA32.PEI_CORE, LibraryClasses.IA32.PEIM]
-  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
-  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
-  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
-  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
-  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
-!if $(SOURCE_DEBUG_ENABLE)
-  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
-!endif
-
-[LibraryClasses.common.DXE_CORE]
-  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
-  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
-  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
-  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
-  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
-!if $(SOURCE_DEBUG_ENABLE)
-  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
-!endif
-  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
-  VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
-
-[LibraryClasses.common.DXE_DRIVER]
-  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
-  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
-  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
-  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
-!if $(SOURCE_DEBUG_ENABLE)
-  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
-!endif
-  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
-  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
-  VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
-
-[LibraryClasses.common.DXE_RUNTIME_DRIVER]
-  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
-  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
-  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
-
-[LibraryClasses.common.UEFI_DRIVER,LibraryClasses.common.UEFI_APPLICATION]
-  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
-  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
-  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
-
-################################################################################
-#
-# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
-#
-################################################################################
-[PcdsFeatureFlag]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
-  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
-  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
-
-[PcdsFixedAtBuild]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x10000
-  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000
-  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x10000
-  #
-  # Make VariableRuntimeDxe work at emulated non-volatile variable mode.
-  #
-  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
-
-  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
-!if $(TARGET) == DEBUG
-  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
-!else
-  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
-!endif
-  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
-  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
-
-  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|$(PCIE_BASE)
-
-!if $(SOURCE_DEBUG_ENABLE)
-  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2
-!endif
-
-[PcdsPatchableInModule.common]
-  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x7
-  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
-!if $(SOURCE_DEBUG_ENABLE)
-  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
-!else
-  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
-!endif
-
-  #
-  # The following parameters are set by Library/PlatformHookLib
-  #
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|FALSE
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|$(BAUD_RATE)
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1
-
-  #
-  # Enable these parameters to be set on the command line
-  #
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|$(SERIAL_CLOCK_RATE)
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl|$(SERIAL_LINE_CONTROL)
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|$(SERIAL_HARDWARE_FLOW_CONTROL)
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable|$(SERIAL_DETECT_CABLE)
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl|$(SERIAL_FIFO_CONTROL)
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize|$(SERIAL_EXTENDED_TX_FIFO_SIZE)
-
-  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
-  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|$(UART_DEFAULT_BAUD_RATE)
-  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|$(UART_DEFAULT_DATA_BITS)
-  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|$(UART_DEFAULT_PARITY)
-  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|$(UART_DEFAULT_STOP_BITS)
-  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|$(DEFAULT_TERMINAL_TYPE)
-  gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters|$(PCI_SERIAL_PARAMETERS)
-
-  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|$(MAX_LOGICAL_PROCESSORS)
-
-
-################################################################################
-#
-# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
-#
-################################################################################
-
-[PcdsDynamicDefault]
-  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
-  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
-  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
-  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
-  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
-
-  ## This PCD defines the video horizontal resolution.
-  #  This PCD could be set to 0 then video resolution could be at highest resolution.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0
-  ## This PCD defines the video vertical resolution.
-  #  This PCD could be set to 0 then video resolution could be at highest resolution.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0
-
-  ## The PCD is used to specify the video horizontal resolution of text setup.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|0
-  ## The PCD is used to specify the video vertical resolution of text setup.
-  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|0
-
-  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31
-  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100
-  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0
-
-################################################################################
-#
-# Components Section - list of all EDK II Modules needed by this Platform.
-#
-################################################################################
-[Components.IA32]
-  #
-  # SEC Core
-  #
-  UefiPayloadPkg/SecCore/SecCore.inf
-
-  #
-  # PEI Core
-  #
-  MdeModulePkg/Core/Pei/PeiMain.inf
-
-  #
-  # PEIM
-  #
-  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
-    <LibraryClasses>
-      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
-  }
-  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
-  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
-
-  UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
-  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
-
-[Components.IA32]
-  #
-  # DXE Core
-  #
-  MdeModulePkg/Core/Dxe/DxeMain.inf {
-    <LibraryClasses>
-      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
-  }
-
-  #
-  # Components that produce the architectural protocols
-  #
-  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
-  UefiCpuPkg/CpuDxe/CpuDxe.inf
-  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
-  MdeModulePkg/Application/UiApp/UiApp.inf {
-    <LibraryClasses>
-      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
-      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
-      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
-  }
-
-  PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
-  MdeModulePkg/Universal/Metronome/Metronome.inf
-  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
-  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
-  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
-  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
-  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
-  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
-  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
-
-  #
-  # Following are the DXE drivers
-  #
-  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
-    <LibraryClasses>
-      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
-  }
-
-  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
-  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
-  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
-  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
-  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
-  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
-  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
-  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
-
-  UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf
-
-  #
-  # SMBIOS Support
-  #
-  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
-
-  #
-  # ACPI Support
-  #
-  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
-
-  #
-  # PCI Support
-  #
-  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
-  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
-    <LibraryClasses>
-      PciHostBridgeLib|UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
-  }
-
-  #
-  # SCSI/ATA/IDE/DISK Support
-  #
-  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
-  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
-  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
-  FatPkg/EnhancedFatDxe/Fat.inf
-  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
-  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
-  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
-  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
-  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
-
-  #
-  # SD/eMMC Support
-  #
-  MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
-  MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf
-  MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf
-
-  #
-  # Usb Support
-  #
-  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
-  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
-  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
-  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
-  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
-  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
-
-  #
-  # ISA Support
-  #
-  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
-!if $(PS2_KEYBOARD_ENABLE) == TRUE
-  OvmfPkg/SioBusDxe/SioBusDxe.inf
-  MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
-!endif
-
-  #
-  # Console Support
-  #
-  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
-  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
-  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
-!if $(DISABLE_SERIAL_TERMINAL) == FALSE
-  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
-!endif
-  UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf
-
-  #------------------------------
-  #  Build the shell
-  #------------------------------
-
-!if $(SHELL_TYPE) == BUILD_SHELL
-
-  #
-  # Shell Lib
-  #
-[LibraryClasses]
-  BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
-  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
-  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
-  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
-  !include NetworkPkg/NetworkLibs.dsc.inc
-
-[Components.IA32]
-  ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf {
-    <PcdsFixedAtBuild>
-      ## This flag is used to control initialization of the shell library
-      #  This should be FALSE for compiling the dynamic command.
-      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
-  }
-  ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf {
-    <PcdsFixedAtBuild>
-      ## This flag is used to control initialization of the shell library
-      #  This should be FALSE for compiling the dynamic command.
-      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
-  }
-  ShellPkg/Application/Shell/Shell.inf {
-    <PcdsFixedAtBuild>
-      ## This flag is used to control initialization of the shell library
-      #  This should be FALSE for compiling the shell application itself only.
-      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
-
-    #------------------------------
-    #  Basic commands
-    #------------------------------
-
-    <LibraryClasses>
-      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
-      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
-      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
-      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
-      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
-      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
-
-    #------------------------------
-    #  Networking commands
-    #------------------------------
-
-    <LibraryClasses>
-      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
-
-    #------------------------------
-    #  Support libraries
-    #------------------------------
-
-    <LibraryClasses>
-      DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
-      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
-      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
-      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-      ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
-      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
-      SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
-  }
-
-!endif
-- 
2.16.2.windows.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [edk2-devel] [PATCH] UefiPayloadPkg: Remove PEI phase from Payload
@ 2020-11-13 23:35 Ma, Maurice
  0 siblings, 0 replies; 2+ messages in thread
From: Ma, Maurice @ 2020-11-13 23:35 UTC (permalink / raw)
  To: Dong, Guo; +Cc: You, Benjamin, devel@edk2.groups.io

Hi, Guo,

Thank for making this changes to simplify the UEFI payload flow.

Below are some of my comments:

UefiPayloadPkg\Library\HobLib\Hob.c
- Please add function comment block for HobConstructor(), CreateHob() and BuildFvHobs().

UefiPayloadPkg\UefiPayloadPkg.fdf
- Please update copyright year to 2020

UefiPayloadPkg\UefiPayloadEntry\Ia32\DxeLoadFunc.c
- Line #304 and #305,  please fix line indentation.
- Line #360, please add code to halt the execution flow in release build since ASSERT() will be removed in release build.

UefiPayloadPkg\UefiPayloadEntry\LoadDxeCore.c
- Please add function comment block for AllocateCodePages() and LoadPeCoffImage().
- In function LoadPeCoffImage(), please enhance error handling. ASSERT() alone is not sufficient to handle error condition.

UefiPayloadEntry\UefiPayloadEntry.c
- Please add function comment block for MemInfoCallback().

Thanks
Maurice
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Guo Dong
> Sent: Tuesday, November 10, 2020 11:39 AM
> To: devel@edk2.groups.io
> Cc: Ma, Maurice <maurice.ma@intel.com>; You, Benjamin
> <benjamin.you@intel.com>
> Subject: [edk2-devel] [PATCH] UefiPayloadPkg: Remove PEI phase from Payload
> 
> It is not necessary to have a PEI phase in the UEFI payload since no
> specific PEI task is required. This patch adds a UefiPayloadEntry
> driver to get UEFI Payload required information from the bootloaders,
> convert them into a HOB list, load DXE core and transfer control to it.
> 
> Here is the change details:
> 1) Removed PEI phase, including Peicore, BlSupportPei, SecCore, etc.
> 2) Added UefiPayloadEntry driver. this is the only driver before DXE core.
> 3) Added Pure X64 support, dropped Pure IA32 (Could add later if required)
>    64bit payload with 32bit entry point is still supported.
> 4) Use one DSC file UefiPayloadPkg.dsc to support X64 and IA32X64 build.
>    Removed UefiPayloadIa32.dsc and UefiPayloadIa32X64.dsc
> 
> Tested with SBL and coreboot on QEMU.
> 
> Signed-off-by: Guo Dong <guo.dong@intel.com>
> ---
>  UefiPayloadPkg/BlSupportPei/BlSupportPei.h                                          |  39 --------
> -------------------------------
>  UefiPayloadPkg/BlSupportPei/BlSupportPei.inf                                        |  73 --------
> -----------------------------------------------------------------
>  UefiPayloadPkg/BuildAndIntegrationInstructions.txt                                  |  32
> +++++++++++++++-----------------
>  UefiPayloadPkg/Include/Library/BlParseLib.h                                         |   4 ++--
>  UefiPayloadPkg/Library/HobLib/Hob.c                                                 | 680
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++
>  UefiPayloadPkg/Library/HobLib/HobLib.inf                                            |  39
> +++++++++++++++++++++++++++++++++++++++
>  UefiPayloadPkg/SecCore/FindPeiCore.c                                                | 193 -----------
> ------------------------------------------------------------------------------------------------------
> --------------------------------------------------------------------------------
>  UefiPayloadPkg/SecCore/Ia32/SecEntry.nasm                                           |  78 -------
> -----------------------------------------------------------------------
>  UefiPayloadPkg/SecCore/Ia32/Stack.nasm                                              |  72 ---------
> ---------------------------------------------------------------
>  UefiPayloadPkg/SecCore/SecCore.inf                                                  |  58 --------------
> --------------------------------------------
>  UefiPayloadPkg/SecCore/SecMain.c                                                    | 288 -------------
> ------------------------------------------------------------------------------------------------------
> ------------------------------------------------------------------------------------------------------
> -----------------------------------------------------------------------
>  UefiPayloadPkg/SecCore/SecMain.h                                                    | 131 ------------
> ------------------------------------------------------------------------------------------------------
> -----------------
>  UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c                                  | 364
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  UefiPayloadPkg/UefiPayloadEntry/Ia32/IdtVectorAsm.nasm                              |
> 71
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++
>  UefiPayloadPkg/UefiPayloadEntry/Ia32/SecEntry.nasm                                  |  46
> ++++++++++++++++++++++++++++++++++++++++++++++
>  UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c                                       | 280
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++
>  UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c                                  | 201
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++
>  UefiPayloadPkg/{BlSupportPei/BlSupportPei.c =>
> UefiPayloadEntry/UefiPayloadEntry.c} | 446
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++-----------------------------------------------------------------
> ------------------------------------------------------------------------------------------------------
> ------------------------------------------------------------------------------------------------------
> ---------------------------------
>  UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h                                  |  85
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++
>  UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf                                |  91
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++
>  UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c                                   |  98
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++
>  UefiPayloadPkg/UefiPayloadEntry/X64/SecEntry.nasm                                   |  47
> +++++++++++++++++++++++++++++++++++++++++++++++
>  UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c                                 |
> 904
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h                                 |
> 322
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++
>  UefiPayloadPkg/UefiPayloadPkg.dec                                                   |   5 +++--
>  UefiPayloadPkg/{UefiPayloadPkgIa32X64.dsc => UefiPayloadPkg.dsc}
> |  57 +++++++++++++++------------------------------------------
>  UefiPayloadPkg/UefiPayloadPkg.fdf                                                   |  30 ++++++++-
> ---------------------
>  UefiPayloadPkg/UefiPayloadPkgIa32.dsc                                               | 585 ----------
> ------------------------------------------------------------------------------------------------------
> ------------------------------------------------------------------------------------------------------
> ------------------------------------------------------------------------------------------------------
> ------------------------------------------------------------------------------------------------------
> ------------------------------------------------------------------------------------------------------
> -----------------------------------------------------------------
>  28 files changed, 3415 insertions(+), 1904 deletions(-)
> 
> diff --git a/UefiPayloadPkg/BlSupportPei/BlSupportPei.h
> b/UefiPayloadPkg/BlSupportPei/BlSupportPei.h
> deleted file mode 100644
> index d11a3570a1..0000000000
> --- a/UefiPayloadPkg/BlSupportPei/BlSupportPei.h
> +++ /dev/null
> @@ -1,39 +0,0 @@
> -/** @file
> -  The header file of bootloader support PEIM.
> -
> -Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -
> -#ifndef __PEI_BOOTLOADER_SUPPORT_H__
> -#define __PEI_BOOTLOADER_SUPPORT_H__
> -
> -#include <PiPei.h>
> -#include <Library/PeimEntryPoint.h>
> -#include <Library/PeiServicesLib.h>
> -#include <Library/BaseLib.h>
> -#include <Library/DebugLib.h>
> -#include <Library/BaseMemoryLib.h>
> -#include <Library/HobLib.h>
> -#include <Library/PcdLib.h>
> -#include <Library/BlParseLib.h>
> -#include <Library/MtrrLib.h>
> -#include <Library/IoLib.h>
> -#include <Library/PlatformSupportLib.h>
> -#include <IndustryStandard/Acpi.h>
> -#include <Guid/MemoryTypeInformation.h>
> -#include <Guid/FirmwareFileSystem2.h>
> -#include <Guid/SystemTableInfoGuid.h>
> -#include <Guid/AcpiBoardInfoGuid.h>
> -#include <Guid/GraphicsInfoHob.h>
> -#include <Ppi/MasterBootMode.h>
> -#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
> -
> -typedef struct {
> -  UINT32  UsableLowMemTop;
> -  UINT32  SystemLowMemTop;
> -} PAYLOAD_MEM_INFO;
> -
> -#endif
> diff --git a/UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
> b/UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
> deleted file mode 100644
> index 711fe63fe6..0000000000
> --- a/UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
> +++ /dev/null
> @@ -1,73 +0,0 @@
> -## @file
> -# Bootloader Support PEI Module
> -#
> -# Parses bootloader information and report resource information into pei core.
> It will install
> -# the memory as required.
> -#
> -#  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
> -#
> -#  SPDX-License-Identifier: BSD-2-Clause-Patent
> -#
> -##
> -
> -[Defines]
> -  INF_VERSION                    = 0x00010005
> -  BASE_NAME                      = BlSupportPeim
> -  FILE_GUID                      = 352C6AF8-315B-4bd6-B04F-31D4ED1EBE57
> -  MODULE_TYPE                    = PEIM
> -  VERSION_STRING                 = 1.0
> -  ENTRY_POINT                    = BlPeiEntryPoint
> -
> -#
> -# The following information is for reference only and not required by the build
> tools.
> -#
> -#  VALID_ARCHITECTURES           = IA32 X64
> -#
> -
> -[Sources]
> -  BlSupportPei.c
> -  BlSupportPei.h
> -
> -[Packages]
> -  MdePkg/MdePkg.dec
> -  MdeModulePkg/MdeModulePkg.dec
> -  IntelFsp2Pkg/IntelFsp2Pkg.dec
> -  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
> -  UefiPayloadPkg/UefiPayloadPkg.dec
> -  UefiCpuPkg/UefiCpuPkg.dec
> -
> -[LibraryClasses]
> -  PeimEntryPoint
> -  PeiServicesLib
> -  BaseLib
> -  BaseMemoryLib
> -  DebugLib
> -  HobLib
> -  PcdLib
> -  BlParseLib
> -  MtrrLib
> -  IoLib
> -  PlatformSupportLib
> -
> -[Guids]
> -  gEfiMemoryTypeInformationGuid
> -  gEfiFirmwareFileSystem2Guid
> -  gUefiSystemTableInfoGuid
> -  gEfiGraphicsInfoHobGuid
> -  gEfiGraphicsDeviceInfoHobGuid
> -  gUefiAcpiBoardInfoGuid
> -
> -[Ppis]
> -  gEfiPeiMasterBootModePpiGuid
> -
> -[Pcd]
> -  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
> -  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
> -  gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
> -  gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
> -  gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
> -  gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
> -  gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
> -
> -[Depex]
> -  TRUE
> diff --git a/UefiPayloadPkg/BuildAndIntegrationInstructions.txt
> b/UefiPayloadPkg/BuildAndIntegrationInstructions.txt
> index 2cacd48904..7512486590 100644
> --- a/UefiPayloadPkg/BuildAndIntegrationInstructions.txt
> +++ b/UefiPayloadPkg/BuildAndIntegrationInstructions.txt
> @@ -1,6 +1,6 @@
> 
> =============================================================
> ===================
>  Build And Integration Instructions
> -2019 March 27th
> +2020 Aug 1st
> 
> =============================================================
> ===================
> 
> 
> =============================================================
> ===================
> @@ -35,27 +35,25 @@ integrate it into coreboot or Slim Bootloader firmware.
>  B. HOW TO BUILD
> 
> =============================================================
> ===================
>  1. Run the below two commands in windows command prompt window:
> -   edksetup.bat
> +   > edksetup.bat
> 
> -   For debug ia32 build:
> -   build -a IA32 -p UefiPayloadPkg\UefiPayloadPkgIa32.dsc -b DEBUG -t
> <ToolChain> -D BOOTLOADER=<Bootloader>
> +   For pure X64 build:
> +   > build -a x64 -p UefiPayloadPkg\UefiPayloadPkg.dsc -b <BuildType> -t
> <ToolChain>
> +     -D BOOTLOADER=<Bootloader>
> 
> -   For release ia32 build:
> -   build -a IA32 -p UefiPayloadPkg\UefiPayloadPkgIa32.dsc -b RELEASE -t
> <ToolChain> -D BOOTLOADER=<Bootloader>
> +   For X64 build with IA32 entry point:
> +   > build -a IA32 -a X64 -p UefiPayloadPkg\UefiPayloadPkg.dsc -b <BuildType>
> -t <ToolChain>
> +     -D BOOTLOADER=<Bootloader>
> 
> -   For debug X64 build:
> -   build -a IA32 -a X64 -p UefiPayloadPkg\UefiPayloadPkgIa32X64.dsc -b DEBUG
> -t <ToolChain> -D BOOTLOADER=<Bootloader>
> -
> -   For release X64 build:
> -   build -a IA32 -a X64 -p UefiPayloadPkg\UefiPayloadPkgIa32X64.dsc -b
> RELEASE -t <ToolChain> -D BOOTLOADER=<Bootloader>
> -
> -   <ToolChain> is the EDK II build environment on your host. Currently it was
> tested
> -   with VS2015x86 toolchain.
> +   <BuildType> support 'DEBUG', 'RELEASE' and 'NOOPT'.
> +   <ToolChain> is the EDK II build environment on your host. Tested with
> VS2015x86 toolchain.
>     <Bootloader> could be "SBL" for Slim Bootloader and "COREBOOT" for
> coreboot.
> 
>     Refer to https://github.com/tianocore/tianocore.github.io/wiki/UDK2018-
> How-to-Build for
>     details about EDK II build steps.
> 
> +   NOTE: Pure 32bit UEFI payload support could be added if required later.
> +
>  2. If build is successfully, the payload image (UEFIPAYLOAD.fd) will be
> generated inside the
>     folder of Build\UefiPayloadPkg.
> 
> @@ -65,9 +63,9 @@ C. HOW TO INTEGRATE INTO COREBOOT
>  1. Copy the payload image (UEFIPAYLOAD.fd) into the top-level directory of
> Coreboot source tree.
>  2. Run "make menuconfig" in linux console to start Coreboot configuration
> surface.
>  3. In the Payload section,
> -   1) Choose "An ELF executable payload" for the option of "Add a payload".
> -   2) Type the path of payload image for the option of "Payload path and
> filename".
> -   3) Select the option of "Use LZMA compression for payloads".
> +   1) Choose "Tianocore Payload" for the option of "Add a payload".
> +   2) Update the path of payload image for the option of "Tianocore binary".
> +   3) Choose "UEFIPayload" for the option of "Tianocore Payload".
>  4. If the graphics console is required in UEFI payload, enable framebuffer
> initialization in coreboot.
>     This could be done by enabling native graphics or using VGA BIOS option rom.
>  5. Build the coreboot firmware image.
> diff --git a/UefiPayloadPkg/Include/Library/BlParseLib.h
> b/UefiPayloadPkg/Include/Library/BlParseLib.h
> index 3f9e591ede..20a526d15c 100644
> --- a/UefiPayloadPkg/Include/Library/BlParseLib.h
> +++ b/UefiPayloadPkg/Include/Library/BlParseLib.h
> @@ -2,7 +2,7 @@
>    This library will parse the coreboot table in memory and extract those required
>    information.
> 
> -  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  **/
> @@ -16,7 +16,7 @@
>  #ifndef __BOOTLOADER_PARSE_LIB__
>  #define __BOOTLOADER_PARSE_LIB__
> 
> -#define GET_BOOTLOADER_PARAMETER()      (*(UINT32
> *)(UINTN)(PcdGet32(PcdPayloadStackTop) - sizeof(UINT32)))
> +#define GET_BOOTLOADER_PARAMETER()      (*(UINTN
> *)(UINTN)(PcdGet32(PcdPayloadStackTop) - sizeof(UINT64)))
>  #define SET_BOOTLOADER_PARAMETER(Value)
> GET_BOOTLOADER_PARAMETER()=Value
> 
>  typedef RETURN_STATUS \
> diff --git a/UefiPayloadPkg/Library/HobLib/Hob.c
> b/UefiPayloadPkg/Library/HobLib/Hob.c
> new file mode 100644
> index 0000000000..308fca5c23
> --- /dev/null
> +++ b/UefiPayloadPkg/Library/HobLib/Hob.c
> @@ -0,0 +1,680 @@
> +/** @file
> +
> +  Copyright (c) 2010, Apple Inc. All rights reserved.<BR>
> +  Copyright (c) 2017 - 2020, 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/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +
> +VOID      *mHobList;
> +
> +/**
> +  Returns the pointer to the HOB list.
> +
> +  This function returns the pointer to first HOB in the list.
> +
> +  @return The pointer to the HOB list.
> +
> +**/
> +VOID *
> +EFIAPI
> +GetHobList (
> +  VOID
> +  )
> +{
> +  ASSERT (mHobList != NULL);
> +  return mHobList;
> +}
> +
> +EFI_HOB_HANDOFF_INFO_TABLE*
> +EFIAPI
> +HobConstructor (
> +  IN VOID   *EfiMemoryBegin,
> +  IN UINTN  EfiMemoryLength,
> +  IN VOID   *EfiFreeMemoryBottom,
> +  IN VOID   *EfiFreeMemoryTop
> +  )
> +{
> +  EFI_HOB_HANDOFF_INFO_TABLE  *Hob;
> +  EFI_HOB_GENERIC_HEADER      *HobEnd;
> +
> +  Hob    = EfiFreeMemoryBottom;
> +  HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
> +
> +  Hob->Header.HobType      = EFI_HOB_TYPE_HANDOFF;
> +  Hob->Header.HobLength    = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
> +  Hob->Header.Reserved     = 0;
> +
> +  HobEnd->HobType          = EFI_HOB_TYPE_END_OF_HOB_LIST;
> +  HobEnd->HobLength        = sizeof(EFI_HOB_GENERIC_HEADER);
> +  HobEnd->Reserved         = 0;
> +
> +  Hob->Version             = EFI_HOB_HANDOFF_TABLE_VERSION;
> +  Hob->BootMode            = BOOT_WITH_FULL_CONFIGURATION;
> +
> +  Hob->EfiMemoryTop        = (UINTN)EfiMemoryBegin + EfiMemoryLength;
> +  Hob->EfiMemoryBottom     = (UINTN)EfiMemoryBegin;
> +  Hob->EfiFreeMemoryTop    = (UINTN)EfiFreeMemoryTop;
> +  Hob->EfiFreeMemoryBottom =
> (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
> +  Hob->EfiEndOfHobList     = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
> +
> +  mHobList = Hob;
> +  return Hob;
> +}
> +
> +VOID *
> +EFIAPI
> +CreateHob (
> +  IN  UINT16    HobType,
> +  IN  UINT16    HobLength
> +  )
> +{
> +  EFI_HOB_HANDOFF_INFO_TABLE  *HandOffHob;
> +  EFI_HOB_GENERIC_HEADER      *HobEnd;
> +  EFI_PHYSICAL_ADDRESS        FreeMemory;
> +  VOID                        *Hob;
> +
> +  HandOffHob = GetHobList ();
> +
> +  HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
> +
> +  FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob-
> >EfiFreeMemoryBottom;
> +
> +  if (FreeMemory < HobLength) {
> +      return NULL;
> +  }
> +
> +  Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
> +  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
> +  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
> +  ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
> +
> +  HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
> +  HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
> +
> +  HobEnd->HobType   = EFI_HOB_TYPE_END_OF_HOB_LIST;
> +  HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
> +  HobEnd->Reserved  = 0;
> +  HobEnd++;
> +  HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN)
> HobEnd;
> +
> +  return Hob;
> +}
> +
> +/**
> +  Builds a HOB that describes a chunk of system memory.
> +
> +  This function builds a HOB that describes a chunk of system memory.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  ResourceType        The type of resource described by this HOB.
> +  @param  ResourceAttribute   The resource attributes of the memory
> described by this HOB.
> +  @param  PhysicalStart       The 64 bit physical address of memory described
> by this HOB.
> +  @param  NumberOfBytes       The length of the memory described by this
> HOB in bytes.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildResourceDescriptorHob (
> +  IN EFI_RESOURCE_TYPE            ResourceType,
> +  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
> +  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
> +  IN UINT64                       NumberOfBytes
> +  )
> +{
> +  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof
> (EFI_HOB_RESOURCE_DESCRIPTOR));
> +  ASSERT(Hob != NULL);
> +
> +  Hob->ResourceType      = ResourceType;
> +  Hob->ResourceAttribute = ResourceAttribute;
> +  Hob->PhysicalStart     = PhysicalStart;
> +  Hob->ResourceLength    = NumberOfBytes;
> +}
> +
> +VOID
> +EFIAPI
> +BuildFvHobs (
> +  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
> +  IN UINT64                       NumberOfBytes,
> +  IN EFI_RESOURCE_ATTRIBUTE_TYPE  *ResourceAttribute
> +  )
> +{
> +
> +  EFI_RESOURCE_ATTRIBUTE_TYPE Resource;
> +
> +  BuildFvHob (PhysicalStart, NumberOfBytes);
> +
> +  if (ResourceAttribute == NULL) {
> +    Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
> +                EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +                EFI_RESOURCE_ATTRIBUTE_TESTED |
> +                EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);
> +  } else {
> +    Resource = *ResourceAttribute;
> +  }
> +
> +  BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource,
> PhysicalStart, NumberOfBytes);
> +}
> +
> +/**
> +  Returns the next instance of a HOB type from the starting HOB.
> +
> +  This function searches the first instance of a HOB type from the starting HOB
> pointer.
> +  If there does not exist such HOB type from the starting HOB pointer, it will
> return NULL.
> +  In contrast with macro GET_NEXT_HOB(), this function does not skip the
> starting HOB pointer
> +  unconditionally: it returns HobStart back if HobStart itself meets the
> requirement;
> +  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
> +  If HobStart is NULL, then ASSERT().
> +
> +  @param  Type          The HOB type to return.
> +  @param  HobStart      The starting HOB pointer to search from.
> +
> +  @return The next instance of a HOB type from the starting HOB.
> +
> +**/
> +VOID *
> +EFIAPI
> +GetNextHob (
> +  IN UINT16                 Type,
> +  IN CONST VOID             *HobStart
> +  )
> +{
> +  EFI_PEI_HOB_POINTERS  Hob;
> +
> +  ASSERT (HobStart != NULL);
> +
> +  Hob.Raw = (UINT8 *) HobStart;
> +  //
> +  // Parse the HOB list until end of list or matching type is found.
> +  //
> +  while (!END_OF_HOB_LIST (Hob)) {
> +    if (Hob.Header->HobType == Type) {
> +      return Hob.Raw;
> +    }
> +    Hob.Raw = GET_NEXT_HOB (Hob);
> +  }
> +  return NULL;
> +}
> +
> +
> +
> +/**
> +  Returns the first instance of a HOB type among the whole HOB list.
> +
> +  This function searches the first instance of a HOB type among the whole HOB
> list.
> +  If there does not exist such HOB type in the HOB list, it will return NULL.
> +
> +  @param  Type          The HOB type to return.
> +
> +  @return The next instance of a HOB type from the starting HOB.
> +
> +**/
> +VOID *
> +EFIAPI
> +GetFirstHob (
> +  IN UINT16                 Type
> +  )
> +{
> +  VOID      *HobList;
> +
> +  HobList = GetHobList ();
> +  return GetNextHob (Type, HobList);
> +}
> +
> +
> +/**
> +  This function searches the first instance of a HOB from the starting HOB
> pointer.
> +  Such HOB should satisfy two conditions:
> +  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals
> to the input Guid.
> +  If there does not exist such HOB from the starting HOB pointer, it will return
> NULL.
> +  Caller is required to apply GET_GUID_HOB_DATA () and
> GET_GUID_HOB_DATA_SIZE ()
> +  to extract the data section and its size info respectively.
> +  In contrast with macro GET_NEXT_HOB(), this function does not skip the
> starting HOB pointer
> +  unconditionally: it returns HobStart back if HobStart itself meets the
> requirement;
> +  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
> +  If Guid is NULL, then ASSERT().
> +  If HobStart is NULL, then ASSERT().
> +
> +  @param  Guid          The GUID to match with in the HOB list.
> +  @param  HobStart      A pointer to a Guid.
> +
> +  @return The next instance of the matched GUID HOB from the starting HOB.
> +
> +**/
> +VOID *
> +EFIAPI
> +GetNextGuidHob (
> +  IN CONST EFI_GUID         *Guid,
> +  IN CONST VOID             *HobStart
> +  ){
> +  EFI_PEI_HOB_POINTERS  GuidHob;
> +
> +  GuidHob.Raw = (UINT8 *) HobStart;
> +  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION,
> GuidHob.Raw)) != NULL) {
> +    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
> +      break;
> +    }
> +    GuidHob.Raw = GET_NEXT_HOB (GuidHob);
> +  }
> +  return GuidHob.Raw;
> +}
> +
> +
> +/**
> +  This function searches the first instance of a HOB among the whole HOB list.
> +  Such HOB should satisfy two conditions:
> +  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals
> to the input Guid.
> +  If there does not exist such HOB from the starting HOB pointer, it will return
> NULL.
> +  Caller is required to apply GET_GUID_HOB_DATA () and
> GET_GUID_HOB_DATA_SIZE ()
> +  to extract the data section and its size info respectively.
> +  If Guid is NULL, then ASSERT().
> +
> +  @param  Guid          The GUID to match with in the HOB list.
> +
> +  @return The first instance of the matched GUID HOB among the whole HOB
> list.
> +
> +**/
> +VOID *
> +EFIAPI
> +GetFirstGuidHob (
> +  IN CONST EFI_GUID         *Guid
> +  )
> +{
> +  VOID      *HobList;
> +
> +  HobList = GetHobList ();
> +  return GetNextGuidHob (Guid, HobList);
> +}
> +
> +
> +
> +
> +/**
> +  Builds a HOB for a loaded PE32 module.
> +
> +  This function builds a HOB for a loaded PE32 module.
> +  It can only be invoked during PEI phase;
> +  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
> +  If ModuleName is NULL, then ASSERT().
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  ModuleName              The GUID File Name of the module.
> +  @param  MemoryAllocationModule  The 64 bit physical address of the
> module.
> +  @param  ModuleLength            The length of the module in bytes.
> +  @param  EntryPoint              The 64 bit physical address of the module entry
> point.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildModuleHob (
> +  IN CONST EFI_GUID         *ModuleName,
> +  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,
> +  IN UINT64                 ModuleLength,
> +  IN EFI_PHYSICAL_ADDRESS   EntryPoint
> +  )
> +{
> +  EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;
> +
> +  ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
> +          ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof
> (EFI_HOB_MEMORY_ALLOCATION_MODULE));
> +
> +  CopyGuid (&(Hob->MemoryAllocationHeader.Name),
> &gEfiHobMemoryAllocModuleGuid);
> +  Hob->MemoryAllocationHeader.MemoryBaseAddress =
> MemoryAllocationModule;
> +  Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;
> +  Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;
> +
> +  //
> +  // Zero the reserved space to match HOB spec
> +  //
> +  ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob-
> >MemoryAllocationHeader.Reserved));
> +
> +  CopyGuid (&Hob->ModuleName, ModuleName);
> +  Hob->EntryPoint = EntryPoint;
> +}
> +
> +/**
> +  Builds a GUID HOB with a certain data length.
> +
> +  This function builds a customized HOB tagged with a GUID for identification
> +  and returns the start address of GUID HOB data so that caller can fill the
> customized data.
> +  The HOB Header and Name field is already stripped.
> +  It can only be invoked during PEI phase;
> +  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
> +  If Guid is NULL, then ASSERT().
> +  If there is no additional space for HOB creation, then ASSERT().
> +  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
> +
> +  @param  Guid          The GUID to tag the customized HOB.
> +  @param  DataLength    The size of the data payload for the GUID HOB.
> +
> +  @return The start address of GUID HOB data.
> +
> +**/
> +VOID *
> +EFIAPI
> +BuildGuidHob (
> +  IN CONST EFI_GUID              *Guid,
> +  IN UINTN                       DataLength
> +  )
> +{
> +  EFI_HOB_GUID_TYPE *Hob;
> +
> +  //
> +  // Make sure that data length is not too long.
> +  //
> +  ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof
> (EFI_HOB_GUID_TYPE) + DataLength));
> +  CopyGuid (&Hob->Name, Guid);
> +  return Hob + 1;
> +}
> +
> +
> +/**
> +  Copies a data buffer to a newly-built HOB.
> +
> +  This function builds a customized HOB tagged with a GUID for identification,
> +  copies the input data to the HOB data field and returns the start address of
> the GUID HOB data.
> +  The HOB Header and Name field is already stripped.
> +  It can only be invoked during PEI phase;
> +  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
> +  If Guid is NULL, then ASSERT().
> +  If Data is NULL and DataLength > 0, then ASSERT().
> +  If there is no additional space for HOB creation, then ASSERT().
> +  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
> +
> +  @param  Guid          The GUID to tag the customized HOB.
> +  @param  Data          The data to be copied into the data field of the GUID HOB.
> +  @param  DataLength    The size of the data payload for the GUID HOB.
> +
> +  @return The start address of GUID HOB data.
> +
> +**/
> +VOID *
> +EFIAPI
> +BuildGuidDataHob (
> +  IN CONST EFI_GUID              *Guid,
> +  IN VOID                        *Data,
> +  IN UINTN                       DataLength
> +  )
> +{
> +  VOID  *HobData;
> +
> +  ASSERT (Data != NULL || DataLength == 0);
> +
> +  HobData = BuildGuidHob (Guid, DataLength);
> +
> +  return CopyMem (HobData, Data, DataLength);
> +}
> +
> +
> +/**
> +  Builds a Firmware Volume HOB.
> +
> +  This function builds a Firmware Volume HOB.
> +  It can only be invoked during PEI phase;
> +  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  BaseAddress   The base address of the Firmware Volume.
> +  @param  Length        The size of the Firmware Volume in bytes.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildFvHob (
> +  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN UINT64                      Length
> +  )
> +{
> +  EFI_HOB_FIRMWARE_VOLUME  *Hob;
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof
> (EFI_HOB_FIRMWARE_VOLUME));
> +
> +  Hob->BaseAddress = BaseAddress;
> +  Hob->Length      = Length;
> +}
> +
> +
> +/**
> +  Builds a EFI_HOB_TYPE_FV2 HOB.
> +
> +  This function builds a EFI_HOB_TYPE_FV2 HOB.
> +  It can only be invoked during PEI phase;
> +  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  BaseAddress   The base address of the Firmware Volume.
> +  @param  Length        The size of the Firmware Volume in bytes.
> +  @param  FvName       The name of the Firmware Volume.
> +  @param  FileName      The name of the file.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildFv2Hob (
> +  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN          UINT64                      Length,
> +  IN CONST    EFI_GUID                    *FvName,
> +  IN CONST    EFI_GUID                    *FileName
> +  )
> +{
> +  EFI_HOB_FIRMWARE_VOLUME2  *Hob;
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof
> (EFI_HOB_FIRMWARE_VOLUME2));
> +
> +  Hob->BaseAddress = BaseAddress;
> +  Hob->Length      = Length;
> +  CopyGuid (&Hob->FvName, FvName);
> +  CopyGuid (&Hob->FileName, FileName);
> +}
> +
> +/**
> +  Builds a EFI_HOB_TYPE_FV3 HOB.
> +
> +  This function builds a EFI_HOB_TYPE_FV3 HOB.
> +  It can only be invoked during PEI phase;
> +  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
> +
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param BaseAddress            The base address of the Firmware Volume.
> +  @param Length                 The size of the Firmware Volume in bytes.
> +  @param AuthenticationStatus   The authentication status.
> +  @param ExtractedFv            TRUE if the FV was extracted as a file within
> +                                another firmware volume. FALSE otherwise.
> +  @param FvName                 The name of the Firmware Volume.
> +                                Valid only if IsExtractedFv is TRUE.
> +  @param FileName               The name of the file.
> +                                Valid only if IsExtractedFv is TRUE.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildFv3Hob (
> +  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN          UINT64                      Length,
> +  IN          UINT32                      AuthenticationStatus,
> +  IN          BOOLEAN                     ExtractedFv,
> +  IN CONST    EFI_GUID                    *FvName, OPTIONAL
> +  IN CONST    EFI_GUID                    *FileName OPTIONAL
> +  )
> +{
> +  EFI_HOB_FIRMWARE_VOLUME3  *Hob;
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_FV3, sizeof
> (EFI_HOB_FIRMWARE_VOLUME3));
> +
> +  Hob->BaseAddress          = BaseAddress;
> +  Hob->Length               = Length;
> +  Hob->AuthenticationStatus = AuthenticationStatus;
> +  Hob->ExtractedFv          = ExtractedFv;
> +  if (ExtractedFv) {
> +    CopyGuid (&Hob->FvName, FvName);
> +    CopyGuid (&Hob->FileName, FileName);
> +  }
> +}
> +
> +
> +/**
> +  Builds a HOB for the CPU.
> +
> +  This function builds a HOB for the CPU.
> +  It can only be invoked during PEI phase;
> +  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  SizeOfMemorySpace   The maximum physical memory
> addressability of the processor.
> +  @param  SizeOfIoSpace       The maximum physical I/O addressability of the
> processor.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildCpuHob (
> +  IN UINT8                       SizeOfMemorySpace,
> +  IN UINT8                       SizeOfIoSpace
> +  )
> +{
> +  EFI_HOB_CPU  *Hob;
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
> +
> +  Hob->SizeOfMemorySpace = SizeOfMemorySpace;
> +  Hob->SizeOfIoSpace     = SizeOfIoSpace;
> +
> +  //
> +  // Zero the reserved space to match HOB spec
> +  //
> +  ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
> +}
> +
> +
> +/**
> +  Builds a HOB for the Stack.
> +
> +  This function builds a HOB for the stack.
> +  It can only be invoked during PEI phase;
> +  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  BaseAddress   The 64 bit physical address of the Stack.
> +  @param  Length        The length of the stack in bytes.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildStackHob (
> +  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN UINT64                      Length
> +  )
> +{
> +  EFI_HOB_MEMORY_ALLOCATION_STACK  *Hob;
> +
> +  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
> +          ((Length & (EFI_PAGE_SIZE - 1)) == 0));
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof
> (EFI_HOB_MEMORY_ALLOCATION_STACK));
> +
> +  CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
> +  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
> +  Hob->AllocDescriptor.MemoryLength      = Length;
> +  Hob->AllocDescriptor.MemoryType        = EfiBootServicesData;
> +
> +  //
> +  // Zero the reserved space to match HOB spec
> +  //
> +  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob-
> >AllocDescriptor.Reserved));
> +}
> +
> +
> +/**
> +  Update the Stack Hob if the stack has been moved
> +
> +  @param  BaseAddress   The 64 bit physical address of the Stack.
> +  @param  Length        The length of the stack in bytes.
> +
> +**/
> +VOID
> +EFIAPI
> +UpdateStackHob (
> +  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN UINT64                      Length
> +  )
> +{
> +  EFI_PEI_HOB_POINTERS           Hob;
> +
> +  Hob.Raw = GetHobList ();
> +  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION,
> Hob.Raw)) != NULL) {
> +    if (CompareGuid (&gEfiHobMemoryAllocStackGuid,
> &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
> +      //
> +      // Build a new memory allocation HOB with old stack info with
> EfiConventionalMemory type
> +      // to be reclaimed by DXE core.
> +      //
> +      BuildMemoryAllocationHob (
> +        Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
> +        Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
> +        EfiConventionalMemory
> +        );
> +      //
> +      // Update the BSP Stack Hob to reflect the new stack info.
> +      //
> +      Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress =
> BaseAddress;
> +      Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
> +      break;
> +    }
> +    Hob.Raw = GET_NEXT_HOB (Hob);
> +  }
> +}
> +
> +
> +
> +/**
> +  Builds a HOB for the memory allocation.
> +
> +  This function builds a HOB for the memory allocation.
> +  It can only be invoked during PEI phase;
> +  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
> +  If there is no additional space for HOB creation, then ASSERT().
> +
> +  @param  BaseAddress   The 64 bit physical address of the memory.
> +  @param  Length        The length of the memory allocation in bytes.
> +  @param  MemoryType    Type of memory allocated by this HOB.
> +
> +**/
> +VOID
> +EFIAPI
> +BuildMemoryAllocationHob (
> +  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN UINT64                      Length,
> +  IN EFI_MEMORY_TYPE             MemoryType
> +  )
> +{
> +  EFI_HOB_MEMORY_ALLOCATION  *Hob;
> +
> +  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
> +          ((Length & (EFI_PAGE_SIZE - 1)) == 0));
> +
> +  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof
> (EFI_HOB_MEMORY_ALLOCATION));
> +
> +  ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
> +  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
> +  Hob->AllocDescriptor.MemoryLength      = Length;
> +  Hob->AllocDescriptor.MemoryType        = MemoryType;
> +  //
> +  // Zero the reserved space to match HOB spec
> +  //
> +  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob-
> >AllocDescriptor.Reserved));
> +}
> +
> diff --git a/UefiPayloadPkg/Library/HobLib/HobLib.inf
> b/UefiPayloadPkg/Library/HobLib/HobLib.inf
> new file mode 100644
> index 0000000000..030e22a810
> --- /dev/null
> +++ b/UefiPayloadPkg/Library/HobLib/HobLib.inf
> @@ -0,0 +1,39 @@
> +#/** @file
> +#
> +#  Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = HobLib
> +  FILE_GUID                      = AD6B4D55-8DBE-48C8-88E3-CFDBB6E9D193
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = HobLib
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources.common]
> +  Hob.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiPayloadPkg/UefiPayloadPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +
> +[Guids]
> +  gEfiHobMemoryAllocModuleGuid
> +  gEfiHobMemoryAllocStackGuid
> +
> diff --git a/UefiPayloadPkg/SecCore/FindPeiCore.c
> b/UefiPayloadPkg/SecCore/FindPeiCore.c
> deleted file mode 100644
> index f67d1afb96..0000000000
> --- a/UefiPayloadPkg/SecCore/FindPeiCore.c
> +++ /dev/null
> @@ -1,193 +0,0 @@
> -/** @file
> -  Locate the entry point for the PEI Core
> -
> -Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#include <PiPei.h>
> -#include <Library/BaseLib.h>
> -#include <Library/PeCoffGetEntryPointLib.h>
> -
> -#include "SecMain.h"
> -
> -/**
> -  Find core image base.
> -
> -  @param   BootFirmwareVolumePtr    Point to the boot firmware volume.
> -  @param   SecCoreImageBase         The base address of the SEC core image.
> -  @param   PeiCoreImageBase         The base address of the PEI core image.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -FindImageBase (
> -  IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
> -  OUT EFI_PHYSICAL_ADDRESS             *SecCoreImageBase,
> -  OUT EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
> -  )
> -{
> -  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> -  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
> -  EFI_FFS_FILE_HEADER         *File;
> -  UINT32                      Size;
> -  EFI_PHYSICAL_ADDRESS        EndOfFile;
> -  EFI_COMMON_SECTION_HEADER   *Section;
> -  EFI_PHYSICAL_ADDRESS        EndOfSection;
> -
> -  *SecCoreImageBase = 0;
> -  *PeiCoreImageBase = 0;
> -
> -  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
> -  EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr-
> >FvLength;
> -
> -  //
> -  // Loop through the FFS files in the Boot Firmware Volume
> -  //
> -  for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; )
> {
> -
> -    CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
> -    if (CurrentAddress > EndOfFirmwareVolume) {
> -      return EFI_NOT_FOUND;
> -    }
> -
> -    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> -    if (IS_FFS_FILE2 (File)) {
> -      Size = FFS_FILE2_SIZE (File);
> -      if (Size <= 0x00FFFFFF) {
> -        return EFI_NOT_FOUND;
> -      }
> -    } else {
> -      Size = FFS_FILE_SIZE (File);
> -      if (Size < sizeof (EFI_FFS_FILE_HEADER)) {
> -        return EFI_NOT_FOUND;
> -      }
> -    }
> -
> -    EndOfFile = CurrentAddress + Size;
> -    if (EndOfFile > EndOfFirmwareVolume) {
> -      return EFI_NOT_FOUND;
> -    }
> -
> -    //
> -    // Look for SEC Core / PEI Core files
> -    //
> -    if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
> -        File->Type != EFI_FV_FILETYPE_PEI_CORE) {
> -      continue;
> -    }
> -
> -    //
> -    // Loop through the FFS file sections within the FFS file
> -    //
> -    if (IS_FFS_FILE2 (File)) {
> -      EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof
> (EFI_FFS_FILE_HEADER2));
> -    } else {
> -      EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof
> (EFI_FFS_FILE_HEADER));
> -    }
> -    for (;;) {
> -      CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
> -      Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> -
> -      if (IS_SECTION2 (Section)) {
> -        Size = SECTION2_SIZE (Section);
> -        if (Size <= 0x00FFFFFF) {
> -          return EFI_NOT_FOUND;
> -        }
> -      } else {
> -        Size = SECTION_SIZE (Section);
> -        if (Size < sizeof (EFI_COMMON_SECTION_HEADER)) {
> -          return EFI_NOT_FOUND;
> -        }
> -      }
> -
> -      EndOfSection = CurrentAddress + Size;
> -      if (EndOfSection > EndOfFile) {
> -        return EFI_NOT_FOUND;
> -      }
> -
> -      //
> -      // Look for executable sections
> -      //
> -      if (Section->Type == EFI_SECTION_PE32 || Section->Type ==
> EFI_SECTION_TE) {
> -        if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
> -          if (IS_SECTION2 (Section)) {
> -            *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section
> + sizeof (EFI_COMMON_SECTION_HEADER2));
> -          } else {
> -            *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section
> + sizeof (EFI_COMMON_SECTION_HEADER));
> -          }
> -        } else {
> -          if (IS_SECTION2 (Section)) {
> -            *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section
> + sizeof (EFI_COMMON_SECTION_HEADER2));
> -          } else {
> -            *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section
> + sizeof (EFI_COMMON_SECTION_HEADER));
> -          }
> -        }
> -        break;
> -      }
> -    }
> -
> -    //
> -    // Both SEC Core and PEI Core images found
> -    //
> -    if (*SecCoreImageBase != 0 && *PeiCoreImageBase != 0) {
> -      return EFI_SUCCESS;
> -    }
> -  }
> -}
> -
> -/**
> -  Find and return Pei Core entry point.
> -
> -  It also find SEC and PEI Core file debug information. It will report them if
> -  remote debug is enabled.
> -
> -  @param   BootFirmwareVolumePtr    Point to the boot firmware volume.
> -  @param   PeiCoreEntryPoint        The entry point of the PEI core.
> -
> -**/
> -VOID
> -EFIAPI
> -FindAndReportEntryPoints (
> -  IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
> -  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
> -  )
> -{
> -  EFI_STATUS                       Status;
> -  EFI_PHYSICAL_ADDRESS             SecCoreImageBase;
> -  EFI_PHYSICAL_ADDRESS             PeiCoreImageBase;
> -  PE_COFF_LOADER_IMAGE_CONTEXT     ImageContext;
> -
> -  //
> -  // Find SEC Core and PEI Core image base
> -  //
> -  Status = FindImageBase (BootFirmwareVolumePtr, &SecCoreImageBase,
> &PeiCoreImageBase);
> -  ASSERT_EFI_ERROR (Status);
> -
> -  ZeroMem ((VOID *) &ImageContext, sizeof
> (PE_COFF_LOADER_IMAGE_CONTEXT));
> -  //
> -  // Report SEC Core debug information when remote debug is enabled
> -  //
> -  ImageContext.ImageAddress = SecCoreImageBase;
> -  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN)
> ImageContext.ImageAddress);
> -  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
> -
> -  //
> -  // Report PEI Core debug information when remote debug is enabled
> -  //
> -  ImageContext.ImageAddress = PeiCoreImageBase;
> -  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN)
> ImageContext.ImageAddress);
> -  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
> -
> -  //
> -  // Find PEI Core entry point
> -  //
> -  Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase,
> (VOID**) PeiCoreEntryPoint);
> -  if (EFI_ERROR (Status)) {
> -    *PeiCoreEntryPoint = 0;
> -  }
> -
> -  return;
> -}
> -
> diff --git a/UefiPayloadPkg/SecCore/Ia32/SecEntry.nasm
> b/UefiPayloadPkg/SecCore/Ia32/SecEntry.nasm
> deleted file mode 100644
> index 877fc61ef0..0000000000
> --- a/UefiPayloadPkg/SecCore/Ia32/SecEntry.nasm
> +++ /dev/null
> @@ -1,78 +0,0 @@
> -;------------------------------------------------------------------------------
> -;
> -; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
> -; SPDX-License-Identifier: BSD-2-Clause-Patent
> -;
> -; Abstract:
> -;
> -;   Entry point for the coreboot UEFI payload.
> -;
> -;------------------------------------------------------------------------------
> -
> -SECTION .text
> -
> -; C Functions
> -extern  ASM_PFX(SecStartup)
> -
> -; Pcds
> -extern  ASM_PFX(PcdGet32 (PcdPayloadFdMemBase))
> -extern  ASM_PFX(PcdGet32 (PcdPayloadStackTop))
> -
> -;
> -; SecCore Entry Point
> -;
> -; Processor is in flat protected mode
> -;
> -; @param[in]  EAX   Initial value of the EAX register (BIST: Built-in Self Test)
> -; @param[in]  DI    'BP': boot-strap processor, or 'AP': application processor
> -; @param[in]  EBP   Pointer to the start of the Boot Firmware Volume
> -;
> -; @return     None  This routine does not return
> -;
> -global ASM_PFX(_ModuleEntryPoint)
> -ASM_PFX(_ModuleEntryPoint):
> -  ;
> -  ; Disable all the interrupts
> -  ;
> -  cli
> -
> -  ;
> -  ; Save the Payload HOB base address before switching the stack
> -  ;
> -  mov     eax, [esp + 4]
> -
> -  ;
> -  ; Construct the temporary memory at 0x80000, length 0x10000
> -  ;
> -  mov     esp, DWORD [ASM_PFX(PcdGet32 (PcdPayloadStackTop))]
> -
> -  ;
> -  ; Push the Payload HOB base address onto new stack
> -  ;
> -  push    eax
> -
> -  ;
> -  ; Pass BFV into the PEI Core
> -  ;
> -  push    DWORD [ASM_PFX(PcdGet32 (PcdPayloadFdMemBase))]
> -
> -  ;
> -  ; Pass stack base into the PEI Core
> -  ;
> -  push    BASE_512KB
> -
> -  ;
> -  ; Pass stack size into the PEI Core
> -  ;
> -  push    SIZE_64KB
> -
> -  ;
> -  ; Pass Control into the PEI Core
> -  ;
> -  call    ASM_PFX(SecStartup)
> -
> -  ;
> -  ; Should never return
> -  ;
> -  jmp     $
> -
> diff --git a/UefiPayloadPkg/SecCore/Ia32/Stack.nasm
> b/UefiPayloadPkg/SecCore/Ia32/Stack.nasm
> deleted file mode 100644
> index 55fd2243c8..0000000000
> --- a/UefiPayloadPkg/SecCore/Ia32/Stack.nasm
> +++ /dev/null
> @@ -1,72 +0,0 @@
> -;------------------------------------------------------------------------------
> -;
> -; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
> -; SPDX-License-Identifier: BSD-2-Clause-Patent
> -;
> -; Abstract:
> -;
> -;   Switch the stack from temporary memory to permanent memory.
> -;
> -;------------------------------------------------------------------------------
> -
> -SECTION .text
> -
> -;------------------------------------------------------------------------------
> -; VOID
> -; EFIAPI
> -; SecSwitchStack (
> -;   UINT32   TemporaryMemoryBase,
> -;   UINT32   PermenentMemoryBase
> -;   );
> -;------------------------------------------------------------------------------
> -global ASM_PFX(SecSwitchStack)
> -ASM_PFX(SecSwitchStack):
> -    ;
> -    ; Save three register: eax, ebx, ecx
> -    ;
> -    push  eax
> -    push  ebx
> -    push  ecx
> -    push  edx
> -
> -    ;
> -    ; !!CAUTION!! this function address's is pushed into stack after
> -    ; migration of whole temporary memory, so need save it to permanent
> -    ; memory at first!
> -    ;
> -
> -    mov   ebx,  [esp + 20]          ; Save the first parameter
> -    mov   ecx,  [esp + 24]          ; Save the second parameter
> -
> -    ;
> -    ; Save this function's return address into permanent memory at first.
> -    ; Then, Fixup the esp point to permanent memory
> -    ;
> -    mov   eax,  esp
> -    sub   eax,  ebx
> -    add   eax,  ecx
> -    mov   edx,  [esp]               ; copy pushed register's value to permanent memory
> -    mov   [eax], edx
> -    mov   edx,  [esp + 4]
> -    mov   [eax + 4], edx
> -    mov   edx,  [esp + 8]
> -    mov   [eax + 8], edx
> -    mov   edx,  [esp + 12]
> -    mov   [eax + 12], edx
> -    mov   edx,  [esp + 16]          ; Update return address into permanent memory
> -    mov   [eax + 16], edx
> -    mov   esp,  eax                 ; From now, esp is pointed to permanent memory
> -
> -    ;
> -    ; Fixup the ebp point to permanent memory
> -    ;
> -    mov   eax,  ebp
> -    sub   eax,  ebx
> -    add   eax,  ecx
> -    mov   ebp,  eax                 ; From now, ebp is pointed to permanent memory
> -
> -    pop   edx
> -    pop   ecx
> -    pop   ebx
> -    pop   eax
> -    ret
> diff --git a/UefiPayloadPkg/SecCore/SecCore.inf
> b/UefiPayloadPkg/SecCore/SecCore.inf
> deleted file mode 100644
> index 82ca7f567f..0000000000
> --- a/UefiPayloadPkg/SecCore/SecCore.inf
> +++ /dev/null
> @@ -1,58 +0,0 @@
> -## @file
> -# This is the first module taking control from the coreboot.
> -#
> -#  Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.<BR>
> -#
> -#  SPDX-License-Identifier: BSD-2-Clause-Patent
> -#
> -#
> -##
> -
> -[Defines]
> -  INF_VERSION                    = 0x00010005
> -  BASE_NAME                      = SecCore
> -  FILE_GUID                      = BA7BE337-6CFB-4dbb-B26C-21EC2FC16073
> -  MODULE_TYPE                    = SEC
> -  VERSION_STRING                 = 1.0
> -
> -
> -#
> -# The following information is for reference only and not required by the build
> tools.
> -#
> -#  VALID_ARCHITECTURES           = IA32 X64 EBC
> -#
> -
> -[Sources]
> -  SecMain.c
> -  SecMain.h
> -  FindPeiCore.c
> -
> -[Sources.IA32]
> -  Ia32/Stack.nasm
> -  Ia32/SecEntry.nasm
> -
> -[Packages]
> -  MdePkg/MdePkg.dec
> -  MdeModulePkg/MdeModulePkg.dec
> -  UefiCpuPkg/UefiCpuPkg.dec
> -  UefiPayloadPkg/UefiPayloadPkg.dec
> -
> -[LibraryClasses]
> -  BaseMemoryLib
> -  DebugLib
> -  BaseLib
> -  PcdLib
> -  DebugAgentLib
> -  UefiCpuLib
> -  PeCoffGetEntryPointLib
> -  PeCoffExtraActionLib
> -
> -[Ppis]
> -  gEfiSecPlatformInformationPpiGuid             # PPI ALWAYS_PRODUCED
> -  gEfiTemporaryRamSupportPpiGuid                # PPI ALWAYS_PRODUCED
> -  gEfiPayLoadHobBasePpiGuid                     # PPI ALWAYS_PRODUCED
> -
> -[Pcd]
> -  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
> -  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
> -  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadStackTop
> diff --git a/UefiPayloadPkg/SecCore/SecMain.c
> b/UefiPayloadPkg/SecCore/SecMain.c
> deleted file mode 100644
> index c0ca0e7d40..0000000000
> --- a/UefiPayloadPkg/SecCore/SecMain.c
> +++ /dev/null
> @@ -1,288 +0,0 @@
> -/** @file
> -  C functions in SEC
> -
> -Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -
> -#include "SecMain.h"
> -
> -EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {
> -  SecTemporaryRamSupport
> -};
> -
> -EFI_PEI_PPI_DESCRIPTOR            mPeiSecPlatformInformationPpi[] = {
> -  {
> -    (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> -    &gEfiTemporaryRamSupportPpiGuid,
> -    &gSecTemporaryRamSupportPpi
> -  }
> -};
> -
> -//
> -// These are IDT entries pointing to 10:FFFFFFE4h.
> -//
> -UINT64  mIdtEntryTemplate = 0xffff8e000010ffe4ULL;
> -
> -/**
> -  Caller provided function to be invoked at the end of InitializeDebugAgent().
> -
> -  Entry point to the C language phase of SEC. After the SEC assembly
> -  code has initialized some temporary memory and set up the stack,
> -  the control is transferred to this function.
> -
> -  @param[in] Context    The first input parameter of InitializeDebugAgent().
> -
> -**/
> -VOID
> -EFIAPI
> -SecStartupPhase2(
> -  IN VOID                     *Context
> -  );
> -
> -
> -/**
> -
> -  Entry point to the C language phase of SEC. After the SEC assembly
> -  code has initialized some temporary memory and set up the stack,
> -  the control is transferred to this function.
> -
> -
> -  @param SizeOfRam           Size of the temporary memory available for use.
> -  @param TempRamBase         Base address of temporary ram
> -  @param BootFirmwareVolume  Base address of the Boot Firmware Volume.
> -  @param BootloaderParameter A parameter from bootloader, e.g. HobList
> from SlimBootloader
> -
> -**/
> -VOID
> -EFIAPI
> -SecStartup (
> -  IN UINT32                   SizeOfRam,
> -  IN UINT32                   TempRamBase,
> -  IN VOID                     *BootFirmwareVolume,
> -  IN UINT32                   BootloaderParameter
> -  )
> -{
> -  EFI_SEC_PEI_HAND_OFF        SecCoreData;
> -  IA32_DESCRIPTOR             IdtDescriptor;
> -  SEC_IDT_TABLE               IdtTableInStack;
> -  UINT32                      Index;
> -  UINT32                      PeiStackSize;
> -
> -  PeiStackSize = (SizeOfRam >> 1);
> -
> -  ASSERT (PeiStackSize < SizeOfRam);
> -
> -  //
> -  // Process all libraries constructor function linked to SecCore.
> -  //
> -  ProcessLibraryConstructorList ();
> -
> -  //
> -  // Initialize floating point operating environment
> -  // to be compliant with UEFI spec.
> -  //
> -  InitializeFloatingPointUnits ();
> -
> -
> -  // |-------------------|---->
> -  // |Idt Table          |
> -  // |-------------------|
> -  // |PeiService Pointer |    PeiStackSize
> -  // |-------------------|
> -  // |                   |
> -  // |      Stack        |
> -  // |-------------------|---->
> -  // |                   |
> -  // |                   |
> -  // |      Heap         |    PeiTemporaryRamSize
> -  // |                   |
> -  // |                   |
> -  // |-------------------|---->  TempRamBase
> -
> -  IdtTableInStack.PeiService = 0;
> -  for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
> -    CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index],
> (VOID*)&mIdtEntryTemplate, sizeof (UINT64));
> -  }
> -
> -  IdtDescriptor.Base  = (UINTN) &IdtTableInStack.IdtTable;
> -  IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
> -
> -  AsmWriteIdtr (&IdtDescriptor);
> -
> -  //
> -  // Update the base address and length of Pei temporary memory
> -  //
> -  SecCoreData.DataSize               = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF);
> -  SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;
> -  SecCoreData.BootFirmwareVolumeSize = (UINTN)(0x100000000ULL - (UINTN)
> BootFirmwareVolume);
> -  SecCoreData.TemporaryRamBase       = (VOID*)(UINTN) TempRamBase;
> -  SecCoreData.TemporaryRamSize       = SizeOfRam;
> -  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;
> -  SecCoreData.PeiTemporaryRamSize    = SizeOfRam - PeiStackSize;
> -  SecCoreData.StackBase              = (VOID*)(UINTN)(TempRamBase +
> SecCoreData.PeiTemporaryRamSize);
> -  SecCoreData.StackSize              = PeiStackSize;
> -
> -  //
> -  // Initialize Debug Agent to support source level debug in SEC/PEI phases
> before memory ready.
> -  //
> -  InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData,
> SecStartupPhase2);
> -
> -}
> -
> -/**
> -  Caller provided function to be invoked at the end of InitializeDebugAgent().
> -
> -  Entry point to the C language phase of SEC. After the SEC assembly
> -  code has initialized some temporary memory and set up the stack,
> -  the control is transferred to this function.
> -
> -  @param[in] Context    The first input parameter of InitializeDebugAgent().
> -
> -**/
> -VOID
> -EFIAPI
> -SecStartupPhase2(
> -  IN VOID                     *Context
> -  )
> -{
> -  EFI_SEC_PEI_HAND_OFF        *SecCoreData;
> -  EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;
> -
> -  SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
> -  //
> -  // Find Pei Core entry point. It will report SEC and Pei Core debug information
> if remote debug
> -  // is enabled.
> -  //
> -  FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *)
> SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint);
> -  if (PeiCoreEntryPoint == NULL)
> -  {
> -    CpuDeadLoop ();
> -  }
> -
> -  //
> -  // Transfer the control to the PEI core
> -  //
> -  ASSERT (PeiCoreEntryPoint != NULL);
> -  (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR
> *)&mPeiSecPlatformInformationPpi);
> -
> -  //
> -  // Should not come here.
> -  //
> -  return ;
> -}
> -
> -/**
> -  This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary
> RAM into
> -  permanent memory.
> -
> -  @param PeiServices            Pointer to the PEI Services Table.
> -  @param TemporaryMemoryBase    Source Address in temporary memory
> from which the SEC or PEIM will copy the
> -                                Temporary RAM contents.
> -  @param PermanentMemoryBase    Destination Address in permanent
> memory into which the SEC or PEIM will copy the
> -                                Temporary RAM contents.
> -  @param CopySize               Amount of memory to migrate from temporary to
> permanent memory.
> -
> -  @retval EFI_SUCCESS           The data was successfully returned.
> -  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize >
> TemporaryMemoryBase when
> -                                TemporaryMemoryBase > PermanentMemoryBase.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SecTemporaryRamSupport (
> -  IN CONST EFI_PEI_SERVICES   **PeiServices,
> -  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> -  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> -  IN UINTN                    CopySize
> -  )
> -{
> -  IA32_DESCRIPTOR   IdtDescriptor;
> -  VOID*             OldHeap;
> -  VOID*             NewHeap;
> -  VOID*             OldStack;
> -  VOID*             NewStack;
> -  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  DebugAgentContext;
> -  BOOLEAN           OldStatus;
> -  UINTN             PeiStackSize;
> -
> -  PeiStackSize = (CopySize >> 1);
> -
> -  ASSERT (PeiStackSize < CopySize);
> -
> -  //
> -  // |-------------------|---->
> -  // |      Stack        |    PeiStackSize
> -  // |-------------------|---->
> -  // |      Heap         |    PeiTemporaryRamSize
> -  // |-------------------|---->  TempRamBase
> -  //
> -  // |-------------------|---->
> -  // |      Heap         |    PeiTemporaryRamSize
> -  // |-------------------|---->
> -  // |      Stack        |    PeiStackSize
> -  // |-------------------|---->  PermanentMemoryBase
> -  //
> -
> -  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
> -  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + PeiStackSize);
> -
> -  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize -
> PeiStackSize);
> -  NewStack = (VOID*)(UINTN)PermanentMemoryBase;
> -
> -  DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap -
> (UINTN)OldHeap;
> -  DebugAgentContext.StackMigrateOffset = (UINTN)NewStack -
> (UINTN)OldStack;
> -
> -  OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
> -  //
> -  // Initialize Debug Agent to support source level debug in PEI phase after
> memory ready.
> -  // It will build HOB and fix up the pointer in IDT table.
> -  //
> -  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *)
> &DebugAgentContext, NULL);
> -
> -  //
> -  // Migrate Heap
> -  //
> -  CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize);
> -
> -  //
> -  // Migrate Stack
> -  //
> -  CopyMem (NewStack, OldStack, PeiStackSize);
> -
> -
> -  //
> -  // We need *not* fix the return address because currently,
> -  // The PeiCore is executed in flash.
> -  //
> -
> -  //
> -  // Rebase IDT table in permanent memory
> -  //
> -  AsmReadIdtr (&IdtDescriptor);
> -  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack +
> (UINTN)NewStack;
> -
> -  AsmWriteIdtr (&IdtDescriptor);
> -
> -
> -  //
> -  // Program MTRR
> -  //
> -
> -  //
> -  // SecSwitchStack function must be invoked after the memory migration
> -  // immediately, also we need fixup the stack change caused by new call into
> -  // permanent memory.
> -  //
> -  SecSwitchStack (
> -    (UINT32) (UINTN) OldStack,
> -    (UINT32) (UINTN) NewStack
> -    );
> -
> -  SaveAndSetDebugTimerInterrupt (OldStatus);
> -
> -  return EFI_SUCCESS;
> -}
> -
> diff --git a/UefiPayloadPkg/SecCore/SecMain.h
> b/UefiPayloadPkg/SecCore/SecMain.h
> deleted file mode 100644
> index ca0a95d03e..0000000000
> --- a/UefiPayloadPkg/SecCore/SecMain.h
> +++ /dev/null
> @@ -1,131 +0,0 @@
> -/** @file
> -  Master header file for SecCore.
> -
> -Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#ifndef _SEC_CORE_H_
> -#define _SEC_CORE_H_
> -
> -
> -#include <PiPei.h>
> -
> -#include <Ppi/SecPlatformInformation.h>
> -#include <Ppi/TemporaryRamSupport.h>
> -
> -#include <Library/BaseLib.h>
> -#include <Library/DebugLib.h>
> -#include <Library/PcdLib.h>
> -#include <Library/BaseMemoryLib.h>
> -#include <Library/UefiCpuLib.h>
> -#include <Library/PeCoffGetEntryPointLib.h>
> -#include <Library/PeCoffExtraActionLib.h>
> -#include <Library/DebugAgentLib.h>
> -
> -
> -#define SEC_IDT_ENTRY_COUNT  34
> -
> -typedef struct _SEC_IDT_TABLE {
> -  //
> -  // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT
> base
> -  // address should be 8-byte alignment.
> -  // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store
> -  // EFI_PEI_SERVICES**
> -  //
> -  UINT64            PeiService;
> -  UINT64            IdtTable[SEC_IDT_ENTRY_COUNT];
> -} SEC_IDT_TABLE;
> -
> -/**
> -  Switch the stack in the temporary memory to the one in the permanent
> memory.
> -
> -  This function must be invoked after the memory migration immediately. The
> relative
> -  position of the stack in the temporary and permanent memory is same.
> -
> -  @param TemporaryMemoryBase  Base address of the temporary memory.
> -  @param PermenentMemoryBase  Base address of the permanent memory.
> -**/
> -VOID
> -EFIAPI
> -SecSwitchStack (
> -  UINT32   TemporaryMemoryBase,
> -  UINT32   PermenentMemoryBase
> -  );
> -
> -/**
> -  This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary
> RAM into
> -  permanent memory.
> -
> -  @param PeiServices            Pointer to the PEI Services Table.
> -  @param TemporaryMemoryBase    Source Address in temporary memory
> from which the SEC or PEIM will copy the
> -                                Temporary RAM contents.
> -  @param PermanentMemoryBase    Destination Address in permanent
> memory into which the SEC or PEIM will copy the
> -                                Temporary RAM contents.
> -  @param CopySize               Amount of memory to migrate from temporary to
> permanent memory.
> -
> -  @retval EFI_SUCCESS           The data was successfully returned.
> -  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize >
> TemporaryMemoryBase when
> -                                TemporaryMemoryBase > PermanentMemoryBase.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SecTemporaryRamSupport (
> -  IN CONST EFI_PEI_SERVICES   **PeiServices,
> -  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> -  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> -  IN UINTN                    CopySize
> -  );
> -
> -/**
> -  Entry point to the C language phase of SEC. After the SEC assembly
> -  code has initialized some temporary memory and set up the stack,
> -  the control is transferred to this function.
> -
> -  @param SizeOfRam           Size of the temporary memory available for use.
> -  @param TempRamBase         Base address of temporary ram
> -  @param BootFirmwareVolume  Base address of the Boot Firmware Volume.
> -  @param BootloaderParameter A parameter from bootloader, e.g. HobList
> from SlimBootloader
> -
> -**/
> -VOID
> -EFIAPI
> -SecStartup (
> -  IN UINT32                   SizeOfRam,
> -  IN UINT32                   TempRamBase,
> -  IN VOID                     *BootFirmwareVolume,
> -  IN UINT32                   BootloaderParameter
> -  );
> -
> -/**
> -  Find and return Pei Core entry point.
> -
> -  It also find SEC and PEI Core file debug information. It will report them if
> -  remote debug is enabled.
> -
> -  @param  BootFirmwareVolumePtr  Point to the boot firmware volume.
> -  @param  PeiCoreEntryPoint      Point to the PEI core entry point.
> -
> -**/
> -VOID
> -EFIAPI
> -FindAndReportEntryPoints (
> -  IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
> -  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
> -  );
> -
> -/**
> -  Autogenerated function that calls the library constructors for all of the
> module's
> -  dependent libraries.  This function must be called by the SEC Core once a stack
> has
> -  been established.
> -
> -**/
> -VOID
> -EFIAPI
> -ProcessLibraryConstructorList (
> -  VOID
> -  );
> -
> -#endif
> diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
> b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
> new file mode 100644
> index 0000000000..73abe56982
> --- /dev/null
> +++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
> @@ -0,0 +1,364 @@
> +/** @file
> +  Ia32-specific functionality for DxeLoad.
> +
> +Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/HobLib.h>
> +#include "VirtualMemory.h"
> +#include "UefiPayloadEntry.h"
> +
> +#define STACK_SIZE            0x20000
> +#define IDT_ENTRY_COUNT       32
> +
> +typedef struct _X64_IDT_TABLE {
> +  //
> +  // Reserved 4 bytes preceding PeiService and IdtTable,
> +  // since IDT base address should be 8-byte alignment.
> +  //
> +  UINT32                   Reserved;
> +  CONST EFI_PEI_SERVICES   **PeiService;
> +  X64_IDT_GATE_DESCRIPTOR  IdtTable[IDT_ENTRY_COUNT];
> +} X64_IDT_TABLE;
> +
> +//
> +// Global Descriptor Table (GDT)
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT gGdtEntries[] = {
> +/* selector { Global Segment Descriptor                              } */
> +/* 0x00 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, //null descriptor
> +/* 0x08 */  {{0xffff, 0,  0,  0x2,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, //linear data
> segment descriptor
> +/* 0x10 */  {{0xffff, 0,  0,  0xf,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, //linear code
> segment descriptor
> +/* 0x18 */  {{0xffff, 0,  0,  0x3,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, //system data
> segment descriptor
> +/* 0x20 */  {{0xffff, 0,  0,  0xa,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, //system code
> segment descriptor
> +/* 0x28 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, //spare segment
> descriptor
> +/* 0x30 */  {{0xffff, 0,  0,  0x2,  1,  0,  1,  0xf,  0,  0, 1,  1,  0}}, //system data
> segment descriptor
> +/* 0x38 */  {{0xffff, 0,  0,  0xa,  1,  0,  1,  0xf,  0,  1, 0,  1,  0}}, //system code
> segment descriptor
> +/* 0x40 */  {{0,      0,  0,  0,    0,  0,  0,  0,    0,  0, 0,  0,  0}}, //spare segment
> descriptor
> +};
> +
> +//
> +// IA32 Gdt register
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR gGdt = {
> +  sizeof (gGdtEntries) - 1,
> +  (UINTN) gGdtEntries
> +  };
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED  IA32_DESCRIPTOR gLidtDescriptor = {
> +  sizeof (X64_IDT_GATE_DESCRIPTOR) * IDT_ENTRY_COUNT - 1,
> +  0
> +};
> +
> +/**
> +  Allocates and fills in the Page Directory and Page Table Entries to
> +  establish a 4G page table.
> +
> +  @param[in] StackBase  Stack base address.
> +  @param[in] StackSize  Stack size.
> +
> +  @return The address of page table.
> +
> +**/
> +UINTN
> +Create4GPageTablesIa32Pae (
> +  IN EFI_PHYSICAL_ADDRESS   StackBase,
> +  IN UINTN                  StackSize
> +  )
> +{
> +  UINT8                                         PhysicalAddressBits;
> +  EFI_PHYSICAL_ADDRESS                          PhysicalAddress;
> +  UINTN                                         IndexOfPdpEntries;
> +  UINTN                                         IndexOfPageDirectoryEntries;
> +  UINT32                                        NumberOfPdpEntriesNeeded;
> +  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMap;
> +  PAGE_MAP_AND_DIRECTORY_POINTER                *PageDirectoryPointerEntry;
> +  PAGE_TABLE_ENTRY                              *PageDirectoryEntry;
> +  UINTN                                         TotalPagesNum;
> +  UINTN                                         PageAddress;
> +  UINT64                                        AddressEncMask;
> +
> +  //
> +  // Make sure AddressEncMask is contained to smallest supported address field
> +  //
> +  AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &
> PAGING_1G_ADDRESS_MASK_64;
> +
> +  PhysicalAddressBits = 32;
> +
> +  //
> +  // Calculate the table entries needed.
> +  //
> +  NumberOfPdpEntriesNeeded = (UINT32) LShiftU64 (1, (PhysicalAddressBits -
> 30));
> +
> +  TotalPagesNum = NumberOfPdpEntriesNeeded + 1;
> +  PageAddress = (UINTN) AllocatePageTableMemory (TotalPagesNum);
> +  ASSERT (PageAddress != 0);
> +
> +  PageMap = (VOID *) PageAddress;
> +  PageAddress += SIZE_4KB;
> +
> +  PageDirectoryPointerEntry = PageMap;
> +  PhysicalAddress = 0;
> +
> +  for (IndexOfPdpEntries = 0; IndexOfPdpEntries <
> NumberOfPdpEntriesNeeded; IndexOfPdpEntries++,
> PageDirectoryPointerEntry++) {
> +    //
> +    // Each Directory Pointer entries points to a page of Page Directory entires.
> +    // So allocate space for them and fill them in in the
> IndexOfPageDirectoryEntries loop.
> +    //
> +    PageDirectoryEntry = (VOID *) PageAddress;
> +    PageAddress += SIZE_4KB;
> +
> +    //
> +    // Fill in a Page Directory Pointer Entries
> +    //
> +    PageDirectoryPointerEntry->Uint64 = (UINT64) (UINTN) PageDirectoryEntry
> | AddressEncMask;
> +    PageDirectoryPointerEntry->Bits.Present = 1;
> +
> +    for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512;
> IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress +=
> SIZE_2MB) {
> +      if ((IsNullDetectionEnabled () && PhysicalAddress == 0)
> +          || ((PhysicalAddress < StackBase + StackSize)
> +              && ((PhysicalAddress + SIZE_2MB) > StackBase))) {
> +        //
> +        // Need to split this 2M page that covers stack range.
> +        //
> +        Split2MPageTo4K (PhysicalAddress, (UINT64 *) PageDirectoryEntry,
> StackBase, StackSize);
> +      } else {
> +        //
> +        // Fill in the Page Directory entries
> +        //
> +        PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress |
> AddressEncMask;
> +        PageDirectoryEntry->Bits.ReadWrite = 1;
> +        PageDirectoryEntry->Bits.Present = 1;
> +        PageDirectoryEntry->Bits.MustBe1 = 1;
> +      }
> +    }
> +  }
> +
> +  for (; IndexOfPdpEntries < 512; IndexOfPdpEntries++,
> PageDirectoryPointerEntry++) {
> +    ZeroMem (
> +      PageDirectoryPointerEntry,
> +      sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
> +      );
> +  }
> +
> +  //
> +  // Protect the page table by marking the memory used for page table to be
> +  // read-only.
> +  //
> +  EnablePageTableProtection ((UINTN)PageMap, FALSE);
> +
> +  return (UINTN) PageMap;
> +}
> +
> +/**
> +  The function will check if IA32 PAE is supported.
> +
> +  @retval TRUE      IA32 PAE is supported.
> +  @retval FALSE     IA32 PAE is not supported.
> +
> +**/
> +BOOLEAN
> +IsIa32PaeSupport (
> +  VOID
> +  )
> +{
> +  UINT32            RegEax;
> +  UINT32            RegEdx;
> +  BOOLEAN           Ia32PaeSupport;
> +
> +  Ia32PaeSupport = FALSE;
> +  AsmCpuid (0x0, &RegEax, NULL, NULL, NULL);
> +  if (RegEax >= 0x1) {
> +    AsmCpuid (0x1, NULL, NULL, NULL, &RegEdx);
> +    if ((RegEdx & BIT6) != 0) {
> +      Ia32PaeSupport = TRUE;
> +    }
> +  }
> +
> +  return Ia32PaeSupport;
> +}
> +
> +/**
> +  The function will check if page table should be setup or not.
> +
> +  @retval TRUE      Page table should be created.
> +  @retval FALSE     Page table should not be created.
> +
> +**/
> +BOOLEAN
> +ToBuildPageTable (
> +  VOID
> +  )
> +{
> +  if (!IsIa32PaeSupport ()) {
> +    return FALSE;
> +  }
> +
> +  if (IsNullDetectionEnabled ()) {
> +    return TRUE;
> +  }
> +
> +  if (PcdGet8 (PcdHeapGuardPropertyMask) != 0) {
> +    return TRUE;
> +  }
> +
> +  if (PcdGetBool (PcdCpuStackGuard)) {
> +    return TRUE;
> +  }
> +
> +  if (IsEnableNonExecNeeded ()) {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +   Transfers control to DxeCore.
> +
> +   This function performs a CPU architecture specific operations to execute
> +   the entry point of DxeCore with the parameters of HobList.
> +
> +   @param DxeCoreEntryPoint         The entry point of DxeCore.
> +   @param HobList                   The start of HobList passed to DxeCore.
> +
> +**/
> +VOID
> +HandOffToDxeCore (
> +  IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,
> +  IN EFI_PEI_HOB_POINTERS   HobList
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS      BaseOfStack;
> +  EFI_PHYSICAL_ADDRESS      TopOfStack;
> +  UINTN                     PageTables;
> +  X64_IDT_GATE_DESCRIPTOR   *IdtTable;
> +  UINTN                     SizeOfTemplate;
> +  VOID                      *TemplateBase;
> +  EFI_PHYSICAL_ADDRESS      VectorAddress;
> +  UINT32                    Index;
> +  X64_IDT_TABLE             *IdtTableForX64;
> +
> +  //
> +  // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
> +  //
> +  if (IsNullDetectionEnabled ()) {
> +    ClearFirst4KPage (HobList.Raw);
> +    BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1),
> EfiBootServicesData);
> +  }
> +
> +  BaseOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocatePages
> (EFI_SIZE_TO_PAGES (STACK_SIZE));
> +  ASSERT (BaseOfStack != 0);
> +
> +  if (FeaturePcdGet(PcdDxeIplSwitchToLongMode)) {
> +    //
> +    // Compute the top of the stack we were allocated, which is used to load X64
> dxe core.
> +    // Pre-allocate a 32 bytes which confroms to x64 calling convention.
> +    //
> +    // The first four parameters to a function are passed in rcx, rdx, r8 and r9.
> +    // Any further parameters are pushed on the stack. Furthermore, space (4 *
> 8bytes) for the
> +    // register parameters is reserved on the stack, in case the called function
> +    // wants to spill them; this is important if the function is variadic.
> +    //
> +    TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) *
> EFI_PAGE_SIZE - 32;
> +
> +    //
> +    //  x64 Calling Conventions requires that the stack must be aligned to 16
> bytes
> +    //
> +    TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER
> (TopOfStack, 16);
> +
> +    //
> +    // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the
> BS_DATA
> +    // memory, it may be corrupted when copying FV to high-end memory
> +    //
> +    AsmWriteGdtr (&gGdt);
> +    //
> +    // Create page table and save PageMapLevel4 to CR3
> +    //
> +    PageTables = CreateIdentityMappingPageTables (BaseOfStack, STACK_SIZE);
> +
> +    //
> +    // Paging might be already enabled. To avoid conflict configuration,
> +    // disable paging first anyway.
> +    //
> +    AsmWriteCr0 (AsmReadCr0 () & (~BIT31));
> +    AsmWriteCr3 (PageTables);
> +
> +    //
> +    // Update the contents of BSP stack HOB to reflect the real stack info passed
> to DxeCore.
> +    //
> +    UpdateStackHob (BaseOfStack, STACK_SIZE);
> +
> +    SizeOfTemplate = AsmGetVectorTemplatInfo (&TemplateBase);
> +
> +  VectorAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocatePages
> (EFI_SIZE_TO_PAGES(sizeof (X64_IDT_TABLE) + SizeOfTemplate *
> IDT_ENTRY_COUNT));
> +  ASSERT (VectorAddress != 0);
> +
> +    //
> +    // Store EFI_PEI_SERVICES** in the 4 bytes immediately preceding IDT to
> avoid that
> +    // it may not be gotten correctly after IDT register is re-written.
> +    //
> +    IdtTableForX64 = (X64_IDT_TABLE *) (UINTN) VectorAddress;
> +    IdtTableForX64->PeiService = NULL;
> +
> +    VectorAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) (IdtTableForX64 + 1);
> +    IdtTable      = IdtTableForX64->IdtTable;
> +    for (Index = 0; Index < IDT_ENTRY_COUNT; Index++) {
> +      IdtTable[Index].Ia32IdtEntry.Bits.GateType    =  0x8e;
> +      IdtTable[Index].Ia32IdtEntry.Bits.Reserved_0  =  0;
> +      IdtTable[Index].Ia32IdtEntry.Bits.Selector    =  SYS_CODE64_SEL;
> +
> +      IdtTable[Index].Ia32IdtEntry.Bits.OffsetLow   = (UINT16) VectorAddress;
> +      IdtTable[Index].Ia32IdtEntry.Bits.OffsetHigh  = (UINT16) (RShiftU64
> (VectorAddress, 16));
> +      IdtTable[Index].Offset32To63                  = (UINT32) (RShiftU64
> (VectorAddress, 32));
> +      IdtTable[Index].Reserved                      = 0;
> +
> +      CopyMem ((VOID *) (UINTN) VectorAddress, TemplateBase,
> SizeOfTemplate);
> +      AsmVectorFixup ((VOID *) (UINTN) VectorAddress, (UINT8) Index);
> +
> +      VectorAddress += SizeOfTemplate;
> +    }
> +
> +    gLidtDescriptor.Base = (UINTN) IdtTable;
> +
> +
> +    AsmWriteIdtr (&gLidtDescriptor);
> +
> +    DEBUG ((
> +      DEBUG_INFO,
> +      "%a() Stack Base: 0x%lx, Stack Size: 0x%x\n",
> +      __FUNCTION__,
> +      BaseOfStack,
> +      STACK_SIZE
> +      ));
> +
> +    //
> +    // Go to Long Mode and transfer control to DxeCore.
> +    // Interrupts will not get turned on until the CPU AP is loaded.
> +    // Call x64 drivers passing in single argument, a pointer to the HOBs.
> +    //
> +    AsmEnablePaging64 (
> +      SYS_CODE64_SEL,
> +      DxeCoreEntryPoint,
> +      (EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw),
> +      0,
> +      TopOfStack
> +      );
> +  } else {
> +    // 32bit UEFI payload could be supported if required later.
> +    DEBUG ((DEBUG_ERROR, "NOT support 32bit UEFI payload\n"));
> +    ASSERT (FALSE);
> +  }
> +
> +}
> +
> diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/IdtVectorAsm.nasm
> b/UefiPayloadPkg/UefiPayloadEntry/Ia32/IdtVectorAsm.nasm
> new file mode 100644
> index 0000000000..4f9b98f18b
> --- /dev/null
> +++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/IdtVectorAsm.nasm
> @@ -0,0 +1,71 @@
> +;/** @file
> +;
> +;    IDT vector entry.
> +;
> +;  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
> +;  SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;**/
> +
> +    SECTION .text
> +
> +;
> +;------------------------------------------------------------------------------
> +;  Generic IDT Vector Handlers for the Host.
> +;
> +;------------------------------------------------------------------------------
> +
> +ALIGN   8
> +global ASM_PFX(AsmGetVectorTemplatInfo)
> +global ASM_PFX(AsmVectorFixup)
> +
> +@VectorTemplateBase:
> +        push  eax
> +        db    0x6a       ; push #VectorNumber
> +@VectorNum:
> +        db    0
> +        mov   eax, CommonInterruptEntry
> +        jmp   eax
> +@VectorTemplateEnd:
> +
> +global ASM_PFX(AsmGetVectorTemplatInfo)
> +ASM_PFX(AsmGetVectorTemplatInfo):
> +        mov   ecx, [esp + 4]
> +        mov   dword [ecx], @VectorTemplateBase
> +        mov   eax, (@VectorTemplateEnd - @VectorTemplateBase)
> +        ret
> +
> +global ASM_PFX(AsmVectorFixup)
> +ASM_PFX(AsmVectorFixup):
> +        mov   eax, dword [esp + 8]
> +        mov   ecx, [esp + 4]
> +        mov   [ecx + (@VectorNum - @VectorTemplateBase)], al
> +        ret
> +
> +;---------------------------------------;
> +; CommonInterruptEntry                  ;
> +;---------------------------------------;
> +; The follow algorithm is used for the common interrupt routine.
> +
> +;
> +; +---------------------+ <-- 16-byte aligned ensured by processor
> +; +    Old SS           +
> +; +---------------------+
> +; +    Old RSP          +
> +; +---------------------+
> +; +    RFlags           +
> +; +---------------------+
> +; +    CS               +
> +; +---------------------+
> +; +    RIP              +
> +; +---------------------+
> +; +    Error Code       +
> +; +---------------------+
> +; +    Vector Number    +
> +; +---------------------+
> +
> +CommonInterruptEntry:
> +  cli
> +
> +  jmp $
> +
> diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/SecEntry.nasm
> b/UefiPayloadPkg/UefiPayloadEntry/Ia32/SecEntry.nasm
> new file mode 100644
> index 0000000000..fa5ed159c6
> --- /dev/null
> +++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/SecEntry.nasm
> @@ -0,0 +1,46 @@
> +;------------------------------------------------------------------------------
> +;*
> +;*   Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
> +;*   SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +;------------------------------------------------------------------------------
> +
> +#include <Base.h>
> +
> +SECTION .text
> +
> +extern ASM_PFX(PayloadEntry)
> +extern  ASM_PFX(PcdGet32 (PcdPayloadStackTop))
> +
> +;
> +; SecCore Entry Point
> +;
> +; Processor is in flat protected mode
> +
> +global ASM_PFX(_ModuleEntryPoint)
> +ASM_PFX(_ModuleEntryPoint):
> +
> +  ;
> +  ; Disable all the interrupts
> +  ;
> +  cli
> +
> +  ;
> +  ; Save the bootloader parameter base address
> +  ;
> +  mov   eax, [esp + 4]
> +
> +  mov   esp, FixedPcdGet32 (PcdPayloadStackTop)
> +
> +  ;
> +  ; Push the bootloader parameter address onto new stack
> +  ;
> +  push  0
> +  push  eax
> +
> +  ;
> +  ; Call into C code
> +  ;
> +  call  ASM_PFX(PayloadEntry)
> +  jmp   $
> +
> diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
> b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
> new file mode 100644
> index 0000000000..d1c9cecd93
> --- /dev/null
> +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
> @@ -0,0 +1,280 @@
> +/** @file
> +
> +  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "UefiPayloadEntry.h"
> +
> +VOID*
> +AllocateCodePages (
> +  IN  UINTN     Pages
> +  )
> +{
> +  VOID                    *Alloc;
> +  EFI_PEI_HOB_POINTERS    Hob;
> +
> +  Alloc = AllocatePages (Pages);
> +  if (Alloc == NULL) {
> +    return NULL;
> +  }
> +
> +  // find the HOB we just created, and change the type to EfiBootServicesCode
> +  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
> +  while (Hob.Raw != NULL) {
> +    if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress ==
> (UINTN)Alloc) {
> +      Hob.MemoryAllocation->AllocDescriptor.MemoryType =
> EfiBootServicesCode;
> +      return Alloc;
> +    }
> +    Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION,
> GET_NEXT_HOB (Hob));
> +  }
> +
> +  ASSERT (FALSE);
> +
> +  FreePages (Alloc, Pages);
> +  return NULL;
> +}
> +
> +
> +EFI_STATUS
> +LoadPeCoffImage (
> +  IN  VOID                          *PeCoffImage,
> +  OUT EFI_PHYSICAL_ADDRESS          *ImageAddress,
> +  OUT UINT64                        *ImageSize,
> +  OUT EFI_PHYSICAL_ADDRESS          *EntryPoint
> +  )
> +{
> +  RETURN_STATUS                     Status;
> +  PE_COFF_LOADER_IMAGE_CONTEXT      ImageContext;
> +  VOID                              *Buffer;
> +
> +  ZeroMem (&ImageContext, sizeof (ImageContext));
> +
> +  ImageContext.Handle    = PeCoffImage;
> +  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
> +
> +  Status = PeCoffLoaderGetImageInfo (&ImageContext);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Allocate Memory for the image
> +  //
> +  Buffer = AllocateCodePages
> (EFI_SIZE_TO_PAGES((UINT32)ImageContext.ImageSize));
> +  ASSERT (Buffer != 0);
> +
> +  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
> +
> +  //
> +  // Load the image to our new buffer
> +  //
> +  Status = PeCoffLoaderLoadImage (&ImageContext);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Relocate the image in our new buffer
> +  //
> +  Status = PeCoffLoaderRelocateImage (&ImageContext);
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  *ImageAddress = ImageContext.ImageAddress;
> +  *ImageSize    = ImageContext.ImageSize;
> +  *EntryPoint   = ImageContext.EntryPoint;
> +
> +  return Status;
> +}
> +
> +/**
> +  This function searchs a given file type within a valid FV.
> +
> +  @param FvHeader        A pointer to firmware volume header that contains the
> set of files
> +                         to be searched.
> +  @param FileType        File type to be searched.
> +  @param FileHeader      A pointer to the discovered file, if successful.
> +
> +  @retval EFI_SUCCESS    Successfully found FileType
> +  @retval EFI_NOT_FOUND  File type can't be found.
> +**/
> +EFI_STATUS
> +FvFindFile (
> +  IN  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader,
> +  IN  EFI_FV_FILETYPE             FileType,
> +  OUT EFI_FFS_FILE_HEADER         **FileHeader
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> +  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
> +  EFI_FFS_FILE_HEADER         *File;
> +  UINT32                      Size;
> +  EFI_PHYSICAL_ADDRESS        EndOfFile;
> +
> +  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader;
> +  EndOfFirmwareVolume = CurrentAddress + FvHeader->FvLength;
> +
> +  //
> +  // Loop through the FFS files
> +  //
> +  for (EndOfFile = CurrentAddress + FvHeader->HeaderLength; ; ) {
> +    CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
> +    if (CurrentAddress > EndOfFirmwareVolume) {
> +      break;
> +    }
> +
> +    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> +    if (IS_FFS_FILE2 (File)) {
> +      Size = FFS_FILE2_SIZE (File);
> +      if (Size <= 0x00FFFFFF) {
> +        break;
> +      }
> +    } else {
> +      Size = FFS_FILE_SIZE (File);
> +      if (Size < sizeof (EFI_FFS_FILE_HEADER)) {
> +        break;
> +      }
> +    }
> +
> +    EndOfFile = CurrentAddress + Size;
> +    if (EndOfFile > EndOfFirmwareVolume) {
> +      break;
> +    }
> +
> +    //
> +    // Look for file type
> +    //
> +    if (File->Type == FileType) {
> +      *FileHeader = File;
> +      return EFI_SUCCESS;
> +    }
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +
> +/**
> +  This function searchs a given section type within a valid FFS file.
> +
> +  @param  FileHeader            A pointer to the file header that contains the set of
> sections to
> +                                be searched.
> +  @param  SearchType            The value of the section type to search.
> +  @param  SectionData           A pointer to the discovered section, if successful.
> +
> +  @retval EFI_SUCCESS           The section was found.
> +  @retval EFI_NOT_FOUND         The section was not found.
> +
> +**/
> +EFI_STATUS
> +FileFindSection (
> +  IN EFI_FFS_FILE_HEADER        *FileHeader,
> +  IN EFI_SECTION_TYPE           SectionType,
> +  OUT VOID                      **SectionData
> +  )
> +{
> +  UINT32                        FileSize;
> +  EFI_COMMON_SECTION_HEADER     *Section;
> +  UINT32                        SectionSize;
> +  UINT32                        Index;
> +
> +  if (IS_FFS_FILE2 (FileHeader)) {
> +    FileSize = FFS_FILE2_SIZE (FileHeader);
> +  } else {
> +    FileSize = FFS_FILE_SIZE (FileHeader);
> +  }
> +  FileSize  -= sizeof (EFI_FFS_FILE_HEADER);
> +
> +  Section    = (EFI_COMMON_SECTION_HEADER *)(FileHeader + 1);
> +  Index      = 0;
> +  while (Index < FileSize) {
> +    if (Section->Type == SectionType) {
> +      if (IS_SECTION2 (Section)) {
> +        *SectionData = (VOID *)((UINT8 *) Section + sizeof
> (EFI_COMMON_SECTION_HEADER2));
> +      } else {
> +        *SectionData = (VOID *)((UINT8 *) Section + sizeof
> (EFI_COMMON_SECTION_HEADER));
> +      }
> +      return EFI_SUCCESS;
> +    }
> +
> +    if (IS_SECTION2 (Section)) {
> +      SectionSize = SECTION2_SIZE (Section);
> +    } else {
> +      SectionSize = SECTION_SIZE (Section);
> +    }
> +
> +    SectionSize = GET_OCCUPIED_SIZE (SectionSize, 4);
> +    ASSERT (SectionSize != 0);
> +    Index += SectionSize;
> +
> +    Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section +
> SectionSize);
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +
> +/**
> +  Find DXE core from FV and build DXE core HOBs.
> +
> +  @param[out]  DxeCoreEntryPoint     DXE core entry point
> +
> +  @retval EFI_SUCCESS        If it completed successfully.
> +  @retval EFI_NOT_FOUND      If it failed to load DXE FV.
> +**/
> +EFI_STATUS
> +LoadDxeCore (
> +  OUT PHYSICAL_ADDRESS        *DxeCoreEntryPoint
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_FIRMWARE_VOLUME_HEADER  *PayloadFv;
> +  EFI_FIRMWARE_VOLUME_HEADER  *DxeCoreFv;
> +  EFI_FFS_FILE_HEADER         *FileHeader;
> +  VOID                        *PeCoffImage;
> +  EFI_PHYSICAL_ADDRESS        ImageAddress;
> +  UINT64                      ImageSize;
> +
> +  PayloadFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32
> (PcdPayloadFdMemBase);
> +
> +  //
> +  // DXE FV is inside Payload FV. Here find DXE FV from Payload FV
> +  //
> +  Status = FvFindFile (PayloadFv,
> EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &FileHeader);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Status = FileFindSection (FileHeader,
> EFI_SECTION_FIRMWARE_VOLUME_IMAGE, (VOID **)&DxeCoreFv);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Report DXE FV to DXE core
> +  //
> +  BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) DxeCoreFv, DxeCoreFv-
> >FvLength);
> +
> +  //
> +  // Find DXE core file from DXE FV
> +  //
> +  Status = FvFindFile (DxeCoreFv, EFI_FV_FILETYPE_DXE_CORE, &FileHeader);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = FileFindSection (FileHeader, EFI_SECTION_PE32, (VOID
> **)&PeCoffImage);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Get DXE core info
> +  //
> +  Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize,
> DxeCoreEntryPoint);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  BuildModuleHob (&FileHeader->Name, ImageAddress, EFI_SIZE_TO_PAGES
> ((UINT32) ImageSize) * EFI_PAGE_SIZE, *DxeCoreEntryPoint);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c
> b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c
> new file mode 100644
> index 0000000000..1204573b3e
> --- /dev/null
> +++ b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c
> @@ -0,0 +1,201 @@
> +/** @file
> +
> +
> +  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
> +  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "UefiPayloadEntry.h"
> +
> +/**
> +  Allocates one or more pages of type EfiBootServicesData.
> +
> +  Allocates the number of pages of MemoryType and returns a pointer to the
> +  allocated buffer.  The buffer returned is aligned on a 4KB boundary.
> +  If Pages is 0, then NULL is returned.
> +  If there is not enough memory availble to satisfy the request, then NULL
> +  is returned.
> +
> +  @param   Pages                 The number of 4 KB pages to allocate.
> +  @return  A pointer to the allocated buffer or NULL if allocation fails.
> +**/
> +VOID *
> +EFIAPI
> +AllocatePages (
> +  IN UINTN                                Pages
> +  )
> +{
> +  EFI_PEI_HOB_POINTERS                    Hob;
> +  EFI_PHYSICAL_ADDRESS                    Offset;
> +  EFI_HOB_HANDOFF_INFO_TABLE              *HobTable;
> +
> +  Hob.Raw  = GetHobList ();
> +  HobTable = Hob.HandoffInformationTable;
> +
> +  if (Pages == 0) {
> +    return NULL;
> +  }
> +
> +  // Make sure allocation address is page alligned.
> +  Offset = HobTable->EfiFreeMemoryTop & EFI_PAGE_MASK;
> +  if (Offset != 0) {
> +    HobTable->EfiFreeMemoryTop -= Offset;
> +  }
> +
> +  //
> +  // Check available memory for the allocation
> +  //
> +  if (HobTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof
> (EFI_HOB_MEMORY_ALLOCATION)) < HobTable->EfiFreeMemoryBottom) {
> +    return NULL;
> +  }
> +
> +  HobTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;
> +  BuildMemoryAllocationHob (HobTable->EfiFreeMemoryTop, Pages *
> EFI_PAGE_SIZE, EfiBootServicesData);
> +
> +  return (VOID *)(UINTN)HobTable->EfiFreeMemoryTop;
> +}
> +
> +/**
> +  Frees one or more 4KB pages that were previously allocated with one of the
> page allocation
> +  functions in the Memory Allocation Library.
> +
> +  Frees the number of 4KB pages specified by Pages from the buffer specified
> by Buffer.  Buffer
> +  must have been allocated on a previous call to the page allocation services of
> the Memory
> +  Allocation Library.  If it is not possible to free allocated pages, then this
> function will
> +  perform no actions.
> +
> +  If Buffer was not allocated with a page allocation function in the Memory
> Allocation Library,
> +  then ASSERT().
> +  If Pages is zero, then ASSERT().
> +
> +  @param  Buffer                Pointer to the buffer of pages to free.
> +  @param  Pages                 The number of 4 KB pages to free.
> +
> +**/
> +VOID
> +EFIAPI
> +FreePages (
> +  IN VOID   *Buffer,
> +  IN UINTN  Pages
> +  )
> +{
> +}
> +
> +/**
> +  Allocates one or more pages of type EfiBootServicesData at a specified
> alignment.
> +
> +  Allocates the number of pages specified by Pages of type EfiBootServicesData
> with an
> +  alignment specified by Alignment.
> +  If Pages is 0, then NULL is returned.
> +  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
> +  If there is no enough memory at the specified alignment available to satisfy
> the
> +  request, then NULL is returned.
> +
> +  @param  Pages          The number of 4 KB pages to allocate.
> +  @param  Alignment      The requested alignment of the allocation.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +**/
> +VOID *
> +EFIAPI
> +AllocateAlignedPages (
> +  IN UINTN                    Pages,
> +  IN UINTN                    Alignment
> +  )
> +{
> +  VOID                        *Memory;
> +  UINTN                       AlignmentMask;
> +
> +  //
> +  // Alignment must be a power of two or zero.
> +  //
> +  ASSERT ((Alignment & (Alignment - 1)) == 0);
> +
> +  if (Pages == 0) {
> +    return NULL;
> +  }
> +
> +  //
> +  // Check overflow.
> +  //
> +  ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment)));
> +
> +  Memory = (VOID *)(UINTN)AllocatePages (Pages + EFI_SIZE_TO_PAGES
> (Alignment));
> +  if (Memory == NULL) {
> +    return NULL;
> +  }
> +
> +  if (Alignment == 0) {
> +    AlignmentMask = Alignment;
> +  } else {
> +    AlignmentMask = Alignment - 1;
> +  }
> +
> +  return (VOID *) (UINTN) (((UINTN) Memory + AlignmentMask) &
> ~AlignmentMask);
> +}
> +
> +
> +/**
> +  Allocates a buffer of type EfiBootServicesData.
> +
> +  Allocates the number bytes specified by AllocationSize of type
> EfiBootServicesData and returns a
> +  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0
> size is
> +  returned.  If there is not enough memory remaining to satisfy the request,
> then NULL is returned.
> +
> +  @param  AllocationSize        The number of bytes to allocate.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocatePool (
> +  IN UINTN  AllocationSize
> +  )
> +{
> +  EFI_HOB_MEMORY_POOL      *Hob;
> +
> +  if (AllocationSize > 0x4000) {
> +    // Please use AllocatePages for big allocations
> +    return NULL;
> +  }
> +
> +  Hob = (EFI_HOB_MEMORY_POOL *)CreateHob
> (EFI_HOB_TYPE_MEMORY_POOL, (UINT16)(sizeof
> (EFI_HOB_TYPE_MEMORY_POOL) + AllocationSize));
> +  return (VOID *)(Hob + 1);
> +}
> +
> +/**
> +  Allocates and zeros a buffer of type EfiBootServicesData.
> +
> +  Allocates the number bytes specified by AllocationSize of type
> EfiBootServicesData, clears the
> +  buffer with zeros, and returns a pointer to the allocated buffer.  If
> AllocationSize is 0, then a
> +  valid buffer of 0 size is returned.  If there is not enough memory remaining to
> satisfy the
> +  request, then NULL is returned.
> +
> +  @param  AllocationSize        The number of bytes to allocate and zero.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +EFIAPI
> +AllocateZeroPool (
> +  IN UINTN  AllocationSize
> +  )
> +{
> +  VOID *Buffer;
> +
> +  Buffer = AllocatePool (AllocationSize);
> +  if (Buffer == NULL) {
> +    return NULL;
> +  }
> +
> +  ZeroMem (Buffer, AllocationSize);
> +
> +  return Buffer;
> +}
> +
> +
> diff --git a/UefiPayloadPkg/BlSupportPei/BlSupportPei.c
> b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
> similarity index 52%
> rename from UefiPayloadPkg/BlSupportPei/BlSupportPei.c
> rename to UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
> index a7e99f9ec6..4be2122a4f 100644
> --- a/UefiPayloadPkg/BlSupportPei/BlSupportPei.c
> +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
> @@ -1,144 +1,66 @@
>  /** @file
> -  This PEIM will parse bootloader information and report resource information
> into pei core.
> -  This file contains the main entrypoint of the PEIM.
> 
> -Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> +  Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  **/
> -#include "BlSupportPei.h"
> -
> -#define LEGACY_8259_MASK_REGISTER_MASTER  0x21
> -#define LEGACY_8259_MASK_REGISTER_SLAVE   0xA1
> -
> -EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
> -  { EfiACPIReclaimMemory,   FixedPcdGet32
> (PcdMemoryTypeEfiACPIReclaimMemory) },
> -  { EfiACPIMemoryNVS,       FixedPcdGet32
> (PcdMemoryTypeEfiACPIMemoryNVS) },
> -  { EfiReservedMemoryType,  FixedPcdGet32
> (PcdMemoryTypeEfiReservedMemoryType) },
> -  { EfiRuntimeServicesData, FixedPcdGet32
> (PcdMemoryTypeEfiRuntimeServicesData) },
> -  { EfiRuntimeServicesCode, FixedPcdGet32
> (PcdMemoryTypeEfiRuntimeServicesCode) },
> -  { EfiMaxMemoryType,       0     }
> -};
> -
> -EFI_PEI_PPI_DESCRIPTOR   mPpiBootMode[] = {
> -  {
> -    EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> -    &gEfiPeiMasterBootModePpiGuid,
> -    NULL
> -  }
> -};
> 
> -EFI_PEI_GRAPHICS_DEVICE_INFO_HOB mDefaultGraphicsDeviceInfo = {
> -  MAX_UINT16, MAX_UINT16, MAX_UINT16, MAX_UINT16, MAX_UINT8,
> MAX_UINT8
> -};
> +#include "UefiPayloadEntry.h"
> +
> 
>  /**
> -  Create memory mapped io resource hob.
> +   Transfers control to DxeCore.
> +
> +   This function performs a CPU architecture specific operations to execute
> +   the entry point of DxeCore with the parameters of HobList.
> 
> -  @param  MmioBase    Base address of the memory mapped io range
> -  @param  MmioSize    Length of the memory mapped io range
> +   @param DxeCoreEntryPoint         The entry point of DxeCore.
> +   @param HobList                   The start of HobList passed to DxeCore.
> 
>  **/
>  VOID
> -BuildMemoryMappedIoRangeHob (
> -  EFI_PHYSICAL_ADDRESS        MmioBase,
> -  UINT64                      MmioSize
> -  )
> -{
> -  BuildResourceDescriptorHob (
> -    EFI_RESOURCE_MEMORY_MAPPED_IO,
> -    (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
> -    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> -    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> -    EFI_RESOURCE_ATTRIBUTE_TESTED),
> -    MmioBase,
> -    MmioSize
> -    );
> -
> -  BuildMemoryAllocationHob (
> -    MmioBase,
> -    MmioSize,
> -    EfiMemoryMappedIO
> -    );
> -}
> +HandOffToDxeCore (
> +  IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,
> +  IN EFI_PEI_HOB_POINTERS   HobList
> +  );
> 
> -/**
> -  Check the integrity of firmware volume header
> -
> -  @param[in]  FwVolHeader   A pointer to a firmware volume header
> -
> -  @retval     TRUE          The firmware volume is consistent
> -  @retval     FALSE         The firmware volume has corrupted.
> 
> -**/
> -STATIC
> -BOOLEAN
> -IsFvHeaderValid (
> -  IN EFI_FIRMWARE_VOLUME_HEADER    *FwVolHeader
> +EFI_STATUS
> +MemInfoCallback (
> +  IN MEMROY_MAP_ENTRY          *MemoryMapEntry,
> +  IN VOID                      *Params
>    )
>  {
> -  UINT16 Checksum;
> +  EFI_PHYSICAL_ADDRESS         Base;
> +  EFI_RESOURCE_TYPE            Type;
> +  UINT64                       Size;
> +  EFI_RESOURCE_ATTRIBUTE_TYPE  Attribue;
> 
> -  // Skip nv storage fv
> -  if (CompareMem (&FwVolHeader->FileSystemGuid,
> &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {
> -    return FALSE;
> -  }
> +  Type    = (MemoryMapEntry->Type == 1) ?
> EFI_RESOURCE_SYSTEM_MEMORY : EFI_RESOURCE_MEMORY_RESERVED;
> +  Base    = MemoryMapEntry->Base;
> +  Size    = MemoryMapEntry->Size;
> 
> -  if ( (FwVolHeader->Revision != EFI_FVH_REVISION)   ||
> -     (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
> -     (FwVolHeader->FvLength == ((UINTN) -1))       ||
> -     ((FwVolHeader->HeaderLength & 0x01 ) !=0) )  {
> -    return FALSE;
> -  }
> +  Attribue = 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;
> 
> -  Checksum = CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader-
> >HeaderLength);
> -  if (Checksum != 0) {
> -    DEBUG (( DEBUG_ERROR,
> -              "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x
> to 0x%04x\r\n",
> -              FwVolHeader->Checksum,
> -              (UINT16)( Checksum + FwVolHeader->Checksum )));
> -    return TRUE; //FALSE; Need update UEFI build tool when patching entrypoin
> @start of fd.
> +  if (Base >= BASE_4GB ) {
> +    // Remove tested attribute to avoid DXE core to dispatch driver to memory
> above 4GB
> +    Attribue &= ~EFI_RESOURCE_ATTRIBUTE_TESTED;
>    }
> 
> -  return TRUE;
> -}
> -
> -/**
> -  Install FvInfo PPI and create fv hobs for remained fvs
> +  BuildResourceDescriptorHob (Type, Attribue, (EFI_PHYSICAL_ADDRESS)Base,
> Size);
> +  DEBUG ((DEBUG_INFO , "buildhob: base = 0x%lx, size = 0x%lx, type =
> 0x%x\n", Base, Size, Type));
> 
> -**/
> -VOID
> -PeiReportRemainedFvs (
> -  VOID
> -  )
> -{
> -  UINT8*  TempPtr;
> -  UINT8*  EndPtr;
> -
> -  TempPtr = (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase);
> -  EndPtr = (UINT8* )(UINTN) (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32
> (PcdPayloadFdMemSize));
> -
> -  for (;TempPtr < EndPtr;) {
> -    if (IsFvHeaderValid ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)) {
> -      if (TempPtr != (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase))  {
> -        // Skip the PEI FV
> -        DEBUG((DEBUG_INFO, "Found one valid fv : 0x%lx.\n", TempPtr,
> ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength));
> -
> -        PeiServicesInstallFvInfoPpi (
> -          NULL,
> -          (VOID *) (UINTN) TempPtr,
> -          (UINT32) (UINTN) ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)-
> >FvLength,
> -          NULL,
> -          NULL
> -          );
> -        BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN) TempPtr,
> ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength);
> -      }
> -    }
> -    TempPtr += ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength;
> -  }
> +  return EFI_SUCCESS;
>  }
> 
> 
> +
>  /**
>    Find the board related info from ACPI table
> 
> @@ -299,91 +221,19 @@ Done:
>    return RETURN_SUCCESS;
>  }
> 
> -EFI_STATUS
> -MemInfoCallback (
> -  IN MEMROY_MAP_ENTRY             *MemoryMapEntry,
> -  IN VOID                         *Params
> -  )
> -{
> -  PAYLOAD_MEM_INFO        *MemInfo;
> -  UINTN                   Attribue;
> -  EFI_PHYSICAL_ADDRESS    Base;
> -  EFI_RESOURCE_TYPE       Type;
> -  UINT64                  Size;
> -  UINT32                  SystemLowMemTop;
> -
> -  Attribue = 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;
> -
> -  MemInfo = (PAYLOAD_MEM_INFO *)Params;
> -  Type    = (MemoryMapEntry->Type == 1) ?
> EFI_RESOURCE_SYSTEM_MEMORY : EFI_RESOURCE_MEMORY_RESERVED;
> -  Base    = MemoryMapEntry->Base;
> -  Size    = MemoryMapEntry->Size;
> -
> -  if ((Base  < 0x100000) && ((Base + Size) > 0x100000)) {
> -    Size -= (0x100000 - Base);
> -    Base  = 0x100000;
> -  }
> -
> -  if (Base >= 0x100000) {
> -    if (Type == EFI_RESOURCE_SYSTEM_MEMORY) {
> -      if (Base < 0x100000000ULL) {
> -        MemInfo->UsableLowMemTop = (UINT32)(Base + Size);
> -      } else {
> -        Attribue &= ~EFI_RESOURCE_ATTRIBUTE_TESTED;
> -      }
> -      BuildResourceDescriptorHob (
> -        EFI_RESOURCE_SYSTEM_MEMORY,
> -        Attribue,
> -        (EFI_PHYSICAL_ADDRESS)Base,
> -        Size
> -        );
> -    } else if (Type == EFI_RESOURCE_MEMORY_RESERVED) {
> -      BuildResourceDescriptorHob (
> -        EFI_RESOURCE_MEMORY_RESERVED,
> -        Attribue,
> -        (EFI_PHYSICAL_ADDRESS)Base,
> -        Size
> -        );
> -      if (Base < 0x100000000ULL) {
> -        SystemLowMemTop = ((UINT32)(Base + Size) + 0x0FFFFFFF) &
> 0xF0000000;
> -        if (SystemLowMemTop > MemInfo->SystemLowMemTop) {
> -          MemInfo->SystemLowMemTop = SystemLowMemTop;
> -        }
> -      }
> -    }
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> 
>  /**
> -  This is the entrypoint of PEIM
> -
> -  @param  FileHandle  Handle of the file being invoked.
> -  @param  PeiServices Describes the list of possible PEI Services.
> +  It will build HOBs based on information from bootloaders.
> 
> -  @retval EFI_SUCCESS if it completed successfully.
> +  @retval EFI_SUCCESS        If it completed successfully.
> +  @retval Others             If it failed to build required HOBs.
>  **/
>  EFI_STATUS
> -EFIAPI
> -BlPeiEntryPoint (
> -  IN       EFI_PEI_FILE_HANDLE     FileHandle,
> -  IN CONST EFI_PEI_SERVICES        **PeiServices
> +BuildHobFromBl (
> +  VOID
>    )
>  {
>    EFI_STATUS                       Status;
> -  UINT64                           LowMemorySize;
> -  UINT64                           PeiMemSize = SIZE_64MB;
> -  EFI_PHYSICAL_ADDRESS             PeiMemBase = 0;
> -  UINT32                           RegEax;
> -  UINT8                            PhysicalAddressBits;
> -  PAYLOAD_MEM_INFO                 PldMemInfo;
>    SYSTEM_TABLE_INFO                SysTableInfo;
>    SYSTEM_TABLE_INFO                *NewSysTableInfo;
>    ACPI_BOARD_INFO                  AcpiBoardInfo;
> @@ -393,119 +243,14 @@ BlPeiEntryPoint (
>    EFI_PEI_GRAPHICS_DEVICE_INFO_HOB GfxDeviceInfo;
>    EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *NewGfxDeviceInfo;
> 
> -
> -  //
> -  // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED
> -  // is intentionally omitted to prevent erasing of the coreboot header
> -  // record before it is processed by ParseMemoryInfo.
> -  //
> -  BuildResourceDescriptorHob (
> -    EFI_RESOURCE_SYSTEM_MEMORY,
> -    (
> -    EFI_RESOURCE_ATTRIBUTE_PRESENT |
> -    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> -    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> -    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> -    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> -    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
> -    ),
> -    (EFI_PHYSICAL_ADDRESS)(0),
> -    (UINT64)(0xA0000)
> -    );
> -
> -  BuildResourceDescriptorHob (
> -    EFI_RESOURCE_MEMORY_RESERVED,
> -    (
> -    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
> -    ),
> -    (EFI_PHYSICAL_ADDRESS)(0xA0000),
> -    (UINT64)(0x60000)
> -    );
> -
> -
>    //
> -  // Parse memory info
> +  // Parse memory info and build memory HOBs
>    //
> -  ZeroMem (&PldMemInfo, sizeof(PldMemInfo));
> -  Status = ParseMemoryInfo (MemInfoCallback, &PldMemInfo);
> +  Status = ParseMemoryInfo (MemInfoCallback, NULL);
>    if (EFI_ERROR(Status)) {
>      return Status;
>    }
> 
> -  //
> -  // Install memory
> -  //
> -  LowMemorySize = PldMemInfo.UsableLowMemTop;
> -  PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));
> -  DEBUG ((DEBUG_INFO, "Low memory 0x%lx\n", LowMemorySize));
> -  DEBUG ((DEBUG_INFO, "SystemLowMemTop 0x%x\n",
> PldMemInfo.SystemLowMemTop));
> -  DEBUG ((DEBUG_INFO, "PeiMemBase: 0x%lx.\n", PeiMemBase));
> -  DEBUG ((DEBUG_INFO, "PeiMemSize: 0x%lx.\n", PeiMemSize));
> -  Status = PeiServicesInstallPeiMemory (PeiMemBase, PeiMemSize);
> -  ASSERT_EFI_ERROR (Status);
> -
> -  //
> -  // Set cache on the physical memory
> -  //
> -  MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB,
> CacheWriteBack);
> -  MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);
> -
> -  //
> -  // Create Memory Type Information HOB
> -  //
> -  BuildGuidDataHob (
> -    &gEfiMemoryTypeInformationGuid,
> -    mDefaultMemoryTypeInformation,
> -    sizeof(mDefaultMemoryTypeInformation)
> -    );
> -
> -  //
> -  // Create Fv hob
> -  //
> -  PeiReportRemainedFvs ();
> -
> -  BuildMemoryAllocationHob (
> -    PcdGet32 (PcdPayloadFdMemBase),
> -    PcdGet32 (PcdPayloadFdMemSize),
> -    EfiBootServicesData
> -    );
> -
> -  //
> -  // Build CPU memory space and IO space hob
> -  //
> -  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
> -  if (RegEax >= 0x80000008) {
> -    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
> -    PhysicalAddressBits = (UINT8) RegEax;
> -  } else {
> -    PhysicalAddressBits  = 36;
> -  }
> -
> -  //
> -  // Create a CPU hand-off information
> -  //
> -  BuildCpuHob (PhysicalAddressBits, 16);
> -
> -  //
> -  // Report Local APIC range
> -  //
> -  BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);
> -
> -  //
> -  // Boot mode
> -  //
> -  Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
> -  ASSERT_EFI_ERROR (Status);
> -
> -  Status = PeiServicesInstallPpi (mPpiBootMode);
> -  ASSERT_EFI_ERROR (Status);
> -
>    //
>    // Create guid hob for frame buffer information
>    //
> @@ -561,12 +306,109 @@ BlPeiEntryPoint (
>      return Status;
>    }
> 
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This function will build some generic HOBs that doesn't depend on
> information from bootloaders.
> +
> +**/
> +VOID
> +BuildGenericHob (
> +  VOID
> +  )
> +{
> +  UINT32                           RegEax;
> +  UINT8                            PhysicalAddressBits;
> +  EFI_RESOURCE_ATTRIBUTE_TYPE      ResourceAttribute;
> +
> +  // The UEFI payload FV
> +  BuildMemoryAllocationHob (PcdGet32 (PcdPayloadFdMemBase), PcdGet32
> (PcdPayloadFdMemSize), EfiBootServicesData);
> +
> +  //
> +  // Build CPU memory space and IO space hob
> +  //
> +  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
> +  if (RegEax >= 0x80000008) {
> +    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
> +    PhysicalAddressBits = (UINT8) RegEax;
> +  } else {
> +    PhysicalAddressBits  = 36;
> +  }
> +
> +  BuildCpuHob (PhysicalAddressBits, 16);
> +
> +  //
> +  // Report Local APIC range, cause sbl HOB to be NULL, comment now
> +  //
> +  ResourceAttribute = (
> +      EFI_RESOURCE_ATTRIBUTE_PRESENT |
> +      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_TESTED
> +  );
> +  BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_MAPPED_IO,
> ResourceAttribute, 0xFEC80000, SIZE_512KB);
> +  BuildMemoryAllocationHob ( 0xFEC80000, SIZE_512KB,
> EfiMemoryMappedIO);
> +
> +}
> +
> +
> +/**
> +  Entry point to the C language phase of UEFI payload.
> +
> +  @retval      It will not return if SUCCESS, and return error when passing
> bootloader parameter.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PayloadEntry (
> +  IN UINTN                     BootloaderParameter
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  PHYSICAL_ADDRESS              DxeCoreEntryPoint;
> +  EFI_HOB_HANDOFF_INFO_TABLE    *HandoffHobTable;
> +  UINTN                         HobMemBase;
> +  UINTN                         HobMemSize;
> +  EFI_PEI_HOB_POINTERS          Hob;
> +
> +  DEBUG ((DEBUG_INFO, "GET_BOOTLOADER_PARAMETER() = 0x%lx\n",
> GET_BOOTLOADER_PARAMETER()));
> +  DEBUG ((DEBUG_INFO, "sizeof(UINTN) = 0x%x\n", sizeof(UINTN)));
> +
> +  // Initialize floating point operating environment to be compliant with UEFI
> spec.
> +  InitializeFloatingPointUnits ();
> +
> +  // Init the region for HOB and memory allocation for this module
> +  HobMemBase      = ALIGN_VALUE (PcdGet32 (PcdPayloadFdMemBase) +
> PcdGet32 (PcdPayloadFdMemSize), SIZE_1MB);
> +  HobMemSize      = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
> +  HandoffHobTable = HobConstructor ((VOID *)HobMemBase, HobMemSize,
> (VOID *)HobMemBase, (VOID *)(HobMemBase + HobMemSize));
> +
> +  // Build HOB based on information from Bootloader
> +  Status = BuildHobFromBl ();
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "BuildHobFromBl Status = %r\n", Status));
> +    return Status;
> +  }
> +
> +  // Build other HOBs required by DXE
> +  BuildGenericHob ();
> +
> +  // Load the DXE Core
> +  Status = LoadDxeCore (&DxeCoreEntryPoint);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG ((DEBUG_INFO, "DxeCoreEntryPoint = 0x%lx\n", DxeCoreEntryPoint));
> +
>    //
>    // Mask off all legacy 8259 interrupt sources
>    //
>    IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
>    IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE,  0xFF);
> 
> +  Hob.HandoffInformationTable = HandoffHobTable;
> +  HandOffToDxeCore (DxeCoreEntryPoint, Hob);
> +
> +  // Should not get here
> +  CpuDeadLoop ();
>    return EFI_SUCCESS;
>  }
> -
> diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
> b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
> new file mode 100644
> index 0000000000..6ae111fa00
> --- /dev/null
> +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
> @@ -0,0 +1,85 @@
> +/** @file
> +*
> +* Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> +*
> +*  SPDX-License-Identifier: BSD-2-Clause-Patent
> +*
> +**/
> +
> +#ifndef __UEFI_PAYLOAD_ENTRY_H__
> +#define __UEFI_PAYLOAD_ENTRY_H__
> +
> +#include <PiPei.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PeCoffLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +#include <Guid/MemoryAllocationHob.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeCoffLib.h>
> +#include <Library/BlParseLib.h>
> +#include <Library/PlatformSupportLib.h>
> +#include <Library/UefiCpuLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include
> <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
> +#include <Guid/SerialPortInfoGuid.h>
> +#include <Guid/SystemTableInfoGuid.h>
> +#include <Guid/MemoryMapInfoGuid.h>
> +#include <Guid/AcpiBoardInfoGuid.h>
> +#include <Guid/GraphicsInfoHob.h>
> +
> +
> +#define LEGACY_8259_MASK_REGISTER_MASTER  0x21
> +#define LEGACY_8259_MASK_REGISTER_SLAVE   0xA1
> +#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
> +  ((ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) &
> ((Alignment) - 1)))
> +
> +VOID *
> +EFIAPI
> +CreateHob (
> +  IN  UINT16    HobType,
> +  IN  UINT16    HobLength
> +  );
> +
> +/**
> +  Update the Stack Hob if the stack has been moved
> +
> +  @param  BaseAddress   The 64 bit physical address of the Stack.
> +  @param  Length        The length of the stack in bytes.
> +
> +**/
> +VOID
> +EFIAPI
> +UpdateStackHob (
> +  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
> +  IN UINT64                      Length
> +  );
> +
> +EFI_HOB_HANDOFF_INFO_TABLE*
> +EFIAPI
> +HobConstructor (
> +  IN VOID   *EfiMemoryBegin,
> +  IN UINTN  EfiMemoryLength,
> +  IN VOID   *EfiFreeMemoryBottom,
> +  IN VOID   *EfiFreeMemoryTop
> +  );
> +
> +/**
> +  Find DXE core from FV and build DXE core HOBs.
> +
> +  @param[out]  DxeCoreEntryPoint     DXE core entry point
> +
> +  @retval EFI_SUCCESS        If it completed successfully.
> +  @retval EFI_NOT_FOUND      If it failed to load DXE FV.
> +**/
> +EFI_STATUS
> +LoadDxeCore (
> +  OUT PHYSICAL_ADDRESS        *DxeCoreEntryPoint
> +  );
> +
> +
> +#endif
> diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
> b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
> new file mode 100644
> index 0000000000..6718d53b68
> --- /dev/null
> +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
> @@ -0,0 +1,91 @@
> +## @file
> +#  This is the first module for UEFI payload.
> +#
> +#  Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = PayloadEntry
> +  FILE_GUID                      = 2119BBD7-9432-4f47-B5E2-5C4EA31B6BDC
> +  MODULE_TYPE                    = SEC
> +  VERSION_STRING                 = 1.0
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  UefiPayloadEntry.c
> +  LoadDxeCore.c
> +  MemoryAllocation.c
> +
> +[Sources.Ia32]
> +  X64/VirtualMemory.h
> +  X64/VirtualMemory.c
> +  Ia32/DxeLoadFunc.c
> +  Ia32/IdtVectorAsm.nasm
> +  Ia32/SecEntry.nasm
> +
> +[Sources.X64]
> +  X64/VirtualMemory.h
> +  X64/VirtualMemory.c
> +  X64/DxeLoadFunc.c
> +  X64/SecEntry.nasm
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  UefiPayloadPkg/UefiPayloadPkg.dec
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  BaseLib
> +  SerialPortLib
> +  IoLib
> +  BlParseLib
> +  HobLib
> +  PeCoffLib
> +  PlatformSupportLib
> +  UefiCpuLib
> +
> +[Guids]
> +  gEfiMemoryTypeInformationGuid
> +  gEfiFirmwareFileSystem2Guid
> +  gUefiSystemTableInfoGuid
> +  gEfiGraphicsInfoHobGuid
> +  gEfiGraphicsDeviceInfoHobGuid
> +  gUefiAcpiBoardInfoGuid
> +
> +[FeaturePcd.IA32]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode      ##
> CONSUMES
> +
> +[FeaturePcd.X64]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables       ##
> CONSUMES
> +
> +
> +[Pcd.IA32,Pcd.X64]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable                      ##
> SOMETIMES_CONSUMES
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask
> ## CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask
> ## CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ##
> CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ##
> CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable                  ##
> SOMETIMES_CONSUMES
> +
> +  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
> +  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
> +  gUefiPayloadPkgTokenSpaceGuid.PcdPayloadStackTop
> +  gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack               ##
> SOMETIMES_CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ##
> SOMETIMES_CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy       ##
> SOMETIMES_CONSUMES
> +
> diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
> b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
> new file mode 100644
> index 0000000000..d2d339d514
> --- /dev/null
> +++ b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
> @@ -0,0 +1,98 @@
> +/** @file
> +  x64-specifc functionality for DxeLoad.
> +
> +Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/HobLib.h>
> +#include "X64/VirtualMemory.h"
> +#include "UefiPayloadEntry.h"
> +#define STACK_SIZE            0x20000
> +
> +
> +/**
> +   Transfers control to DxeCore.
> +
> +   This function performs a CPU architecture specific operations to execute
> +   the entry point of DxeCore with the parameters of HobList.
> +   It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.
> +
> +   @param DxeCoreEntryPoint         The entry point of DxeCore.
> +   @param HobList                   The start of HobList passed to DxeCore.
> +
> +**/
> +VOID
> +HandOffToDxeCore (
> +  IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,
> +  IN EFI_PEI_HOB_POINTERS   HobList
> +  )
> +{
> +  VOID                            *BaseOfStack;
> +  VOID                            *TopOfStack;
> +  UINTN                           PageTables;
> +
> +  //
> +  // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
> +  //
> +  if (IsNullDetectionEnabled ()) {
> +    ClearFirst4KPage (HobList.Raw);
> +    BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1),
> EfiBootServicesData);
> +  }
> +
> +
> +  //
> +  // Allocate 128KB for the Stack
> +  //
> +  BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
> +  ASSERT (BaseOfStack != NULL);
> +
> +  //
> +  // Compute the top of the stack we were allocated. Pre-allocate a UINTN
> +  // for safety.
> +  //
> +  TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES
> (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
> +  TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
> +
> +  PageTables = 0;
> +  if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
> +    //
> +    // Create page table and save PageMapLevel4 to CR3
> +    //
> +    PageTables = CreateIdentityMappingPageTables ((EFI_PHYSICAL_ADDRESS)
> (UINTN) BaseOfStack, STACK_SIZE);
> +  } else {
> +    //
> +    // Set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE
> +    // for the DxeIpl and the DxeCore are both X64.
> +    //
> +    ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE);
> +    ASSERT (PcdGetBool (PcdCpuStackGuard) == FALSE);
> +  }
> +
> +
> +  if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
> +    AsmWriteCr3 (PageTables);
> +  }
> +
> +  //
> +  // Update the contents of BSP stack HOB to reflect the real stack info passed
> to DxeCore.
> +  //
> +  UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack,
> STACK_SIZE);
> +
> +  //
> +  // Transfer the control to the entry point of DxeCore.
> +  //
> +  SwitchStack (
> +    (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
> +    HobList.Raw,
> +    NULL,
> +    TopOfStack
> +    );
> +}
> diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/SecEntry.nasm
> b/UefiPayloadPkg/UefiPayloadEntry/X64/SecEntry.nasm
> new file mode 100644
> index 0000000000..974cf77771
> --- /dev/null
> +++ b/UefiPayloadPkg/UefiPayloadEntry/X64/SecEntry.nasm
> @@ -0,0 +1,47 @@
> +;------------------------------------------------------------------------------
> +;*
> +;*   Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
> +;*   SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +;------------------------------------------------------------------------------
> +
> +#include <Base.h>
> +
> +DEFAULT REL
> +SECTION .text
> +
> +extern ASM_PFX(PayloadEntry)
> +extern  ASM_PFX(PcdGet32 (PcdPayloadStackTop))
> +
> +;
> +; SecCore Entry Point
> +;
> +; Processor is in flat protected mode
> +
> +global ASM_PFX(_ModuleEntryPoint)
> +ASM_PFX(_ModuleEntryPoint):
> +
> +  ;
> +  ; Disable all the interrupts
> +  ;
> +  cli
> +
> +
> +  mov   rsp, FixedPcdGet32 (PcdPayloadStackTop)
> +
> +  ;
> +  ; Push the bootloader parameter address onto new stack
> +  ;
> +  push  rcx
> +  mov   rax, 0
> +  push  rax ; shadow space
> +  push  rax
> +  push  rax
> +  push  rax
> +
> +  ;
> +  ; Call into C code
> +  ;
> +  call  ASM_PFX(PayloadEntry)
> +  jmp   $
> +
> diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c
> b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c
> new file mode 100644
> index 0000000000..329274b1b6
> --- /dev/null
> +++ b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c
> @@ -0,0 +1,904 @@
> +/** @file
> +  x64 Virtual Memory Management Services in the form of an IA-32 driver.
> +  Used to establish a 1:1 Virtual to Physical Mapping that is required to
> +  enter Long Mode (x64 64-bit mode).
> +
> +  While we make a 1:1 mapping (identity mapping) for all physical pages
> +  we still need to use the MTRR's to ensure that the cachability attributes
> +  for all memory regions is correct.
> +
> +  The basic idea is to use 2MB page table entries where ever possible. If
> +  more granularity of cachability is required then 4K page tables are used.
> +
> +  References:
> +    1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic
> Architecture, Intel
> +    2) IA-32 Intel(R) Architecture Software Developer's Manual Volume
> 2:Instruction Set Reference, Intel
> +    3) IA-32 Intel(R) Architecture Software Developer's Manual Volume
> 3:System Programmer's Guide, Intel
> +
> +Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/HobLib.h>
> +#include <Register/Intel/Cpuid.h>
> +#include "VirtualMemory.h"
> +
> +//
> +// Global variable to keep track current available memory used as page table.
> +//
> +PAGE_TABLE_POOL   *mPageTablePool = NULL;
> +
> +/**
> +  Clear legacy memory located at the first 4K-page, if available.
> +
> +  This function traverses the whole HOB list to check if memory from 0 to 4095
> +  exists and has not been allocated, and then clear it if so.
> +
> +  @param HobStart                  The start of HobList passed to DxeCore.
> +
> +**/
> +VOID
> +ClearFirst4KPage (
> +  IN  VOID *HobStart
> +  )
> +{
> +  EFI_PEI_HOB_POINTERS          RscHob;
> +  EFI_PEI_HOB_POINTERS          MemHob;
> +  BOOLEAN                       DoClear;
> +
> +  RscHob.Raw = HobStart;
> +  MemHob.Raw = HobStart;
> +  DoClear = FALSE;
> +
> +  //
> +  // Check if page 0 exists and free
> +  //
> +  while ((RscHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
> +                                   RscHob.Raw)) != NULL) {
> +    if (RscHob.ResourceDescriptor->ResourceType ==
> EFI_RESOURCE_SYSTEM_MEMORY &&
> +        RscHob.ResourceDescriptor->PhysicalStart == 0) {
> +      DoClear = TRUE;
> +      //
> +      // Make sure memory at 0-4095 has not been allocated.
> +      //
> +      while ((MemHob.Raw = GetNextHob
> (EFI_HOB_TYPE_MEMORY_ALLOCATION,
> +                                       MemHob.Raw)) != NULL) {
> +        if (MemHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress
> +            < EFI_PAGE_SIZE) {
> +          DoClear = FALSE;
> +          break;
> +        }
> +        MemHob.Raw = GET_NEXT_HOB (MemHob);
> +      }
> +      break;
> +    }
> +    RscHob.Raw = GET_NEXT_HOB (RscHob);
> +  }
> +
> +  if (DoClear) {
> +    DEBUG ((DEBUG_INFO, "Clearing first 4K-page!\r\n"));
> +    SetMem (NULL, EFI_PAGE_SIZE, 0);
> +  }
> +
> +  return;
> +}
> +
> +/**
> +  Return configure status of NULL pointer detection feature.
> +
> +  @return TRUE   NULL pointer detection feature is enabled
> +  @return FALSE  NULL pointer detection feature is disabled
> +
> +**/
> +BOOLEAN
> +IsNullDetectionEnabled (
> +  VOID
> +  )
> +{
> +  return ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) != 0);
> +}
> +
> +/**
> +  The function will check if Execute Disable Bit is available.
> +
> +  @retval TRUE      Execute Disable Bit is available.
> +  @retval FALSE     Execute Disable Bit is not available.
> +
> +**/
> +BOOLEAN
> +IsExecuteDisableBitAvailable (
> +  VOID
> +  )
> +{
> +  UINT32            RegEax;
> +  UINT32            RegEdx;
> +  BOOLEAN           Available;
> +
> +  Available = FALSE;
> +  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
> +  if (RegEax >= 0x80000001) {
> +    AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
> +    if ((RegEdx & BIT20) != 0) {
> +      //
> +      // Bit 20: Execute Disable Bit available.
> +      //
> +      Available = TRUE;
> +    }
> +  }
> +
> +  return Available;
> +}
> +
> +/**
> +  Check if Execute Disable Bit (IA32_EFER.NXE) should be enabled or not.
> +
> +  @retval TRUE    IA32_EFER.NXE should be enabled.
> +  @retval FALSE   IA32_EFER.NXE should not be enabled.
> +
> +**/
> +BOOLEAN
> +IsEnableNonExecNeeded (
> +  VOID
> +  )
> +{
> +  if (!IsExecuteDisableBitAvailable ()) {
> +    return FALSE;
> +  }
> +
> +  //
> +  // XD flag (BIT63) in page table entry is only valid if IA32_EFER.NXE is set.
> +  // Features controlled by Following PCDs need this feature to be enabled.
> +  //
> +  return (PcdGetBool (PcdSetNxForStack) ||
> +          PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0 ||
> +          PcdGet32 (PcdImageProtectionPolicy) != 0);
> +}
> +
> +/**
> +  Enable Execute Disable Bit.
> +
> +**/
> +VOID
> +EnableExecuteDisableBit (
> +  VOID
> +  )
> +{
> +  UINT64           MsrRegisters;
> +
> +  MsrRegisters = AsmReadMsr64 (0xC0000080);
> +  MsrRegisters |= BIT11;
> +  AsmWriteMsr64 (0xC0000080, MsrRegisters);
> +}
> +
> +/**
> +  The function will check if page table entry should be splitted to smaller
> +  granularity.
> +
> +  @param Address      Physical memory address.
> +  @param Size         Size of the given physical memory.
> +  @param StackBase    Base address of stack.
> +  @param StackSize    Size of stack.
> +
> +  @retval TRUE      Page table should be split.
> +  @retval FALSE     Page table should not be split.
> +**/
> +BOOLEAN
> +ToSplitPageTable (
> +  IN EFI_PHYSICAL_ADDRESS               Address,
> +  IN UINTN                              Size,
> +  IN EFI_PHYSICAL_ADDRESS               StackBase,
> +  IN UINTN                              StackSize
> +  )
> +{
> +  if (IsNullDetectionEnabled () && Address == 0) {
> +    return TRUE;
> +  }
> +
> +  if (PcdGetBool (PcdCpuStackGuard)) {
> +    if (StackBase >= Address && StackBase < (Address + Size)) {
> +      return TRUE;
> +    }
> +  }
> +
> +  if (PcdGetBool (PcdSetNxForStack)) {
> +    if ((Address < StackBase + StackSize) && ((Address + Size) > StackBase)) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +/**
> +  Initialize a buffer pool for page table use only.
> +
> +  To reduce the potential split operation on page table, the pages reserved for
> +  page table should be allocated in the times of
> PAGE_TABLE_POOL_UNIT_PAGES and
> +  at the boundary of PAGE_TABLE_POOL_ALIGNMENT. So the page pool is
> always
> +  initialized with number of pages greater than or equal to the given PoolPages.
> +
> +  Once the pages in the pool are used up, this method should be called again to
> +  reserve at least another PAGE_TABLE_POOL_UNIT_PAGES. But usually this
> won't
> +  happen in practice.
> +
> +  @param PoolPages  The least page number of the pool to be created.
> +
> +  @retval TRUE    The pool is initialized successfully.
> +  @retval FALSE   The memory is out of resource.
> +**/
> +BOOLEAN
> +InitializePageTablePool (
> +  IN UINTN           PoolPages
> +  )
> +{
> +  VOID          *Buffer;
> +
> +  //
> +  // Always reserve at least PAGE_TABLE_POOL_UNIT_PAGES, including one
> page for
> +  // header.
> +  //
> +  PoolPages += 1;   // Add one page for header.
> +  PoolPages = ((PoolPages - 1) / PAGE_TABLE_POOL_UNIT_PAGES + 1) *
> +              PAGE_TABLE_POOL_UNIT_PAGES;
> +  Buffer = AllocateAlignedPages (PoolPages, PAGE_TABLE_POOL_ALIGNMENT);
> +  if (Buffer == NULL) {
> +    DEBUG ((DEBUG_ERROR, "ERROR: Out of aligned pages\r\n"));
> +    return FALSE;
> +  }
> +
> +  //
> +  // Link all pools into a list for easier track later.
> +  //
> +  if (mPageTablePool == NULL) {
> +    mPageTablePool = Buffer;
> +    mPageTablePool->NextPool = mPageTablePool;
> +  } else {
> +    ((PAGE_TABLE_POOL *)Buffer)->NextPool = mPageTablePool->NextPool;
> +    mPageTablePool->NextPool = Buffer;
> +    mPageTablePool = Buffer;
> +  }
> +
> +  //
> +  // Reserve one page for pool header.
> +  //
> +  mPageTablePool->FreePages  = PoolPages - 1;
> +  mPageTablePool->Offset = EFI_PAGES_TO_SIZE (1);
> +
> +  return TRUE;
> +}
> +
> +/**
> +  This API provides a way to allocate memory for page table.
> +
> +  This API can be called more than once to allocate memory for page tables.
> +
> +  Allocates the number of 4KB pages and returns a pointer to the allocated
> +  buffer. The buffer returned is aligned on a 4KB boundary.
> +
> +  If Pages is 0, then NULL is returned.
> +  If there is not enough memory remaining to satisfy the request, then NULL is
> +  returned.
> +
> +  @param  Pages                 The number of 4 KB pages to allocate.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +AllocatePageTableMemory (
> +  IN UINTN           Pages
> +  )
> +{
> +  VOID          *Buffer;
> +
> +  if (Pages == 0) {
> +    return NULL;
> +  }
> +
> +  //
> +  // Renew the pool if necessary.
> +  //
> +  if (mPageTablePool == NULL ||
> +      Pages > mPageTablePool->FreePages) {
> +    if (!InitializePageTablePool (Pages)) {
> +      return NULL;
> +    }
> +  }
> +
> +  Buffer = (UINT8 *)mPageTablePool + mPageTablePool->Offset;
> +
> +  mPageTablePool->Offset     += EFI_PAGES_TO_SIZE (Pages);
> +  mPageTablePool->FreePages  -= Pages;
> +
> +  return Buffer;
> +}
> +
> +/**
> +  Split 2M page to 4K.
> +
> +  @param[in]      PhysicalAddress       Start physical address the 2M page
> covered.
> +  @param[in, out] PageEntry2M           Pointer to 2M page entry.
> +  @param[in]      StackBase             Stack base address.
> +  @param[in]      StackSize             Stack size.
> +
> +**/
> +VOID
> +Split2MPageTo4K (
> +  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
> +  IN OUT UINT64                         *PageEntry2M,
> +  IN EFI_PHYSICAL_ADDRESS               StackBase,
> +  IN UINTN                              StackSize
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS                  PhysicalAddress4K;
> +  UINTN                                 IndexOfPageTableEntries;
> +  PAGE_TABLE_4K_ENTRY                   *PageTableEntry;
> +  UINT64                                AddressEncMask;
> +
> +  //
> +  // Make sure AddressEncMask is contained to smallest supported address field
> +  //
> +  AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &
> PAGING_1G_ADDRESS_MASK_64;
> +
> +  PageTableEntry = AllocatePageTableMemory (1);
> +  ASSERT (PageTableEntry != NULL);
> +
> +  //
> +  // Fill in 2M page entry.
> +  //
> +  *PageEntry2M = (UINT64) (UINTN) PageTableEntry | AddressEncMask |
> IA32_PG_P | IA32_PG_RW;
> +
> +  PhysicalAddress4K = PhysicalAddress;
> +  for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512;
> IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB)
> {
> +    //
> +    // Fill in the Page Table entries
> +    //
> +    PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask;
> +    PageTableEntry->Bits.ReadWrite = 1;
> +
> +    if ((IsNullDetectionEnabled () && PhysicalAddress4K == 0) ||
> +        (PcdGetBool (PcdCpuStackGuard) && PhysicalAddress4K == StackBase)) {
> +      PageTableEntry->Bits.Present = 0;
> +    } else {
> +      PageTableEntry->Bits.Present = 1;
> +    }
> +
> +    if (PcdGetBool (PcdSetNxForStack)
> +        && (PhysicalAddress4K >= StackBase)
> +        && (PhysicalAddress4K < StackBase + StackSize)) {
> +      //
> +      // Set Nx bit for stack.
> +      //
> +      PageTableEntry->Bits.Nx = 1;
> +    }
> +  }
> +}
> +
> +/**
> +  Split 1G page to 2M.
> +
> +  @param[in]      PhysicalAddress       Start physical address the 1G page covered.
> +  @param[in, out] PageEntry1G           Pointer to 1G page entry.
> +  @param[in]      StackBase             Stack base address.
> +  @param[in]      StackSize             Stack size.
> +
> +**/
> +VOID
> +Split1GPageTo2M (
> +  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
> +  IN OUT UINT64                         *PageEntry1G,
> +  IN EFI_PHYSICAL_ADDRESS               StackBase,
> +  IN UINTN                              StackSize
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS                  PhysicalAddress2M;
> +  UINTN                                 IndexOfPageDirectoryEntries;
> +  PAGE_TABLE_ENTRY                      *PageDirectoryEntry;
> +  UINT64                                AddressEncMask;
> +
> +  //
> +  // Make sure AddressEncMask is contained to smallest supported address field
> +  //
> +  AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &
> PAGING_1G_ADDRESS_MASK_64;
> +
> +  PageDirectoryEntry = AllocatePageTableMemory (1);
> +  ASSERT (PageDirectoryEntry != NULL);
> +
> +  //
> +  // Fill in 1G page entry.
> +  //
> +  *PageEntry1G = (UINT64) (UINTN) PageDirectoryEntry | AddressEncMask |
> IA32_PG_P | IA32_PG_RW;
> +
> +  PhysicalAddress2M = PhysicalAddress;
> +  for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512;
> IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M +=
> SIZE_2MB) {
> +    if (ToSplitPageTable (PhysicalAddress2M, SIZE_2MB, StackBase, StackSize)) {
> +      //
> +      // Need to split this 2M page that covers NULL or stack range.
> +      //
> +      Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry,
> StackBase, StackSize);
> +    } else {
> +      //
> +      // Fill in the Page Directory entries
> +      //
> +      PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress2M |
> AddressEncMask;
> +      PageDirectoryEntry->Bits.ReadWrite = 1;
> +      PageDirectoryEntry->Bits.Present = 1;
> +      PageDirectoryEntry->Bits.MustBe1 = 1;
> +    }
> +  }
> +}
> +
> +/**
> +  Set one page of page table pool memory to be read-only.
> +
> +  @param[in] PageTableBase    Base address of page table (CR3).
> +  @param[in] Address          Start address of a page to be set as read-only.
> +  @param[in] Level4Paging     Level 4 paging flag.
> +
> +**/
> +VOID
> +SetPageTablePoolReadOnly (
> +  IN  UINTN                             PageTableBase,
> +  IN  EFI_PHYSICAL_ADDRESS              Address,
> +  IN  BOOLEAN                           Level4Paging
> +  )
> +{
> +  UINTN                 Index;
> +  UINTN                 EntryIndex;
> +  UINT64                AddressEncMask;
> +  EFI_PHYSICAL_ADDRESS  PhysicalAddress;
> +  UINT64                *PageTable;
> +  UINT64                *NewPageTable;
> +  UINT64                PageAttr;
> +  UINT64                LevelSize[5];
> +  UINT64                LevelMask[5];
> +  UINTN                 LevelShift[5];
> +  UINTN                 Level;
> +  UINT64                PoolUnitSize;
> +
> +  ASSERT (PageTableBase != 0);
> +
> +  //
> +  // Since the page table is always from page table pool, which is always
> +  // located at the boundary of PcdPageTablePoolAlignment, we just need to
> +  // set the whole pool unit to be read-only.
> +  //
> +  Address = Address & PAGE_TABLE_POOL_ALIGN_MASK;
> +
> +  LevelShift[1] = PAGING_L1_ADDRESS_SHIFT;
> +  LevelShift[2] = PAGING_L2_ADDRESS_SHIFT;
> +  LevelShift[3] = PAGING_L3_ADDRESS_SHIFT;
> +  LevelShift[4] = PAGING_L4_ADDRESS_SHIFT;
> +
> +  LevelMask[1] = PAGING_4K_ADDRESS_MASK_64;
> +  LevelMask[2] = PAGING_2M_ADDRESS_MASK_64;
> +  LevelMask[3] = PAGING_1G_ADDRESS_MASK_64;
> +  LevelMask[4] = PAGING_1G_ADDRESS_MASK_64;
> +
> +  LevelSize[1] = SIZE_4KB;
> +  LevelSize[2] = SIZE_2MB;
> +  LevelSize[3] = SIZE_1GB;
> +  LevelSize[4] = SIZE_512GB;
> +
> +  AddressEncMask  = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &
> +                    PAGING_1G_ADDRESS_MASK_64;
> +  PageTable       = (UINT64 *)(UINTN)PageTableBase;
> +  PoolUnitSize    = PAGE_TABLE_POOL_UNIT_SIZE;
> +
> +  for (Level = (Level4Paging) ? 4 : 3; Level > 0; --Level) {
> +    Index = ((UINTN)RShiftU64 (Address, LevelShift[Level]));
> +    Index &= PAGING_PAE_INDEX_MASK;
> +
> +    PageAttr = PageTable[Index];
> +    if ((PageAttr & IA32_PG_PS) == 0) {
> +      //
> +      // Go to next level of table.
> +      //
> +      PageTable = (UINT64 *)(UINTN)(PageAttr & ~AddressEncMask &
> +                                    PAGING_4K_ADDRESS_MASK_64);
> +      continue;
> +    }
> +
> +    if (PoolUnitSize >= LevelSize[Level]) {
> +      //
> +      // Clear R/W bit if current page granularity is not larger than pool unit
> +      // size.
> +      //
> +      if ((PageAttr & IA32_PG_RW) != 0) {
> +        while (PoolUnitSize > 0) {
> +          //
> +          // PAGE_TABLE_POOL_UNIT_SIZE and PAGE_TABLE_POOL_ALIGNMENT
> are fit in
> +          // one page (2MB). Then we don't need to update attributes for pages
> +          // crossing page directory. ASSERT below is for that purpose.
> +          //
> +          ASSERT (Index < EFI_PAGE_SIZE/sizeof (UINT64));
> +
> +          PageTable[Index] &= ~(UINT64)IA32_PG_RW;
> +          PoolUnitSize    -= LevelSize[Level];
> +
> +          ++Index;
> +        }
> +      }
> +
> +      break;
> +
> +    } else {
> +      //
> +      // The smaller granularity of page must be needed.
> +      //
> +      ASSERT (Level > 1);
> +
> +      NewPageTable = AllocatePageTableMemory (1);
> +      ASSERT (NewPageTable != NULL);
> +
> +      PhysicalAddress = PageAttr & LevelMask[Level];
> +      for (EntryIndex = 0;
> +            EntryIndex < EFI_PAGE_SIZE/sizeof (UINT64);
> +            ++EntryIndex) {
> +        NewPageTable[EntryIndex] = PhysicalAddress  | AddressEncMask |
> +                                   IA32_PG_P | IA32_PG_RW;
> +        if (Level > 2) {
> +          NewPageTable[EntryIndex] |= IA32_PG_PS;
> +        }
> +        PhysicalAddress += LevelSize[Level - 1];
> +      }
> +
> +      PageTable[Index] = (UINT64)(UINTN)NewPageTable | AddressEncMask |
> +                                        IA32_PG_P | IA32_PG_RW;
> +      PageTable = NewPageTable;
> +    }
> +  }
> +}
> +
> +/**
> +  Prevent the memory pages used for page table from been overwritten.
> +
> +  @param[in] PageTableBase    Base address of page table (CR3).
> +  @param[in] Level4Paging     Level 4 paging flag.
> +
> +**/
> +VOID
> +EnablePageTableProtection (
> +  IN  UINTN     PageTableBase,
> +  IN  BOOLEAN   Level4Paging
> +  )
> +{
> +  PAGE_TABLE_POOL         *HeadPool;
> +  PAGE_TABLE_POOL         *Pool;
> +  UINT64                  PoolSize;
> +  EFI_PHYSICAL_ADDRESS    Address;
> +
> +  if (mPageTablePool == NULL) {
> +    return;
> +  }
> +
> +  //
> +  // Disable write protection, because we need to mark page table to be write
> +  // protected.
> +  //
> +  AsmWriteCr0 (AsmReadCr0() & ~CR0_WP);
> +
> +  //
> +  // SetPageTablePoolReadOnly might update mPageTablePool. It's safer to
> +  // remember original one in advance.
> +  //
> +  HeadPool = mPageTablePool;
> +  Pool = HeadPool;
> +  do {
> +    Address  = (EFI_PHYSICAL_ADDRESS)(UINTN)Pool;
> +    PoolSize = Pool->Offset + EFI_PAGES_TO_SIZE (Pool->FreePages);
> +
> +    //
> +    // The size of one pool must be multiple of PAGE_TABLE_POOL_UNIT_SIZE,
> which
> +    // is one of page size of the processor (2MB by default). Let's apply the
> +    // protection to them one by one.
> +    //
> +    while (PoolSize > 0) {
> +      SetPageTablePoolReadOnly(PageTableBase, Address, Level4Paging);
> +      Address   += PAGE_TABLE_POOL_UNIT_SIZE;
> +      PoolSize  -= PAGE_TABLE_POOL_UNIT_SIZE;
> +    }
> +
> +    Pool = Pool->NextPool;
> +  } while (Pool != HeadPool);
> +
> +  //
> +  // Enable write protection, after page table attribute updated.
> +  //
> +  AsmWriteCr0 (AsmReadCr0() | CR0_WP);
> +}
> +
> +/**
> +  Allocates and fills in the Page Directory and Page Table Entries to
> +  establish a 1:1 Virtual to Physical mapping.
> +
> +  @param[in] StackBase  Stack base address.
> +  @param[in] StackSize  Stack size.
> +
> +  @return The address of 4 level page map.
> +
> +**/
> +UINTN
> +CreateIdentityMappingPageTables (
> +  IN EFI_PHYSICAL_ADDRESS   StackBase,
> +  IN UINTN                  StackSize
> +  )
> +{
> +  UINT32                                        RegEax;
> +  CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX   EcxFlags;
> +  UINT32                                        RegEdx;
> +  UINT8                                         PhysicalAddressBits;
> +  EFI_PHYSICAL_ADDRESS                          PageAddress;
> +  UINTN                                         IndexOfPml5Entries;
> +  UINTN                                         IndexOfPml4Entries;
> +  UINTN                                         IndexOfPdpEntries;
> +  UINTN                                         IndexOfPageDirectoryEntries;
> +  UINT32                                        NumberOfPml5EntriesNeeded;
> +  UINT32                                        NumberOfPml4EntriesNeeded;
> +  UINT32                                        NumberOfPdpEntriesNeeded;
> +  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMapLevel5Entry;
> +  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMapLevel4Entry;
> +  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMap;
> +  PAGE_MAP_AND_DIRECTORY_POINTER                *PageDirectoryPointerEntry;
> +  PAGE_TABLE_ENTRY                              *PageDirectoryEntry;
> +  UINTN                                         TotalPagesNum;
> +  UINTN                                         BigPageAddress;
> +  VOID                                          *Hob;
> +  BOOLEAN                                       Page5LevelSupport;
> +  BOOLEAN                                       Page1GSupport;
> +  PAGE_TABLE_1G_ENTRY                           *PageDirectory1GEntry;
> +  UINT64                                        AddressEncMask;
> +  IA32_CR4                                      Cr4;
> +
> +  //
> +  // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings
> +  //
> +  PageMapLevel5Entry = NULL;
> +
> +  //
> +  // Make sure AddressEncMask is contained to smallest supported address field
> +  //
> +  AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &
> PAGING_1G_ADDRESS_MASK_64;
> +
> +  Page1GSupport = FALSE;
> +  if (PcdGetBool(PcdUse1GPageTable)) {
> +    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
> +    if (RegEax >= 0x80000001) {
> +      AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
> +      if ((RegEdx & BIT26) != 0) {
> +        Page1GSupport = TRUE;
> +      }
> +    }
> +  }
> +
> +  //
> +  // Get physical address bits supported.
> +  //
> +  Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
> +  if (Hob != NULL) {
> +    PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
> +  } else {
> +    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
> +    if (RegEax >= 0x80000008) {
> +      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
> +      PhysicalAddressBits = (UINT8) RegEax;
> +    } else {
> +      PhysicalAddressBits = 36;
> +    }
> +  }
> +
> +  Page5LevelSupport = FALSE;
> +  if (PcdGetBool (PcdUse5LevelPageTable)) {
> +    AsmCpuidEx (
> +      CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS,
> CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, NULL,
> +      &EcxFlags.Uint32, NULL, NULL
> +      );
> +    if (EcxFlags.Bits.FiveLevelPage != 0) {
> +      Page5LevelSupport = TRUE;
> +    }
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "AddressBits=%u 5LevelPaging=%u 1GPage=%u\n",
> PhysicalAddressBits, Page5LevelSupport, Page1GSupport));
> +
> +  //
> +  // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses
> +  //  when 5-Level Paging is disabled,
> +  //  due to either unsupported by HW, or disabled by PCD.
> +  //
> +  ASSERT (PhysicalAddressBits <= 52);
> +  if (!Page5LevelSupport && PhysicalAddressBits > 48) {
> +    PhysicalAddressBits = 48;
> +  }
> +
> +  //
> +  // Calculate the table entries needed.
> +  //
> +  NumberOfPml5EntriesNeeded = 1;
> +  if (PhysicalAddressBits > 48) {
> +    NumberOfPml5EntriesNeeded = (UINT32) LShiftU64 (1, PhysicalAddressBits
> - 48);
> +    PhysicalAddressBits = 48;
> +  }
> +
> +  NumberOfPml4EntriesNeeded = 1;
> +  if (PhysicalAddressBits > 39) {
> +    NumberOfPml4EntriesNeeded = (UINT32) LShiftU64 (1, PhysicalAddressBits
> - 39);
> +    PhysicalAddressBits = 39;
> +  }
> +
> +  NumberOfPdpEntriesNeeded = 1;
> +  ASSERT (PhysicalAddressBits > 30);
> +  NumberOfPdpEntriesNeeded = (UINT32) LShiftU64 (1, PhysicalAddressBits -
> 30);
> +
> +  //
> +  // Pre-allocate big pages to avoid later allocations.
> +  //
> +  if (!Page1GSupport) {
> +    TotalPagesNum = ((NumberOfPdpEntriesNeeded + 1) *
> NumberOfPml4EntriesNeeded + 1) * NumberOfPml5EntriesNeeded + 1;
> +  } else {
> +    TotalPagesNum = (NumberOfPml4EntriesNeeded + 1) *
> NumberOfPml5EntriesNeeded + 1;
> +  }
> +
> +  //
> +  // Substract the one page occupied by PML5 entries if 5-Level Paging is
> disabled.
> +  //
> +  if (!Page5LevelSupport) {
> +    TotalPagesNum--;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "Pml5=%u Pml4=%u Pdp=%u TotalPage=%Lu\n",
> +    NumberOfPml5EntriesNeeded, NumberOfPml4EntriesNeeded,
> +    NumberOfPdpEntriesNeeded, (UINT64)TotalPagesNum));
> +
> +  BigPageAddress = (UINTN) AllocatePageTableMemory (TotalPagesNum);
> +  ASSERT (BigPageAddress != 0);
> +
> +  //
> +  // By architecture only one PageMapLevel4 exists - so lets allocate storage for
> it.
> +  //
> +  PageMap         = (VOID *) BigPageAddress;
> +  if (Page5LevelSupport) {
> +    //
> +    // By architecture only one PageMapLevel5 exists - so lets allocate storage for
> it.
> +    //
> +    PageMapLevel5Entry = PageMap;
> +    BigPageAddress    += SIZE_4KB;
> +  }
> +  PageAddress        = 0;
> +
> +  for ( IndexOfPml5Entries = 0
> +      ; IndexOfPml5Entries < NumberOfPml5EntriesNeeded
> +      ; IndexOfPml5Entries++) {
> +    //
> +    // Each PML5 entry points to a page of PML4 entires.
> +    // So lets allocate space for them and fill them in in the IndexOfPml4Entries
> loop.
> +    // When 5-Level Paging is disabled, below allocation happens only once.
> +    //
> +    PageMapLevel4Entry = (VOID *) BigPageAddress;
> +    BigPageAddress    += SIZE_4KB;
> +
> +    if (Page5LevelSupport) {
> +      //
> +      // Make a PML5 Entry
> +      //
> +      PageMapLevel5Entry->Uint64 = (UINT64) (UINTN) PageMapLevel4Entry |
> AddressEncMask;
> +      PageMapLevel5Entry->Bits.ReadWrite = 1;
> +      PageMapLevel5Entry->Bits.Present   = 1;
> +      PageMapLevel5Entry++;
> +    }
> +
> +    for ( IndexOfPml4Entries = 0
> +        ; IndexOfPml4Entries < (NumberOfPml5EntriesNeeded == 1 ?
> NumberOfPml4EntriesNeeded : 512)
> +        ; IndexOfPml4Entries++, PageMapLevel4Entry++) {
> +      //
> +      // Each PML4 entry points to a page of Page Directory Pointer entires.
> +      // So lets allocate space for them and fill them in in the IndexOfPdpEntries
> loop.
> +      //
> +      PageDirectoryPointerEntry = (VOID *) BigPageAddress;
> +      BigPageAddress += SIZE_4KB;
> +
> +      //
> +      // Make a PML4 Entry
> +      //
> +      PageMapLevel4Entry->Uint64 =
> (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask;
> +      PageMapLevel4Entry->Bits.ReadWrite = 1;
> +      PageMapLevel4Entry->Bits.Present = 1;
> +
> +      if (Page1GSupport) {
> +        PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;
> +
> +        for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512;
> IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress +=
> SIZE_1GB) {
> +          if (ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSize)) {
> +            Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry,
> StackBase, StackSize);
> +          } else {
> +            //
> +            // Fill in the Page Directory entries
> +            //
> +            PageDirectory1GEntry->Uint64 = (UINT64)PageAddress |
> AddressEncMask;
> +            PageDirectory1GEntry->Bits.ReadWrite = 1;
> +            PageDirectory1GEntry->Bits.Present = 1;
> +            PageDirectory1GEntry->Bits.MustBe1 = 1;
> +          }
> +        }
> +      } else {
> +        for ( IndexOfPdpEntries = 0
> +            ; IndexOfPdpEntries < (NumberOfPml4EntriesNeeded == 1 ?
> NumberOfPdpEntriesNeeded : 512)
> +            ; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
> +          //
> +          // Each Directory Pointer entries points to a page of Page Directory
> entires.
> +          // So allocate space for them and fill them in in the
> IndexOfPageDirectoryEntries loop.
> +          //
> +          PageDirectoryEntry = (VOID *) BigPageAddress;
> +          BigPageAddress += SIZE_4KB;
> +
> +          //
> +          // Fill in a Page Directory Pointer Entries
> +          //
> +          PageDirectoryPointerEntry->Uint64 =
> (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask;
> +          PageDirectoryPointerEntry->Bits.ReadWrite = 1;
> +          PageDirectoryPointerEntry->Bits.Present = 1;
> +
> +          for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512;
> IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress +=
> SIZE_2MB) {
> +            if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSize)) {
> +              //
> +              // Need to split this 2M page that covers NULL or stack range.
> +              //
> +              Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry,
> StackBase, StackSize);
> +            } else {
> +              //
> +              // Fill in the Page Directory entries
> +              //
> +              PageDirectoryEntry->Uint64 = (UINT64)PageAddress |
> AddressEncMask;
> +              PageDirectoryEntry->Bits.ReadWrite = 1;
> +              PageDirectoryEntry->Bits.Present = 1;
> +              PageDirectoryEntry->Bits.MustBe1 = 1;
> +            }
> +          }
> +        }
> +
> +        //
> +        // Fill with null entry for unused PDPTE
> +        //
> +        ZeroMem (PageDirectoryPointerEntry, (512 - IndexOfPdpEntries) *
> sizeof(PAGE_MAP_AND_DIRECTORY_POINTER));
> +      }
> +    }
> +
> +    //
> +    // For the PML4 entries we are not using fill in a null entry.
> +    //
> +    ZeroMem (PageMapLevel4Entry, (512 - IndexOfPml4Entries) * sizeof
> (PAGE_MAP_AND_DIRECTORY_POINTER));
> +  }
> +
> +  if (Page5LevelSupport) {
> +    Cr4.UintN = AsmReadCr4 ();
> +    Cr4.Bits.LA57 = 1;
> +    AsmWriteCr4 (Cr4.UintN);
> +    //
> +    // For the PML5 entries we are not using fill in a null entry.
> +    //
> +    ZeroMem (PageMapLevel5Entry, (512 - IndexOfPml5Entries) * sizeof
> (PAGE_MAP_AND_DIRECTORY_POINTER));
> +  }
> +
> +  //
> +  // Protect the page table by marking the memory used for page table to be
> +  // read-only.
> +  //
> +  EnablePageTableProtection ((UINTN)PageMap, TRUE);
> +
> +  //
> +  // Set IA32_EFER.NXE if necessary.
> +  //
> +  if (IsEnableNonExecNeeded ()) {
> +    EnableExecuteDisableBit ();
> +  }
> +
> +  return (UINTN)PageMap;
> +}
> +
> diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h
> b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h
> new file mode 100644
> index 0000000000..2d0493f109
> --- /dev/null
> +++ b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h
> @@ -0,0 +1,322 @@
> +/** @file
> +  x64 Long Mode Virtual Memory Management Definitions
> +
> +  References:
> +    1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic
> Architecture, Intel
> +    2) IA-32 Intel(R) Architecture Software Developer's Manual Volume
> 2:Instruction Set Reference, Intel
> +    3) IA-32 Intel(R) Architecture Software Developer's Manual Volume
> 3:System Programmer's Guide, Intel
> +    4) AMD64 Architecture Programmer's Manual Volume 2: System
> Programming
> +
> +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef _VIRTUAL_MEMORY_H_
> +#define _VIRTUAL_MEMORY_H_
> +
> +
> +#define SYS_CODE64_SEL 0x38
> +
> +
> +#pragma pack(1)
> +
> +typedef union {
> +  struct {
> +    UINT32  LimitLow    : 16;
> +    UINT32  BaseLow     : 16;
> +    UINT32  BaseMid     : 8;
> +    UINT32  Type        : 4;
> +    UINT32  System      : 1;
> +    UINT32  Dpl         : 2;
> +    UINT32  Present     : 1;
> +    UINT32  LimitHigh   : 4;
> +    UINT32  Software    : 1;
> +    UINT32  Reserved    : 1;
> +    UINT32  DefaultSize : 1;
> +    UINT32  Granularity : 1;
> +    UINT32  BaseHigh    : 8;
> +  } Bits;
> +  UINT64  Uint64;
> +} IA32_GDT;
> +
> +typedef struct {
> +  IA32_IDT_GATE_DESCRIPTOR  Ia32IdtEntry;
> +  UINT32                    Offset32To63;
> +  UINT32                    Reserved;
> +} X64_IDT_GATE_DESCRIPTOR;
> +
> +//
> +// Page-Map Level-4 Offset (PML4) and
> +// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
> +//
> +
> +typedef union {
> +  struct {
> +    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in
> memory
> +    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
> +    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
> +    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through
> caching
> +    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
> +    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
> +    UINT64  Reserved:1;               // Reserved
> +    UINT64  MustBeZero:2;             // Must Be Zero
> +    UINT64  Available:3;              // Available for use by system software
> +    UINT64  PageTableBaseAddress:40;  // Page Table Base Address
> +    UINT64  AvabilableHigh:11;        // Available for use by system software
> +    UINT64  Nx:1;                     // No Execute bit
> +  } Bits;
> +  UINT64    Uint64;
> +} PAGE_MAP_AND_DIRECTORY_POINTER;
> +
> +//
> +// Page Table Entry 4KB
> +//
> +typedef union {
> +  struct {
> +    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in
> memory
> +    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
> +    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
> +    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through
> caching
> +    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
> +    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
> +    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access
> to page
> +    UINT64  PAT:1;                    //
> +    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not
> cleared on CR3 write
> +    UINT64  Available:3;              // Available for use by system software
> +    UINT64  PageTableBaseAddress:40;  // Page Table Base Address
> +    UINT64  AvabilableHigh:11;        // Available for use by system software
> +    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
> +  } Bits;
> +  UINT64    Uint64;
> +} PAGE_TABLE_4K_ENTRY;
> +
> +//
> +// Page Table Entry 2MB
> +//
> +typedef union {
> +  struct {
> +    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in
> memory
> +    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
> +    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
> +    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through
> caching
> +    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
> +    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
> +    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access
> to page
> +    UINT64  MustBe1:1;                // Must be 1
> +    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not
> cleared on CR3 write
> +    UINT64  Available:3;              // Available for use by system software
> +    UINT64  PAT:1;                    //
> +    UINT64  MustBeZero:8;             // Must be zero;
> +    UINT64  PageTableBaseAddress:31;  // Page Table Base Address
> +    UINT64  AvabilableHigh:11;        // Available for use by system software
> +    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
> +  } Bits;
> +  UINT64    Uint64;
> +} PAGE_TABLE_ENTRY;
> +
> +//
> +// Page Table Entry 1GB
> +//
> +typedef union {
> +  struct {
> +    UINT64  Present:1;                // 0 = Not present in memory, 1 = Present in
> memory
> +    UINT64  ReadWrite:1;              // 0 = Read-Only, 1= Read/Write
> +    UINT64  UserSupervisor:1;         // 0 = Supervisor, 1=User
> +    UINT64  WriteThrough:1;           // 0 = Write-Back caching, 1=Write-Through
> caching
> +    UINT64  CacheDisabled:1;          // 0 = Cached, 1=Non-Cached
> +    UINT64  Accessed:1;               // 0 = Not accessed, 1 = Accessed (set by CPU)
> +    UINT64  Dirty:1;                  // 0 = Not Dirty, 1 = written by processor on access
> to page
> +    UINT64  MustBe1:1;                // Must be 1
> +    UINT64  Global:1;                 // 0 = Not global page, 1 = global page TLB not
> cleared on CR3 write
> +    UINT64  Available:3;              // Available for use by system software
> +    UINT64  PAT:1;                    //
> +    UINT64  MustBeZero:17;            // Must be zero;
> +    UINT64  PageTableBaseAddress:22;  // Page Table Base Address
> +    UINT64  AvabilableHigh:11;        // Available for use by system software
> +    UINT64  Nx:1;                     // 0 = Execute Code, 1 = No Code Execution
> +  } Bits;
> +  UINT64    Uint64;
> +} PAGE_TABLE_1G_ENTRY;
> +
> +#pragma pack()
> +
> +#define CR0_WP                      BIT16
> +
> +#define IA32_PG_P                   BIT0
> +#define IA32_PG_RW                  BIT1
> +#define IA32_PG_PS                  BIT7
> +
> +#define PAGING_PAE_INDEX_MASK       0x1FF
> +
> +#define PAGING_4K_ADDRESS_MASK_64   0x000FFFFFFFFFF000ull
> +#define PAGING_2M_ADDRESS_MASK_64   0x000FFFFFFFE00000ull
> +#define PAGING_1G_ADDRESS_MASK_64   0x000FFFFFC0000000ull
> +
> +#define PAGING_L1_ADDRESS_SHIFT     12
> +#define PAGING_L2_ADDRESS_SHIFT     21
> +#define PAGING_L3_ADDRESS_SHIFT     30
> +#define PAGING_L4_ADDRESS_SHIFT     39
> +
> +#define PAGING_PML4E_NUMBER         4
> +
> +#define PAGE_TABLE_POOL_ALIGNMENT   BASE_2MB
> +#define PAGE_TABLE_POOL_UNIT_SIZE   SIZE_2MB
> +#define PAGE_TABLE_POOL_UNIT_PAGES  EFI_SIZE_TO_PAGES
> (PAGE_TABLE_POOL_UNIT_SIZE)
> +#define PAGE_TABLE_POOL_ALIGN_MASK  \
> +  (~(EFI_PHYSICAL_ADDRESS)(PAGE_TABLE_POOL_ALIGNMENT - 1))
> +
> +typedef struct {
> +  VOID            *NextPool;
> +  UINTN           Offset;
> +  UINTN           FreePages;
> +} PAGE_TABLE_POOL;
> +
> +/**
> +  Check if Execute Disable Bit (IA32_EFER.NXE) should be enabled or not.
> +
> +  @retval TRUE    IA32_EFER.NXE should be enabled.
> +  @retval FALSE   IA32_EFER.NXE should not be enabled.
> +
> +**/
> +BOOLEAN
> +IsEnableNonExecNeeded (
> +  VOID
> +  );
> +
> +/**
> +  Enable Execute Disable Bit.
> +
> +**/
> +VOID
> +EnableExecuteDisableBit (
> +  VOID
> +  );
> +
> +/**
> +  Split 2M page to 4K.
> +
> +  @param[in]      PhysicalAddress       Start physical address the 2M page
> covered.
> +  @param[in, out] PageEntry2M           Pointer to 2M page entry.
> +  @param[in]      StackBase             Stack base address.
> +  @param[in]      StackSize             Stack size.
> +
> +**/
> +VOID
> +Split2MPageTo4K (
> +  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
> +  IN OUT UINT64                         *PageEntry2M,
> +  IN EFI_PHYSICAL_ADDRESS               StackBase,
> +  IN UINTN                              StackSize
> +  );
> +
> +/**
> +  Allocates and fills in the Page Directory and Page Table Entries to
> +  establish a 1:1 Virtual to Physical mapping.
> +
> +  @param[in] StackBase  Stack base address.
> +  @param[in] StackSize  Stack size.
> +
> +  @return The address of 4 level page map.
> +
> +**/
> +UINTN
> +CreateIdentityMappingPageTables (
> +  IN EFI_PHYSICAL_ADDRESS   StackBase,
> +  IN UINTN                  StackSize
> +  );
> +
> +
> +/**
> +
> +  Fix up the vector number in the vector code.
> +
> +  @param VectorBase   Base address of the vector handler.
> +  @param VectorNum    Index of vector.
> +
> +**/
> +VOID
> +EFIAPI
> +AsmVectorFixup (
> +  VOID    *VectorBase,
> +  UINT8   VectorNum
> +  );
> +
> +
> +/**
> +
> +  Get the information of vector template.
> +
> +  @param TemplateBase   Base address of the template code.
> +
> +  @return               Size of the Template code.
> +
> +**/
> +UINTN
> +EFIAPI
> +AsmGetVectorTemplatInfo (
> +  OUT   VOID  **TemplateBase
> +  );
> +
> +/**
> +  Clear legacy memory located at the first 4K-page.
> +
> +  This function traverses the whole HOB list to check if memory from 0 to 4095
> +  exists and has not been allocated, and then clear it if so.
> +
> +  @param HobStart         The start of HobList passed to DxeCore.
> +
> +**/
> +VOID
> +ClearFirst4KPage (
> +  IN  VOID *HobStart
> +  );
> +
> +/**
> +  Return configure status of NULL pointer detection feature.
> +
> +  @return TRUE   NULL pointer detection feature is enabled
> +  @return FALSE  NULL pointer detection feature is disabled
> +**/
> +BOOLEAN
> +IsNullDetectionEnabled (
> +  VOID
> +  );
> +
> +/**
> +  Prevent the memory pages used for page table from been overwritten.
> +
> +  @param[in] PageTableBase    Base address of page table (CR3).
> +  @param[in] Level4Paging     Level 4 paging flag.
> +
> +**/
> +VOID
> +EnablePageTableProtection (
> +  IN  UINTN     PageTableBase,
> +  IN  BOOLEAN   Level4Paging
> +  );
> +
> +/**
> +  This API provides a way to allocate memory for page table.
> +
> +  This API can be called more than once to allocate memory for page tables.
> +
> +  Allocates the number of 4KB pages and returns a pointer to the allocated
> +  buffer. The buffer returned is aligned on a 4KB boundary.
> +
> +  If Pages is 0, then NULL is returned.
> +  If there is not enough memory remaining to satisfy the request, then NULL is
> +  returned.
> +
> +  @param  Pages                 The number of 4 KB pages to allocate.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +AllocatePageTableMemory (
> +  IN UINTN           Pages
> +  );
> +
> +#endif
> diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec
> b/UefiPayloadPkg/UefiPayloadPkg.dec
> index 1559735db2..99cb3311a6 100644
> --- a/UefiPayloadPkg/UefiPayloadPkg.dec
> +++ b/UefiPayloadPkg/UefiPayloadPkg.dec
> @@ -3,7 +3,7 @@
>  #
>  # Provides drivers and definitions to create uefi payload for bootloaders.
>  #
> -# Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
>  # SPDX-License-Identifier: BSD-2-Clause-Patent
>  #
>  ##
> @@ -68,4 +68,5 @@
> gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0x
> 04|UINT32|0x0
> 
> gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|0xC
> 0|UINT32|0x00000015
> 
> gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|0x
> 80|UINT32|0x00000016
> 
> -
> +# Size of the region used by UEFI in permanent memory
> +gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x02000
> 000|UINT32|0x00000017
> diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
> b/UefiPayloadPkg/UefiPayloadPkg.dsc
> similarity index 90%
> rename from UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
> rename to UefiPayloadPkg/UefiPayloadPkg.dsc
> index e18c4678e8..b772c8456e 100644
> --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
> +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
> @@ -92,6 +92,12 @@
>    INTEL:RELEASE_*_*_CC_FLAGS     = /D MDEPKG_NDEBUG
>    MSFT:RELEASE_*_*_CC_FLAGS      = /D MDEPKG_NDEBUG
> 
> +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
> +  GCC:*_*_*_DLINK_FLAGS      = -z common-page-size=0x1000
> +  XCODE:*_*_*_DLINK_FLAGS    = -seg1addr 0x1000 -segalign 0x1000
> +  XCODE:*_*_*_MTOC_FLAGS     = -align 0x1000
> +  CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096
> +  MSFT:*_*_*_DLINK_FLAGS     = /ALIGN:4096
> 
> 
> #############################################################
> ###################
>  #
> @@ -110,8 +116,6 @@
>    #
>    # Entry point
>    #
> -  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
> -  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> 
> DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> 
> UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoi
> nt.inf
> 
> UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiAppl
> icationEntryPoint.inf
> @@ -149,8 +153,6 @@
>    HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
>    DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> 
> UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecomp
> ressLib.inf
> -
> PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiS
> ervicesTablePointerLibIdt.inf
> -  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
>    DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> 
> DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib
> .inf
>    UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
> @@ -210,23 +212,9 @@
> 
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmM
> easurementLibNull.inf
>    VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> 
> -[LibraryClasses.IA32.SEC]
> -  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +[LibraryClasses.common.SEC]
> +  HobLib|UefiPayloadPkg/Library/HobLib/HobLib.inf
>    PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> -  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> -
> MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAll
> ocationLib.inf
> -
> DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNu
> ll.inf
> -
> ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseRepo
> rtStatusCodeLibNull.inf
> -
> -[LibraryClasses.IA32.PEI_CORE, LibraryClasses.IA32.PEIM]
> -  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> -  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> -
> MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAll
> ocationLib.inf
> -
> ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiRepo
> rtStatusCodeLib.inf
> -
> ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtrac
> tGuidedSectionLib.inf
> -!if $(SOURCE_DEBUG_ENABLE)
> -
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent
> Lib.inf
> -!endif
> 
>  [LibraryClasses.common.DXE_CORE]
>    PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> @@ -372,29 +360,14 @@
>  # Components Section - list of all EDK II Modules needed by this Platform.
>  #
> 
> #############################################################
> ###################
> -[Components.IA32]
> -  #
> -  # SEC Core
> -  #
> -  UefiPayloadPkg/SecCore/SecCore.inf
> -
> -  #
> -  # PEI Core
> -  #
> -  MdeModulePkg/Core/Pei/PeiMain.inf
> 
> -  #
> -  # PEIM
> -  #
> -  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
> -    <LibraryClasses>
> -      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> -  }
> -
> MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRout
> erPei.inf
> -  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
> -
> -  UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
> -  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
> +!if "IA32" in $(ARCH)
> +  [Components.IA32]
> +    UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
> +!else
> +  [Components.X64]
> +    UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
> +!endif
> 
>  [Components.X64]
>    #
> diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf
> b/UefiPayloadPkg/UefiPayloadPkg.fdf
> index 570a8ee7fd..c81b405c6e 100644
> --- a/UefiPayloadPkg/UefiPayloadPkg.fdf
> +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf
> @@ -13,13 +13,10 @@ DEFINE FD_BASE       = 0x00800000
>  DEFINE FD_BLOCK_SIZE = 0x00001000
> 
>  !if $(TARGET) == "NOOPT"
> -DEFINE PEI_FV_SIZE = 0x00050000
> -DEFINE DXE_FV_SIZE = 0x00800000
>  DEFINE FD_SIZE     = 0x00850000
>  DEFINE NUM_BLOCKS  = 0x850
>  !else
> -DEFINE PEI_FV_SIZE = 0x30000
> -DEFINE DXE_FV_SIZE = 0x3E0000
> +
>  DEFINE FD_SIZE     = 0x00410000
>  DEFINE NUM_BLOCKS  = 0x410
>  !endif
> @@ -32,14 +29,11 @@ ErasePolarity = 1
>  BlockSize     = $(FD_BLOCK_SIZE)
>  NumBlocks     = $(NUM_BLOCKS)
> 
> -0x00000000|$(PEI_FV_SIZE)
> -FV = PEIFV
> -
> -$(PEI_FV_SIZE)|$(DXE_FV_SIZE)
> -FV = DXEFV
> +0x00000000|$(FD_SIZE)
> +FV = PLDFV
> 
> 
> #############################################################
> ###################
> -[FV.PEIFV]
> +[FV.PLDFV]
>  BlockSize          = $(FD_BLOCK_SIZE)
>  FvAlignment        = 16
>  ERASE_POLARITY     = 1
> @@ -58,14 +52,11 @@ READ_STATUS        = TRUE
>  READ_LOCK_CAP      = TRUE
>  READ_LOCK_STATUS   = TRUE
> 
> -INF UefiPayloadPkg/SecCore/SecCore.inf
> +INF UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
> 
> -INF MdeModulePkg/Core/Pei/PeiMain.inf
> -INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> -INF
> MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRout
> erPei.inf
> -INF
> MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
> -INF UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
> -INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
> +FILE FV_IMAGE = 4E35FD93-9C72-4c15-8C4B-E77F1DB2D793 {
> +    SECTION FV_IMAGE = DXEFV
> +}
> 
> 
> #############################################################
> ###################
> 
> @@ -89,11 +80,6 @@ READ_STATUS        = TRUE
>  READ_LOCK_CAP      = TRUE
>  READ_LOCK_STATUS   = TRUE
> 
> -APRIORI DXE {
> -  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> -  INF
> MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatus
> CodeRouterRuntimeDxe.inf
> -  INF
> MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandler
> RuntimeDxe.inf
> -}
> 
>  #
>  # DXE Phase modules
> diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
> b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
> deleted file mode 100644
> index 12d7ffe814..0000000000
> --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
> +++ /dev/null
> @@ -1,585 +0,0 @@
> -## @file
> -# Bootloader Payload Package
> -#
> -# Provides drivers and definitions to create uefi payload for bootloaders.
> -#
> -# Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
> -# SPDX-License-Identifier: BSD-2-Clause-Patent
> -#
> -##
> -
> -
> #############################################################
> ###################
> -#
> -# Defines Section - statements that will be processed to create a Makefile.
> -#
> -
> #############################################################
> ###################
> -[Defines]
> -  PLATFORM_NAME                       = UefiPayloadPkg
> -  PLATFORM_GUID                       = F71608AB-D63D-4491-B744-A99998C8CD96
> -  PLATFORM_VERSION                    = 0.1
> -  DSC_SPECIFICATION                   = 0x00010005
> -  SUPPORTED_ARCHITECTURES             = IA32
> -  BUILD_TARGETS                       = DEBUG|RELEASE|NOOPT
> -  SKUID_IDENTIFIER                    = DEFAULT
> -  OUTPUT_DIRECTORY                    = Build/UefiPayloadPkgIA32
> -  FLASH_DEFINITION                    = UefiPayloadPkg/UefiPayloadPkg.fdf
> -
> -  DEFINE SOURCE_DEBUG_ENABLE          = FALSE
> -
> -  #
> -  # SBL:      UEFI payload for Slim Bootloader
> -  # COREBOOT: UEFI payload for coreboot
> -  #
> -  DEFINE   BOOTLOADER = SBL
> -
> -  #
> -  # CPU options
> -  #
> -  DEFINE MAX_LOGICAL_PROCESSORS       = 64
> -
> -  #
> -  # PCI options
> -  #
> -  DEFINE PCIE_BASE_SUPPORT            = TRUE
> -
> -  #
> -  # Serial port set up
> -  #
> -  DEFINE BAUD_RATE                    = 115200
> -  DEFINE SERIAL_CLOCK_RATE            = 1843200
> -  DEFINE SERIAL_LINE_CONTROL          = 3 # 8-bits, no parity
> -  DEFINE SERIAL_HARDWARE_FLOW_CONTROL = FALSE
> -  DEFINE SERIAL_DETECT_CABLE          = FALSE
> -  DEFINE SERIAL_FIFO_CONTROL          = 7 # Enable FIFO
> -  DEFINE SERIAL_EXTENDED_TX_FIFO_SIZE = 16
> -  DEFINE UART_DEFAULT_BAUD_RATE       = $(BAUD_RATE)
> -  DEFINE UART_DEFAULT_DATA_BITS       = 8
> -  DEFINE UART_DEFAULT_PARITY          = 1
> -  DEFINE UART_DEFAULT_STOP_BITS       = 1
> -  DEFINE DEFAULT_TERMINAL_TYPE        = 0
> -
> -  # Enabling the serial terminal will slow down the boot menu redering!
> -  DEFINE DISABLE_SERIAL_TERMINAL      = FALSE
> -
> -  #
> -  #  typedef struct {
> -  #    UINT16  VendorId;          ///< Vendor ID to match the PCI device.  The value
> 0xFFFF terminates the list of entries.
> -  #    UINT16  DeviceId;          ///< Device ID to match the PCI device
> -  #    UINT32  ClockRate;         ///< UART clock rate.  Set to 0 for default clock rate
> of 1843200 Hz
> -  #    UINT64  Offset;            ///< The byte offset into to the BAR
> -  #    UINT8   BarIndex;          ///< Which BAR to get the UART base address
> -  #    UINT8   RegisterStride;    ///< UART register stride in bytes.  Set to 0 for
> default register stride of 1 byte.
> -  #    UINT16  ReceiveFifoDepth;  ///< UART receive FIFO depth in bytes. Set to 0
> for a default FIFO depth of 16 bytes.
> -  #    UINT16  TransmitFifoDepth; ///< UART transmit FIFO depth in bytes. Set to
> 0 for a default FIFO depth of 16 bytes.
> -  #    UINT8   Reserved[2];
> -  #  } PCI_SERIAL_PARAMETER;
> -  #
> -  # Vendor FFFF Device 0000 Prog Interface 1, BAR #0, Offset 0, Stride = 1,
> Clock 1843200 (0x1c2000)
> -  #
> -  #                                       [Vendor]   [Device]  [----ClockRate---]  [------------Offset---
> --------] [Bar] [Stride] [RxFifo] [TxFifo]   [Rsvd]   [Vendor]
> -  DEFINE PCI_SERIAL_PARAMETERS        = {0xff,0xff, 0x00,0x00,
> 0x0,0x20,0x1c,0x00, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x00,    0x01, 0x0,0x0,
> 0x0,0x0, 0x0,0x0, 0xff,0xff}
> -
> -  #
> -  # Shell options: [BUILD_SHELL, MIN_BIN, NONE, UEFI_BIN]
> -  #
> -  DEFINE SHELL_TYPE                   = BUILD_SHELL
> -
> -[BuildOptions]
> -  *_*_*_CC_FLAGS                 = -D DISABLE_NEW_DEPRECATED_INTERFACES
> -  GCC:*_UNIXGCC_*_CC_FLAGS       = -DMDEPKG_NDEBUG
> -  GCC:RELEASE_*_*_CC_FLAGS       = -DMDEPKG_NDEBUG
> -  INTEL:RELEASE_*_*_CC_FLAGS     = /D MDEPKG_NDEBUG
> -  MSFT:RELEASE_*_*_CC_FLAGS      = /D MDEPKG_NDEBUG
> -
> -
> -
> #############################################################
> ###################
> -#
> -# SKU Identification section - list of all SKU IDs supported by this Platform.
> -#
> -
> #############################################################
> ###################
> -[SkuIds]
> -  0|DEFAULT
> -
> -
> #############################################################
> ###################
> -#
> -# Library Class section - list of all Library Classes needed by this Platform.
> -#
> -
> #############################################################
> ###################
> -[LibraryClasses]
> -  #
> -  # Entry point
> -  #
> -  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
> -  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> -
> DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> -
> UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoi
> nt.inf
> -
> UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiAppl
> icationEntryPoint.inf
> -
> -  #
> -  # Basic
> -  #
> -  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> -
> BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepSt
> r.inf
> -
> SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizat
> ionLib.inf
> -  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> -  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> -  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> -!if $(PCIE_BASE_SUPPORT) == FALSE
> -  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
> -  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
> -!else
> -  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
> -  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
> -!endif
> -
> PciSegmentLib|MdePkg/Library/PciSegmentLibSegmentInfo/BasePciSegmentLi
> bSegmentInfo.inf
> -
> PciSegmentInfoLib|UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/P
> ciSegmentInfoLibAcpiBoardInfo.inf
> -  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> -
> PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeC
> offGetEntryPointLib.inf
> -
> CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCache
> MaintenanceLib.inf
> -
> -  #
> -  # UEFI & PI
> -  #
> -
> UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootS
> ervicesTableLib.inf
> -
> UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/Ue
> fiRuntimeServicesTableLib.inf
> -  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
> -  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
> -
> UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib
> .inf
> -  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
> -  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> -
> UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecomp
> ressLib.inf
> -
> PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiS
> ervicesTablePointerLibIdt.inf
> -  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> -  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> -
> DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib
> .inf
> -  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
> -  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> -
> -  #
> -  # Generic Modules
> -  #
> -  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
> -  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
> -
> OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/
> OemHookStatusCodeLibNull.inf
> -  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
> -
> SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/
> DxeSecurityManagementLib.inf
> -
> UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootM
> anagerLib.inf
> -
> CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/Customiz
> edDisplayLib.inf
> -
> FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltL
> ib.inf
> -
> -  #
> -  # CPU
> -  #
> -  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
> -  LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
> -
> -  #
> -  # Platform
> -  #
> -  TimerLib|UefiPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
> -  ResetSystemLib|UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.inf
> -
> SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLi
> b16550.inf
> -
> PlatformHookLib|UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.i
> nf
> -
> PlatformBootManagerLib|UefiPayloadPkg/Library/PlatformBootManagerLib/Pl
> atformBootManagerLib.inf
> -  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf
> -
> -  #
> -  # Misc
> -  #
> -
> DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseD
> ebugPrintErrorLevelLib.inf
> -
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLi
> bNull.inf
> -!if $(SOURCE_DEBUG_ENABLE) == TRUE
> -
> PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebu
> g/PeCoffExtraActionLibDebug.inf
> -
> DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunication
> LibSerialPort/DebugCommunicationLibSerialPort.inf
> -!else
> -
> PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCo
> ffExtraActionLibNull.inf
> -
> DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNu
> ll.inf
> -!endif
> -
> PlatformSupportLib|UefiPayloadPkg/Library/PlatformSupportLibNull/PlatformS
> upportLibNull.inf
> -!if $(BOOTLOADER) == "COREBOOT"
> -  BlParseLib|UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf
> -!else
> -  BlParseLib|UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf
> -!endif
> -
> -
> DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> -  LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
> -  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
> -
> AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLib
> Null.inf
> -
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmM
> easurementLibNull.inf
> -  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> -
> -[LibraryClasses.IA32.SEC]
> -  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> -  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> -  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> -
> MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAll
> ocationLib.inf
> -
> DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNu
> ll.inf
> -
> ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseRepo
> rtStatusCodeLibNull.inf
> -
> -[LibraryClasses.IA32.PEI_CORE, LibraryClasses.IA32.PEIM]
> -  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> -  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> -
> MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAll
> ocationLib.inf
> -
> ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiRepo
> rtStatusCodeLib.inf
> -
> ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtrac
> tGuidedSectionLib.inf
> -!if $(SOURCE_DEBUG_ENABLE)
> -
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent
> Lib.inf
> -!endif
> -
> -[LibraryClasses.common.DXE_CORE]
> -  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> -  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> -
> MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/D
> xeCoreMemoryAllocationLib.inf
> -
> ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtr
> actGuidedSectionLib.inf
> -
> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeRe
> portStatusCodeLib.inf
> -!if $(SOURCE_DEBUG_ENABLE)
> -
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib
> .inf
> -!endif
> -
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpu
> ExceptionHandlerLib.inf
> -  VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> -
> -[LibraryClasses.common.DXE_DRIVER]
> -  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> -  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> -
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemory
> AllocationLib.inf
> -
> ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtr
> actGuidedSectionLib.inf
> -
> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeRe
> portStatusCodeLib.inf
> -!if $(SOURCE_DEBUG_ENABLE)
> -
> DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib
> .inf
> -!endif
> -
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpu
> ExceptionHandlerLib.inf
> -  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
> -  VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf
> -
> -[LibraryClasses.common.DXE_RUNTIME_DRIVER]
> -  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> -  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> -
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemory
> AllocationLib.inf
> -
> ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib
> /RuntimeDxeReportStatusCodeLib.inf
> -
> -
> [LibraryClasses.common.UEFI_DRIVER,LibraryClasses.common.UEFI_APPLICATI
> ON]
> -  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> -
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemory
> AllocationLib.inf
> -
> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeRe
> portStatusCodeLib.inf
> -  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> -
> -
> #############################################################
> ###################
> -#
> -# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
> -#
> -
> #############################################################
> ###################
> -[PcdsFeatureFlag]
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
> -
> -[PcdsFixedAtBuild]
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x10000
> -
> gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x800
> 0
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x10000
> -  #
> -  # Make VariableRuntimeDxe work at emulated non-volatile variable mode.
> -  #
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
> -
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
> -!if $(TARGET) == DEBUG
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
> -!else
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
> -!endif
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa,
> 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23,
> 0x31 }
> -
> -  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|$(PCIE_BASE)
> -
> -!if $(SOURCE_DEBUG_ENABLE)
> -  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2
> -!endif
> -
> -[PcdsPatchableInModule.common]
> -  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x7
> -  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
> -!if $(SOURCE_DEBUG_ENABLE)
> -  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
> -!else
> -  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
> -!endif
> -
> -  #
> -  # The following parameters are set by Library/PlatformHookLib
> -  #
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|FALSE
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|$(BAUD_RATE)
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1
> -
> -  #
> -  # Enable these parameters to be set on the command line
> -  #
> -
> gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|$(SERIAL_CLOCK_RAT
> E)
> -
> gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl|$(SERIAL_LINE_CON
> TROL)
> -
> gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|$(SERI
> AL_HARDWARE_FLOW_CONTROL)
> -
> gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable|$(SERIAL_DETECT_C
> ABLE)
> -
> gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl|$(SERIAL_FIFO_CON
> TROL)
> -
> gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize|$(SERIAL_EX
> TENDED_TX_FIFO_SIZE)
> -
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
> -
> gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|$(UART_DEFAULT_BAU
> D_RATE)
> -
> gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|$(UART_DEFAULT_DATA
> _BITS)
> -  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|$(UART_DEFAULT_PARITY)
> -
> gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|$(UART_DEFAULT_STOP_
> BITS)
> -
> gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|$(DEFAULT_TERMINAL_
> TYPE)
> -
> gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters|$(PCI_SERIAL_PA
> RAMETERS)
> -
> -
> gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|$(MAX_LO
> GICAL_PROCESSORS)
> -
> -
> -
> #############################################################
> ###################
> -#
> -# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
> -#
> -
> #############################################################
> ###################
> -
> -[PcdsDynamicDefault]
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
> -  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
> -
> -  ## This PCD defines the video horizontal resolution.
> -  #  This PCD could be set to 0 then video resolution could be at highest
> resolution.
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0
> -  ## This PCD defines the video vertical resolution.
> -  #  This PCD could be set to 0 then video resolution could be at highest
> resolution.
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0
> -
> -  ## The PCD is used to specify the video horizontal resolution of text setup.
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|0
> -  ## The PCD is used to specify the video vertical resolution of text setup.
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|0
> -
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31
> -  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100
> -  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0
> -
> -
> #############################################################
> ###################
> -#
> -# Components Section - list of all EDK II Modules needed by this Platform.
> -#
> -
> #############################################################
> ###################
> -[Components.IA32]
> -  #
> -  # SEC Core
> -  #
> -  UefiPayloadPkg/SecCore/SecCore.inf
> -
> -  #
> -  # PEI Core
> -  #
> -  MdeModulePkg/Core/Pei/PeiMain.inf
> -
> -  #
> -  # PEIM
> -  #
> -  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
> -    <LibraryClasses>
> -      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> -  }
> -
> MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRout
> erPei.inf
> -  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
> -
> -  UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
> -  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
> -
> -[Components.IA32]
> -  #
> -  # DXE Core
> -  #
> -  MdeModulePkg/Core/Dxe/DxeMain.inf {
> -    <LibraryClasses>
> -
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecom
> pressLib.inf
> -  }
> -
> -  #
> -  # Components that produce the architectural protocols
> -  #
> -  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> -  UefiCpuPkg/CpuDxe/CpuDxe.inf
> -  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
> -  MdeModulePkg/Application/UiApp/UiApp.inf {
> -    <LibraryClasses>
> -
> NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
> -      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
> -
> NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenan
> ceManagerUiLib.inf
> -  }
> -
> -  PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
> -  MdeModulePkg/Universal/Metronome/Metronome.inf
> -  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> -  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> -  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> -
> MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterR
> untimeDxe.inf
> -
> MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.in
> f
> -
> PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.
> inf
> -  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> -
> -  #
> -  # Following are the DXE drivers
> -  #
> -  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
> -    <LibraryClasses>
> -      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> -  }
> -
> -
> MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatus
> CodeRouterRuntimeDxe.inf
> -
> MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandler
> RuntimeDxe.inf
> -  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> -  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
> -
> MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTest
> Dxe.inf
> -  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> -  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
> -  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
> -
> -  UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf
> -
> -  #
> -  # SMBIOS Support
> -  #
> -  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> -
> -  #
> -  # ACPI Support
> -  #
> -  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
> -
> -  #
> -  # PCI Support
> -  #
> -  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> -  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
> -    <LibraryClasses>
> -
> PciHostBridgeLib|UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.in
> f
> -  }
> -
> -  #
> -  # SCSI/ATA/IDE/DISK Support
> -  #
> -  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
> -  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
> -  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
> -  FatPkg/EnhancedFatDxe/Fat.inf
> -  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
> -  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> -  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> -  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> -  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> -
> -  #
> -  # SD/eMMC Support
> -  #
> -  MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
> -  MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf
> -  MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf
> -
> -  #
> -  # Usb Support
> -  #
> -  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
> -  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
> -  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> -  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> -  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> -  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> -
> -  #
> -  # ISA Support
> -  #
> -  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
> -!if $(PS2_KEYBOARD_ENABLE) == TRUE
> -  OvmfPkg/SioBusDxe/SioBusDxe.inf
> -  MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
> -!endif
> -
> -  #
> -  # Console Support
> -  #
> -  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> -  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> -
> MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.in
> f
> -!if $(DISABLE_SERIAL_TERMINAL) == FALSE
> -  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
> -!endif
> -  UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf
> -
> -  #------------------------------
> -  #  Build the shell
> -  #------------------------------
> -
> -!if $(SHELL_TYPE) == BUILD_SHELL
> -
> -  #
> -  # Shell Lib
> -  #
> -[LibraryClasses]
> -
> BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCo
> mmandLib.inf
> -  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> -  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> -  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
> -  !include NetworkPkg/NetworkLibs.dsc.inc
> -
> -[Components.IA32]
> -
> ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
> {
> -    <PcdsFixedAtBuild>
> -      ## This flag is used to control initialization of the shell library
> -      #  This should be FALSE for compiling the dynamic command.
> -      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> -  }
> -  ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf
> {
> -    <PcdsFixedAtBuild>
> -      ## This flag is used to control initialization of the shell library
> -      #  This should be FALSE for compiling the dynamic command.
> -      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> -  }
> -  ShellPkg/Application/Shell/Shell.inf {
> -    <PcdsFixedAtBuild>
> -      ## This flag is used to control initialization of the shell library
> -      #  This should be FALSE for compiling the shell application itself only.
> -      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> -
> -    #------------------------------
> -    #  Basic commands
> -    #------------------------------
> -
> -    <LibraryClasses>
> -
> NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1Command
> sLib.inf
> -
> NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2Command
> sLib.inf
> -
> NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3Command
> sLib.inf
> -
> NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Comma
> ndsLib.inf
> -
> NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1Comman
> dsLib.inf
> -
> NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Comma
> ndsLib.inf
> -
> -    #------------------------------
> -    #  Networking commands
> -    #------------------------------
> -
> -    <LibraryClasses>
> -
> NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1Co
> mmandsLib.inf
> -
> -    #------------------------------
> -    #  Support libraries
> -    #------------------------------
> -
> -    <LibraryClasses>
> -      DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
> -      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> -
> HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.
> inf
> -      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> -      ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
> -
> ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLi
> b.inf
> -      SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> -  }
> -
> -!endif
> --
> 2.16.2.windows.1
> 
> 
> 
> 
> 


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-11-13 23:36 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-11-10 18:39 [edk2-devel] [PATCH] UefiPayloadPkg: Remove PEI phase from Payload Guo Dong
  -- strict thread matches above, loose matches on Subject: below --
2020-11-13 23:35 Ma, Maurice

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox