[edk2-devel] [PATCH V2 1/1] UefiPayloadPkg: Remove PEI phase from Payload

Patrick Rudolph patrick.rudolph at 9elements.com
Tue Jan 26 16:21:12 UTC 2021


Hi,
I'm trying to rebase my TPM support patches for UefiPayloadPkg on top of master.

The Tcg*Dxe needs the following PCDs set by their Tcg*Pei counterparts:
* PcdTpm2HashMask
* PcdTcg2HashAlgorithmBitmap
* PcdTpmInstanceGuid

As there's no PEI stage any more, how do you plan to support TPMs in
UefiPayloadPkg?

Kind Regards,
Patrick Rudolph

On Mon, Nov 16, 2020 at 10:39 PM Ma, Maurice <maurice.ma at intel.com> wrote:
>
> V2 patch looks good to me.
>
> Reviewed-by:
> Maurice Ma <maurice.ma at intel.com>
>
> Regards
> Maurice
> > -----Original Message-----
> > From: Guo Dong <guo.dong at intel.com>
> > Sent: Sunday, November 15, 2020 16:35
> > To: devel at edk2.groups.io
> > Cc: Ma, Maurice <maurice.ma at intel.com>; You, Benjamin
> > <benjamin.you at intel.com>
> > Subject: [edk2-devel] [PATCH V2 1/1] 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 at 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                | 706 ++++++++++++++++
> >  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 | 365 ++++++++
> >  .../UefiPayloadEntry/Ia32/IdtVectorAsm.nasm        |  71 ++
> >  UefiPayloadPkg/UefiPayloadEntry/Ia32/SecEntry.nasm |  46 +
> >  UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c      | 307 +++++++
> >  UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c | 201 +++++
> >  .../UefiPayloadEntry.c}                            | 451 ++++------
> >  UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h | 134 +++
> >  .../UefiPayloadEntry/UefiPayloadEntry.inf          |  93 ++
> >  UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c  | 107 +++
> >  UefiPayloadPkg/UefiPayloadEntry/X64/SecEntry.nasm  |  47 ++
> >  .../UefiPayloadEntry/X64/VirtualMemory.c           | 939
> > +++++++++++++++++++++
> >  .../UefiPayloadEntry/X64/VirtualMemory.h           | 330 ++++++++
> >  UefiPayloadPkg/UefiPayloadPkg.dec                  |   5 +-
> >  ...efiPayloadPkgIa32X64.dsc => UefiPayloadPkg.dsc} |  57 +-
> >  UefiPayloadPkg/UefiPayloadPkg.fdf                  |  32 +-
> >  UefiPayloadPkg/UefiPayloadPkgIa32.dsc              | 585 -------------
> >  28 files changed, 3576 insertions(+), 1907 deletions(-)
> >  delete mode 100644 UefiPayloadPkg/BlSupportPei/BlSupportPei.h
> >  delete mode 100644 UefiPayloadPkg/BlSupportPei/BlSupportPei.inf
> >  create mode 100644 UefiPayloadPkg/Library/HobLib/Hob.c
> >  create mode 100644 UefiPayloadPkg/Library/HobLib/HobLib.inf
> >  delete mode 100644 UefiPayloadPkg/SecCore/FindPeiCore.c
> >  delete mode 100644 UefiPayloadPkg/SecCore/Ia32/SecEntry.nasm
> >  delete mode 100644 UefiPayloadPkg/SecCore/Ia32/Stack.nasm
> >  delete mode 100644 UefiPayloadPkg/SecCore/SecCore.inf
> >  delete mode 100644 UefiPayloadPkg/SecCore/SecMain.c
> >  delete mode 100644 UefiPayloadPkg/SecCore/SecMain.h
> >  create mode 100644 UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
> >  create mode 100644
> > UefiPayloadPkg/UefiPayloadEntry/Ia32/IdtVectorAsm.nasm
> >  create mode 100644 UefiPayloadPkg/UefiPayloadEntry/Ia32/SecEntry.nasm
> >  create mode 100644 UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
> >  create mode 100644 UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c
> >  rename UefiPayloadPkg/{BlSupportPei/BlSupportPei.c =>
> > UefiPayloadEntry/UefiPayloadEntry.c} (52%)
> >  create mode 100644 UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
> >  create mode 100644 UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
> >  create mode 100644 UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
> >  create mode 100644 UefiPayloadPkg/UefiPayloadEntry/X64/SecEntry.nasm
> >  create mode 100644 UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c
> >  create mode 100644 UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h
> >  rename UefiPayloadPkg/{UefiPayloadPkgIa32X64.dsc => UefiPayloadPkg.dsc}
> > (90%)
> >  delete mode 100644 UefiPayloadPkg/UefiPayloadPkgIa32.dsc
> >
> > 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..c0b4cc0b0f
> > --- /dev/null
> > +++ b/UefiPayloadPkg/Library/HobLib/Hob.c
> > @@ -0,0 +1,706 @@
> > +/** @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;
> > +}
> > +
> > +
> > +/**
> > +  Build a Handoff Information Table HOB
> > +
> > +  This function initialize a HOB region from EfiMemoryBegin with length
> > +  EfiMemoryLength. And EfiFreeMemoryBottom and EfiFreeMemoryTop
> > should
> > +  be inside the HOB region.
> > +
> > +  @param[in] EfiMemoryBegin       Total memory start address
> > +  @param[in] EfiMemoryLength      Total memory length reported in handoff
> > HOB.
> > +  @param[in] EfiFreeMemoryBottom  Free memory start address
> > +  @param[in] EfiFreeMemoryTop     Free memory end address.
> > +
> > +  @return   The pointer to the handoff HOB table.
> > +
> > +**/
> > +EFI_HOB_HANDOFF_INFO_TABLE*
> > +EFIAPI
> > +HobConstructor (
> > +  IN VOID   *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;
> > +}
> > +
> > +/**
> > +  Add a new HOB to the HOB List.
> > +
> > +  @param HobType            Type of the new HOB.
> > +  @param HobLength          Length of the new HOB to allocate.
> > +
> > +  @return  NULL if there is no space to create a hob.
> > +  @return  The address point to the new created hob.
> > +
> > +**/
> > +VOID *
> > +EFIAPI
> > +CreateHob (
> > +  IN  UINT16    HobType,
> > +  IN  UINT16    HobLength
> > +  )
> > +{
> > +  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..f999da9c66
> > --- /dev/null
> > +++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
> > @@ -0,0 +1,365 @@
> > +/** @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, 0, 0);
> > +      } 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,
> > 0, 0);
> > +
> > +    //
> > +    // 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);
> > +    CpuDeadLoop();
> > +  }
> > +
> > +}
> > +
> > 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)
> > +
> > + at VectorTemplateBase:
> > +        push  eax
> > +        db    0x6a       ; push #VectorNumber
> > + at VectorNum:
> > +        db    0
> > +        mov   eax, CommonInterruptEntry
> > +        jmp   eax
> > + at 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..de9dbb0b0e
> > --- /dev/null
> > +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c
> > @@ -0,0 +1,307 @@
> > +/** @file
> > +
> > +  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "UefiPayloadEntry.h"
> > +
> > +/**
> > +  Allocate pages for code.
> > +
> > +  @param[in] Pages      Number of pages to be allocated.
> > +
> > +  @return Allocated memory.
> > +**/
> > +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;
> > +}
> > +
> > +
> > +/**
> > +    Loads and relocates a PE/COFF image
> > +
> > +  @param[in]  PeCoffImage     Point to a Pe/Coff image.
> > +  @param[out]  ImageAddress   The image memory address after relocation.
> > +  @param[out]  ImageSize      The image size.
> > +  @param[out]  EntryPoint     The image entry point.
> > +
> > +  @return EFI_SUCCESS    If the image is loaded and relocated successfully.
> > +  @return Others         If the image failed to load or relocate.
> > +**/
> > +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);
> > +  if (EFI_ERROR (Status)) {
> > +    ASSERT_EFI_ERROR (Status);
> > +    return Status;
> > +  }
> > +
> > +  //
> > +  // Allocate Memory for the image
> > +  //
> > +  Buffer = AllocateCodePages
> > (EFI_SIZE_TO_PAGES((UINT32)ImageContext.ImageSize));
> > +  if (Buffer == NULL) {
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
> > +
> > +  //
> > +  // Load the image to our new buffer
> > +  //
> > +  Status = PeCoffLoaderLoadImage (&ImageContext);
> > +  if (EFI_ERROR (Status)) {
> > +    ASSERT_EFI_ERROR (Status);
> > +    return Status;
> > +  }
> > +
> > +  //
> > +  // Relocate the image in our new buffer
> > +  //
> > +  Status = PeCoffLoaderRelocateImage (&ImageContext);
> > +  if (EFI_ERROR (Status)) {
> > +    ASSERT_EFI_ERROR (Status);
> > +    return Status;
> > +  }
> > +
> > +  *ImageAddress = ImageContext.ImageAddress;
> > +  *ImageSize    = ImageContext.ImageSize;
> > +  *EntryPoint   = ImageContext.EntryPoint;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  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..805f5448d9 100644
> > --- a/UefiPayloadPkg/BlSupportPei/BlSupportPei.c
> > +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
> > @@ -1,144 +1,58 @@
> >  /** @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.
> > +   Callback function to build resource descriptor HOB
> >
> > -  @param  MmioBase    Base address of the memory mapped io range
> > -  @param  MmioSize    Length of the memory mapped io range
> > +   This function build a HOB based on the memory map entry info.
> >
> > -**/
> > -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
> > -    );
> > -}
> > -
> > -/**
> > -  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.
> > +   @param MemoryMapEntry         Memory map entry info got from
> > bootloader.
> > +   @param Params                 Not used for now.
> >
> > +  @retval RETURN_SUCCESS        Successfully build a HOB.
> >  **/
> > -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 RETURN_SUCCESS;
> >  }
> >
> >
> > +
> >  /**
> >    Find the board related info from ACPI table
> >
> > @@ -299,91 +213,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 +235,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 +298,118 @@ 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                         MemBase;
> > +  UINTN                         MemSize;
> > +  UINTN                         HobMemBase;
> > +  UINTN                         HobMemTop;
> > +  EFI_PEI_HOB_POINTERS          Hob;
> > +
> > +  // Call constructor for all libraries
> > +  ProcessLibraryConstructorList ();
> > +
> > +  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 ();
> > +
> > +  // HOB region is used for HOB and memory allocation for this module
> > +  MemBase    = PcdGet32 (PcdPayloadFdMemBase);
> > +  HobMemBase = ALIGN_VALUE (MemBase + PcdGet32
> > (PcdPayloadFdMemSize), SIZE_1MB);
> > +  HobMemTop  = HobMemBase + FixedPcdGet32
> > (PcdSystemMemoryUefiRegionSize);
> > +
> > +  // DXE core assumes the memory below HOB region could be used, so include
> > the FV region memory into HOB range.
> > +  MemSize    = HobMemTop - MemBase;
> > +  HandoffHobTable = HobConstructor ((VOID *)MemBase, MemSize, (VOID
> > *)HobMemBase, (VOID *)HobMemTop);
> > +
> > +  // 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..2c84d6ed53
> > --- /dev/null
> > +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
> > @@ -0,0 +1,134 @@
> > +/** @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)))
> > +
> > +/**
> > +  Auto-generated function that calls the library constructors for all of the
> > module's
> > +  dependent libraries.
> > +**/
> > +VOID
> > +EFIAPI
> > +ProcessLibraryConstructorList (
> > +  VOID
> > +  );
> > +
> > +/**
> > +  Add a new HOB to the HOB List.
> > +
> > +  @param HobType            Type of the new HOB.
> > +  @param HobLength          Length of the new HOB to allocate.
> > +
> > +  @return  NULL if there is no space to create a hob.
> > +  @return  The address point to the new created hob.
> > +
> > +**/
> > +VOID *
> > +EFIAPI
> > +CreateHob (
> > +  IN  UINT16    HobType,
> > +  IN  UINT16    HobLength
> > +  );
> > +
> > +/**
> > +  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
> > +  );
> > +
> > +/**
> > +  Build a Handoff Information Table HOB
> > +
> > +  This function initialize a HOB region from EfiMemoryBegin with length
> > +  EfiMemoryLength. And EfiFreeMemoryBottom and EfiFreeMemoryTop
> > should
> > +  be inside the HOB region.
> > +
> > +  @param[in] EfiMemoryBegin       Total memory start address
> > +  @param[in] EfiMemoryLength      Total memory length reported in handoff
> > HOB.
> > +  @param[in] EfiFreeMemoryBottom  Free memory start address
> > +  @param[in] EfiFreeMemoryTop     Free memory end address.
> > +
> > +  @return   The pointer to the handoff HOB table.
> > +
> > +**/
> > +EFI_HOB_HANDOFF_INFO_TABLE*
> > +EFIAPI
> > +HobConstructor (
> > +  IN VOID   *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
> > +  );
> > +
> > +/**
> > +   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
> > +  );
> > +
> > +#endif
> > diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
> > b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
> > new file mode 100644
> > index 0000000000..cc59f1903b
> > --- /dev/null
> > +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
> > @@ -0,0 +1,93 @@
> > +## @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
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                            ##
> > CONSUMES
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize                            ##
> > 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..73ea30e7a2
> > --- /dev/null
> > +++ b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
> > @@ -0,0 +1,107 @@
> > +/** @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;
> > +  VOID                            *GhcbBase;
> > +  UINTN                           GhcbSize;
> > +
> > +  //
> > +  // 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);
> > +
> > +  //
> > +  // Get the address and size of the GHCB pages
> > +  //
> > +  GhcbBase = (VOID *) PcdGet64 (PcdGhcbBase);
> > +  GhcbSize = PcdGet64 (PcdGhcbSize);
> > +
> > +  PageTables = 0;
> > +  if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
> > +    //
> > +    // Create page table and save PageMapLevel4 to CR3
> > +    //
> > +    PageTables = CreateIdentityMappingPageTables ((EFI_PHYSICAL_ADDRESS)
> > (UINTN) BaseOfStack, STACK_SIZE,
> > +                                                  (EFI_PHYSICAL_ADDRESS) (UINTN) GhcbBase,
> > GhcbSize);
> > +  } 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..a1c4ad6ff4
> > --- /dev/null
> > +++ b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c
> > @@ -0,0 +1,939 @@
> > +/** @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.
> > +  @param GhcbBase     Base address of GHCB pages.
> > +  @param GhcbSize     Size of GHCB area.
> > +
> > +  @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,
> > +  IN EFI_PHYSICAL_ADDRESS               GhcbBase,
> > +  IN UINTN                              GhcbSize
> > +  )
> > +{
> > +  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;
> > +    }
> > +  }
> > +
> > +  if (GhcbBase != 0) {
> > +    if ((Address < GhcbBase + GhcbSize) && ((Address + Size) > GhcbBase)) {
> > +      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.
> > +  @param[in]      GhcbBase              GHCB page area base address.
> > +  @param[in]      GhcbSize              GHCB page area size.
> > +
> > +**/
> > +VOID
> > +Split2MPageTo4K (
> > +  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
> > +  IN OUT UINT64                         *PageEntry2M,
> > +  IN EFI_PHYSICAL_ADDRESS               StackBase,
> > +  IN UINTN                              StackSize,
> > +  IN EFI_PHYSICAL_ADDRESS               GhcbBase,
> > +  IN UINTN                              GhcbSize
> > +  )
> > +{
> > +  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;
> > +
> > +    //
> > +    // The GHCB range consists of two pages per CPU, the GHCB and a
> > +    // per-CPU variable page. The GHCB page needs to be mapped as an
> > +    // unencrypted page while the per-CPU variable page needs to be
> > +    // mapped encrypted. These pages alternate in assignment.
> > +    //
> > +    if ((GhcbBase == 0)
> > +        || (PhysicalAddress4K < GhcbBase)
> > +        || (PhysicalAddress4K >= GhcbBase + GhcbSize)
> > +        || (((PhysicalAddress4K - GhcbBase) & SIZE_4KB) != 0)) {
> > +      PageTableEntry->Uint64 |= 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.
> > +  @param[in]      GhcbBase              GHCB page area base address.
> > +  @param[in]      GhcbSize              GHCB page area size.
> > +
> > +**/
> > +VOID
> > +Split1GPageTo2M (
> > +  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
> > +  IN OUT UINT64                         *PageEntry1G,
> > +  IN EFI_PHYSICAL_ADDRESS               StackBase,
> > +  IN UINTN                              StackSize,
> > +  IN EFI_PHYSICAL_ADDRESS               GhcbBase,
> > +  IN UINTN                              GhcbSize
> > +  )
> > +{
> > +  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,
> > GhcbBase, GhcbSize)) {
> > +      //
> > +      // Need to split this 2M page that covers NULL or stack range.
> > +      //
> > +      Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry,
> > StackBase, StackSize, GhcbBase, GhcbSize);
> > +    } 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.
> > +  @param[in] GhcbBase   GHCB base address.
> > +  @param[in] GhcbSize   GHCB size.
> > +
> > +  @return The address of 4 level page map.
> > +
> > +**/
> > +UINTN
> > +CreateIdentityMappingPageTables (
> > +  IN EFI_PHYSICAL_ADDRESS   StackBase,
> > +  IN UINTN                  StackSize,
> > +  IN EFI_PHYSICAL_ADDRESS   GhcbBase,
> > +  IN UINTN                  GhcbSize
> > +  )
> > +{
> > +  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,
> > GhcbBase, GhcbSize)) {
> > +            Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry,
> > StackBase, StackSize, GhcbBase, GhcbSize);
> > +          } 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,
> > GhcbBase, GhcbSize)) {
> > +              //
> > +              // Need to split this 2M page that covers NULL or stack range.
> > +              //
> > +              Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry,
> > StackBase, StackSize, GhcbBase, GhcbSize);
> > +            } 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..6b7c38a441
> > --- /dev/null
> > +++ b/UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.h
> > @@ -0,0 +1,330 @@
> > +/** @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.
> > +  @param[in]      GhcbBase              GHCB page area base address.
> > +  @param[in]      GhcbSize              GHCB page area size.
> > +
> > +**/
> > +VOID
> > +Split2MPageTo4K (
> > +  IN EFI_PHYSICAL_ADDRESS               PhysicalAddress,
> > +  IN OUT UINT64                         *PageEntry2M,
> > +  IN EFI_PHYSICAL_ADDRESS               StackBase,
> > +  IN UINTN                              StackSize,
> > +  IN EFI_PHYSICAL_ADDRESS               GhcbBase,
> > +  IN UINTN                              GhcbSize
> > +  );
> > +
> > +/**
> > +  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.
> > +  @param[in] GhcbBase   GHCB page area base address.
> > +  @param[in] GhcbSize   GHCB page area size.
> > +
> > +  @return The address of 4 level page map.
> > +
> > +**/
> > +UINTN
> > +CreateIdentityMappingPageTables (
> > +  IN EFI_PHYSICAL_ADDRESS   StackBase,
> > +  IN UINTN                  StackSize,
> > +  IN EFI_PHYSICAL_ADDRESS   GhcbBase,
> > +  IN UINTN                  GhcbkSize
> > +  );
> > +
> > +
> > +/**
> > +
> > +  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..a97ace7395 100644
> > --- a/UefiPayloadPkg/UefiPayloadPkg.fdf
> > +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf
> > @@ -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
> >  #
> >  ##
> > @@ -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
>
>
>
> 
>
>


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#70780): https://edk2.groups.io/g/devel/message/70780
Mute This Topic: https://groups.io/mt/78282656/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list