public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Théo Jehl" <theojehl76@gmail.com>
To: devel@edk2.groups.io
Cc: Leif Lindholm <quic_llindhol@quicinc.com>,
	Michael D Kinney <michael.d.kinney@intel.com>,
	Isaac Oram <isaac.w.oram@intel.com>,
	Pedro Falcato <pedro.falcato@gmail.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	Stefan Hajnoczi <stefanha@gmail.com>
Subject: [edk2-devel][edk2-platforms][PATCH V3 1/4] QemuOpenBoardPkg: Add QemuOpenBoardPkg
Date: Tue, 13 Sep 2022 23:31:54 +0200	[thread overview]
Message-ID: <1abf84f82e191df746a7dcf13e0d73eb3aa0ff03.1663104246.git.theojehl76@gmail.com> (raw)
In-Reply-To: <cover.1663104246.git.theojehl76@gmail.com>

QemuOpenBoardPkg adds a MinPlatform port to QEMU x86_64.
This port brings a starting place for understanding the MinPlatform,
and board porting.

This patch adds the base for QemuOpenBoardPkg.
It also enables MinPlatform stage 1 (debug) functionality which
includes serial debug messages.

Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Isaac Oram <isaac.w.oram@intel.com>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Stefan Hajnoczi <stefanha@gmail.com>

Signed-off-by: Theo Jehl <theojehl76@gmail.com>
---
 .../QemuOpenBoardPkg/QemuOpenBoardPkg.dec     |  33 ++
 .../Include/Dsc/Stage1.dsc.inc                |  55 ++++
 .../QemuOpenBoardPkg/QemuOpenBoardPkg.dsc     | 157 ++++++++++
 .../QemuOpenBoardPkg/QemuOpenBoardPkg.fdf     | 203 +++++++++++++
 .../Library/BoardInitLib/BoardInitLib.inf     |  29 ++
 .../Library/PeiReportFvLib/PeiReportFvLib.inf |  63 ++++
 .../Library/PlatformSecLib/PlatformSecLib.inf |  49 +++
 .../QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf     |  23 ++
 .../PlatformInitPei/PlatformInitPei.inf       |  59 ++++
 .../Include/Library/QemuOpenFwCfgLib.h        | 105 +++++++
 .../PlatformInitPei/PlatformInit.h            |  59 ++++
 .../Library/BoardInitLib/BoardInitLib.c       | 231 ++++++++++++++
 .../Library/PeiReportFvLib/PeiReportFvLib.c   | 285 ++++++++++++++++++
 .../Library/PlatformSecLib/PlatformSecLib.c   | 140 +++++++++
 .../QemuOpenFwCfgLib/QemuOpenFwCfgLib.c       | 136 +++++++++
 .../QemuOpenBoardPkg/PlatformInitPei/Cpu.c    |  64 ++++
 .../QemuOpenBoardPkg/PlatformInitPei/Memory.c | 254 ++++++++++++++++
 .../QemuOpenBoardPkg/PlatformInitPei/Pci.c    |  70 +++++
 .../QemuOpenBoardPkg/PlatformInitPei/Pcie.c   | 106 +++++++
 .../PlatformInitPei/PlatformInit.c            |  75 +++++
 .../Include/Fdf/FlashMap.fdf.inc              |  94 ++++++
 .../Library/PlatformSecLib/Ia32/SecEntry.nasm | 117 +++++++
 Platform/Qemu/QemuOpenBoardPkg/README.md      |  53 ++++
 23 files changed, 2460 insertions(+)
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Include/Library/QemuOpenFwCfgLib.h
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.h
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.c
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.c
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Memory.c
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pci.c
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pcie.c
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.c
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/Ia32/SecEntry.nasm
 create mode 100644 Platform/Qemu/QemuOpenBoardPkg/README.md

diff --git a/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec
new file mode 100644
index 000000000000..aa50766172a0
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec
@@ -0,0 +1,33 @@
+## @file QemuOpenBoardPkg.dec
+#  Declaration file for QemuOpenBoardPkg.
+#
+#  This package supports a simple QEMU port implemented per the MinPlatform
+#  Arch specification.
+#
+#  Copyright (c) 2022 Theo Jehl
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#  @par Specification Reference:
+#   -https://tianocore-docs.github.io/edk2-MinimumPlatformSpecification/draft/ 0.7
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = QemuOpenBoardPkg
+  PACKAGE_GUID                   = 3487DE0A-6770-48A2-9833-FB426A42D7B2
+  PACKAGE_VERSION                = 0.1
+
+[LibraryClasses]
+  QemuOpenFwCfgLib|Include/Library/QemuOpenFwCfgLib.h
+
+[Includes]
+  Include
+
+[Guids]
+  gQemuOpenBoardPkgTokenSpaceGuid                     = { 0x221b20c4, 0xa3dc, 0x4b8f, { 0xb6, 0x94, 0x03, 0xc7, 0xf4, 0x76, 0x51, 0x2b } }
+
+[PcdsFixedAtBuild]
+  gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamBase|0|UINT32|0x00000001
+  gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamSize|0|UINT32|0x00000002
+  gQemuOpenBoardPkgTokenSpaceGuid.PcdDebugIoPort|0|UINT16|0x00000003
+  gQemuOpenBoardPkgTokenSpaceGuid.PcdFdVarBlockSize|0|UINT16|0x00000004
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc b/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc
new file mode 100644
index 000000000000..114c4e8193b2
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc
@@ -0,0 +1,55 @@
+## @file
+# Common DSC content to begin Stage 1 enabling
+#
+# @copyright
+# Copyright (C) 2022 Intel Corporation
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+
+[LibraryClasses]
+  PciSegmentInfoLib       | MinPlatformPkg/Pci/Library/PciSegmentInfoLibSimple/PciSegmentInfoLibSimple.inf
+  BoardInitLib            | QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf
+  SetCacheMtrrLib         | MinPlatformPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.inf
+  ReportCpuHobLib         | MinPlatformPkg/PlatformInit/Library/ReportCpuHobLib/ReportCpuHobLib.inf
+  SiliconPolicyInitLib    | MinPlatformPkg/PlatformInit/Library/SiliconPolicyInitLibNull/SiliconPolicyInitLibNull.inf
+  SiliconPolicyUpdateLib  | MinPlatformPkg/PlatformInit/Library/SiliconPolicyUpdateLibNull/SiliconPolicyUpdateLibNull.inf
+  ReportFvLib             | QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
+  PciLib                  | MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+
+[LibraryClasses.Common.SEC]
+  TestPointCheckLib       | MinPlatformPkg/Test/Library/TestPointCheckLib/SecTestPointCheckLib.inf
+  TimerLib                | MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+
+[LibraryClasses.Common.PEI_CORE, LibraryClasses.Common.PEIM]
+  TestPointCheckLib       | MinPlatformPkg/Test/Library/TestPointCheckLib/PeiTestPointCheckLib.inf
+  TestPointLib            | MinPlatformPkg/Test/Library/TestPointLib/PeiTestPointLib.inf
+  TimerLib                | MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+
+[Components.$(PEI_ARCH)]
+  UefiCpuPkg/SecCore/SecCore.inf
+  MdeModulePkg/Core/Pei/PeiMain.inf
+  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+  UefiCpuPkg/CpuIoPei/CpuIoPei.inf
+  MdeModulePkg/Universal/PcatSingleSegmentPciCfg2Pei/PcatSingleSegmentPciCfg2Pei.inf
+  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+    <LibraryClasses>
+      PcdLib | MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+  MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf
+  MinPlatformPkg/PlatformInit/ReportFv/ReportFvPei.inf
+  MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+  QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf
+  !if $(SMM_REQUIRED) == TRUE
+    OvmfPkg/SmmAccess/SmmAccessPei.inf
+  !endif
diff --git a/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc
new file mode 100644
index 000000000000..fc36b9d45ab2
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc
@@ -0,0 +1,157 @@
+## @file
+#  QemuOpenBoardPkg.dsc
+#
+#  Description file for QemuOpenBoardPkg
+#
+#  Copyright (c) 2022 Theo Jehl
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  DSC_SPECIFICATION           = 0x0001001C
+  PLATFORM_GUID               = 94797875-D562-40CF-8D55-ADD623C8D46C
+  PLATFORM_NAME               = QemuOpenBoardPkg
+  PLATFORM_VERSION            = 0.1
+  SUPPORTED_ARCHITECTURES     = IA32 | X64
+  FLASH_DEFINITION            = $(PLATFORM_NAME)/$(PLATFORM_NAME).fdf
+  OUTPUT_DIRECTORY            = Build/$(PLATFORM_NAME)
+  BUILD_TARGETS               = DEBUG | RELEASE | NOOPT
+  SKUID_IDENTIFIER            = ALL
+  SMM_REQUIRED                = FALSE
+
+!ifndef $(PEI_ARCH)
+  !error "PEI_ARCH must be specified to build this feature!"
+!endif
+!ifndef $(DXE_ARCH)
+  !error "DXE_ARCH must be specified to build this feature!"
+!endif
+
+[SkuIds]
+  0 | DEFAULT
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  QemuOpenBoardPkg/QemuOpenBoardPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[PcdsFixedAtBuild]
+  ######################################
+  # Key Boot Stage and FSP configuration
+  ######################################
+  #
+  # Please select the Boot Stage here.
+  # Stage 1 - enable debug (system deadloop after debug init)
+  # Stage 2 - mem init (system deadloop after mem init)
+  # Stage 3 - boot to shell only
+  # Stage 4 - boot to OS
+  # Stage 5 - boot to OS with security boot enabled
+  # Stage 6 - boot with advanced features enabled
+  #
+  gMinPlatformPkgTokenSpaceGuid.PcdBootStage | 1
+
+#
+# MinPlatform common include for required feature PCD
+# These PCD must be set before the core include files, CoreCommonLib,
+# CorePeiLib, and CoreDxeLib.
+# Optional MinPlatformPkg features should be enabled after this
+#
+!include MinPlatformPkg/Include/Dsc/MinPlatformFeaturesPcd.dsc.inc
+
+#
+# Commonly used MinPlatform feature configuration logic that maps functionity to stage
+#
+!include BoardModulePkg/Include/Dsc/CommonStageConfig.dsc.inc
+
+[PcdsFixedAtBuild]
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel                      | 0x802A00C7
+  gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel                 | 0x802A00C7
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask                         | 0x17
+
+  # QEMU "memory" is functional even in SEC.  For simplicity, we just use that
+  # "memory" for the temporary RAM
+  gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamBase                   | 0x1000000
+  gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamSize                   | 0x010000
+
+  gQemuOpenBoardPkgTokenSpaceGuid.PcdDebugIoPort                        | 0x402
+  gEfiMdePkgTokenSpaceGuid.PcdFSBClock                                  | 100000000
+
+  # PCIe base address for Q35 machines
+  # QEMU usable memory below 4G cannot exceed 2.8Gb
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress                     | 0xB0000000
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable             | TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange  | FALSE
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase                      | 0x00000000 # Will be updated by build
+
+[PcdsFeatureFlag]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress         | TRUE
+
+  !if $(DXE_ARCH) == X64
+    gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode            | TRUE
+  !else
+    gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode            | FALSE
+  !endif
+
+  gMinPlatformPkgTokenSpaceGuid.PcdSerialTerminalEnable                 | TRUE
+
+  !if $(SMM_REQUIRED) == TRUE
+    gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire                       | FALSE
+    gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugSupport                      | FALSE
+    gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache        | FALSE
+  !endif
+
+[PcdsDynamicDefault]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId                  | 0
+
+  # Video setup
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution      | 640
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution        | 480
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion                       | 0x0208
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev                        | 0x0
+
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut                       | 3
+
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber             | 0
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber            | 0
+
+  !if $(SMM_REQUIRED) == TRUE
+    gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes                         | 8
+    gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase               | FALSE
+    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode                         | 0x01
+    gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout                    | 100000
+  !endif
+
+# Include Common libraries and then stage specific libraries and components
+!include MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc
+!include MinPlatformPkg/Include/Dsc/CorePeiLib.dsc
+!include MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc
+!include QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc
+
+[LibraryClasses.Common]
+  QemuOpenFwCfgLib        | QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf
+  PlatformHookLib         | MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+  PlatformSecLib          | QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf
+  DebugLib                | MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  PciCf8Lib               | MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  TimerLib                | OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+
+[LibraryClasses.Common.DXE_CORE]
+  TimerLib                | OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+
+[LibraryClasses.Common.DXE_DRIVER, LibraryClasses.Common.DXE_RUNTIME_DRIVER, LibraryClasses.Common.DXE_SMM_DRIVER, LibraryClasses.Common.UEFI_DRIVER, LibraryClasses.Common.UEFI_APPLICATION, LibraryClasses.Common.SMM_CORE]
+  TimerLib                | OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  QemuFwCfgLib            | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf
+  MemEncryptSevLib        | OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf
+  MemEncryptTdxLib        | OvmfPkg/Library/BaseMemEncryptTdxLib/BaseMemEncryptTdxLibNull.inf
+  Tcg2PhysicalPresenceLib | OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf
+  ResetSystemLib          | OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+
+[LibraryClasses.Common.SEC]
+  DebugLib                | OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf
+
+[Components.$(DXE_ARCH)]
diff --git a/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf
new file mode 100644
index 000000000000..0bfad51cb32e
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf
@@ -0,0 +1,203 @@
+## @file
+#  QemuOpenBoardPkg.fdf
+#
+#  Copyright (c) 2022 Theo Jehl
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress      = 0xFF800000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize             = 0x800000
+
+!include QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc
+
+[FD.QemuOpenBoardPkgVars]
+  BaseAddress   = 0xFF800000
+  Size          = 0x80000
+  ErasePolarity = 1
+  BlockSize     = 0x800|gQemuOpenBoardPkgTokenSpaceGuid.PcdFdVarBlockSize
+  NumBlocks     = 0x100
+
+  #
+  # Do not modify this block
+  # These three areas are tightly coupled and should be modified with utmost care.
+  # The total size must match the size in the EFI_FIRMWARE_VOLUME_HEADER in NvStorage512K.fdf.
+  # The NvStorageVariableSize must also match the VARIABLE_STORE_HEADER size in NvStorage512K.fdf.
+  # The EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER in CommonNvStorageFtwWorking.fdf doesn't have size info.
+  #
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset | gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  !include WhitleyOpenBoardPkg/Include/Fdf/NvStorage512K.fdf
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset | gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  !include WhitleyOpenBoardPkg/Include/Fdf/CommonNvStorageFtwWorking.fdf
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset | gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+  DATA = { 0xFF } # Hack to ensure build doesn't treat the next PCD as Base/Size to be written
+
+[FD.QemuOpenBoardPkg]
+  BaseAddress   = 0xFF880000
+  Size          = 0x780000
+  ErasePolarity = 1
+  BlockSize     = 0x1000
+  NumBlocks     = 0x780
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize
+  FV = FvAdvanced
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize
+  FV = FvSecurity
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize
+  FV = FvOsBoot
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize
+  FV = FvUefiBoot
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize
+  FV = FvBsp
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize
+  FV = FvPostMemory
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize
+  FV = FvFspS
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize
+  FV = FvFspM
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize
+  FV = FvFspT
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize
+  FV = FvBspPreMemory
+
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset | gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize
+  FV = FvPreMemory
+
+###########################
+#
+# Stage 1 Firmware Volumes
+#
+###########################
+
+[FV.FvPreMemory]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid      = BD479C6B-2EFF-401F-A7F1-566347B41D07
+
+  FILE FV_IMAGE = 618FBA00-2231-41F6-9931-25A89DF501D3 {
+    SECTION FV_IMAGE = FvSecurityPreMemory
+  }
+
+  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+
+  INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  INF MinPlatformPkg/PlatformInit/ReportFv/ReportFvPei.inf
+
+  INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+  INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+
+  INF UefiCpuPkg/SecCore/SecCore.inf
+
+[FV.FvSecurityPreMemory]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid      = F626B0FB-D759-44A8-B131-42408BB3533D
+
+[FV.FvBspPreMemory]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid      = 5CF9C072-385F-44FC-B21B-002074251C08
+
+  INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+  INF MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPreMem.inf
+  INF QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf
+
+  FILE FV_IMAGE = 90B948EA-FF73-4689-B90A-A54F86C1FC01 {
+    SECTION FV_IMAGE = FvAdvancedPreMemory
+  }
+
+[FV.FvAdvancedPreMemory]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid      = 43528CE0-812B-4074-B77E-C49E7A2F4FE1
+
+[FV.FvFspT]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid      = 958CAF39-0B6C-40F1-B190-EC91C536CFF9
+
+[FV.FvFspM]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid      = 03982cf7-246a-4356-b6ba-436a2251595c
+
+  INF MdeModulePkg/Core/Pei/PeiMain.inf
+
+  FILE FV_IMAGE = 83B39C64-BFB9-42EC-A7A3-527854A5C4C3 {
+      SECTION FV_IMAGE = FvPreMemorySilicon
+  }
+
+[FV.FvPreMemorySilicon]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid    = F0205C0E-0AD1-499C-A5F9-96BAF98248A0
+
+  INF MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
+
+  !if $(SMM_REQUIRED) == TRUE
+    INF OvmfPkg/SmmAccess/SmmAccessPei.inf
+  !endif
+
+[FV.FvFspS]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid    = C6786443-AFCA-471B-A8FC-E8C330708F99
+
+[FV.FvPostMemorySilicon]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid    = EF76DFDC-2B7D-423D-BFE4-8FD4BB22E770
+
+###########################
+#
+# Stage 2 Firmware Volumes
+#
+###########################
+[FV.FvPostMemory]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid    = 5A1D6978-BABE-42F9-A629-F7B3B6A1E1BD
+
+[FV.FvBsp]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid    = FCA0BC4A-994D-4EF9-BD56-A8C45872C2A8
+
+###########################
+#
+# Stage 3 Firmware Volumes
+#
+###########################
+[FV.FvUefiBoot]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid    = D0C15ADB-FE38-4331-841C-0E96C1B0FBFA
+
+###########################
+#
+# Stage 4 Firmware Volumes
+#
+###########################
+[FV.FvOsBoot]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid    = AE8F0EA0-1614-422D-ABC1-C518596F1678
+
+###########################
+#
+# Stage 5 Firmware Volumes
+#
+###########################
+[FV.FvSecurity]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid    = 1AE6AB90-9431-425B-9A92-ED2708A4E982
+
+###########################
+#
+# Stage 6 Firmware Volumes
+#
+###########################
+[FV.FvAdvanced]
+  !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+  FvNameGuid    = 936D6D65-CB6C-4B87-A51C-70D56511CB55
+
+###########################
+#
+# File Construction Rules
+#
+###########################
+!include MinPlatformPkg/Include/Fdf/RuleInclude.fdf
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf
new file mode 100644
index 000000000000..8f75d1277070
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf
@@ -0,0 +1,29 @@
+## @file
+#  QemuOpenBoardPkg BoardInitLib instance
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BoardInitLib
+  FILE_GUID                      = 70EE7BD9-08FF-4D0E-AA7B-4320844F939A
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = BoardInitLib
+
+[Sources]
+  BoardInitLib.c
+
+[Packages]
+  QemuOpenBoardPkg/QemuOpenBoardPkg.dec
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  PcdLib
+  IoLib
+  PciCf8Lib
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf b/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
new file mode 100644
index 000000000000..d416f1c64061
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
@@ -0,0 +1,63 @@
+### @file
+# Component information file for the Report Firmware Volume (FV) library.
+#
+# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiReportFvLib
+  FILE_GUID                      = 44328FA5-E4DD-4A15-ABDF-C6584AC363D9
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = ReportFvLib
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  PeiServicesLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+  QemuOpenBoardPkg/QemuOpenBoardPkg.dec
+
+[Sources]
+  PeiReportFvLib.c
+
+[Pcd]
+  gMinPlatformPkgTokenSpaceGuid.PcdBootStage                      ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFspWrapperBootMode             ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress           ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize                  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryBase           ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize           ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTBase                ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize                ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase                ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize                ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase                ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize                ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase          ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize          ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase              ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize              ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedPreMemoryBase   ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedPreMemorySize   ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize        ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryBase        ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryOffset      ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize                 ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspBase                 ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspOffset               ## CONSUMES
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf
new file mode 100644
index 000000000000..d838ad2b0e9d
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf
@@ -0,0 +1,49 @@
+## @file
+#  PlatformSecLib for QEMU OpenBoardPkg
+#
+#  Copyright (c) 2022 Theo Jehl
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformSecLib
+  FILE_GUID                      = 37b1bddc-5a53-4f2a-af7d-b78d5e80dcbd
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformSecLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources.IA32]
+  Ia32/SecEntry.nasm
+
+[Sources]
+  PlatformSecLib.c
+
+[LibraryClasses]
+  DebugLib
+  BaseLib
+  BaseMemoryLib
+  PciLib
+  PcdLib
+  HobLib
+  MtrrLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  QemuOpenBoardPkg/QemuOpenBoardPkg.dec
+  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[Ppis]
+  gTopOfTemporaryRamPpiGuid
+
+[Pcd]
+  gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamBase
+  gQemuOpenBoardPkgTokenSpaceGuid.PcdTemporaryRamSize
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf b/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf
new file mode 100644
index 000000000000..195191bd7e2c
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf
@@ -0,0 +1,23 @@
+## @file
+#  QemuOpenFwCfgLib.inf
+#
+#  Simple implementation of the QemuFwCfgLib that reads data from the QEMU
+#  FW_CFG device
+#
+#  Copyright (c) 2022 Theo Jehl
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = QemuFwCfgLib
+  FILE_GUID                      = 70EE7BD9-08FF-4D0E-AA7B-4320844F939A
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = QemuOpenFwCfgLib
+
+[Sources]
+  QemuOpenFwCfgLib.c
+
+[LibraryClasses]
+  IoLib
diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf
new file mode 100644
index 000000000000..43b1e13adfeb
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf
@@ -0,0 +1,59 @@
+## @file
+#  PlatformInitPei
+#
+#  Simple PEIM for QEMU PIIX4/Q35 Memory, SMP and PCI/PCI Express initialization
+#
+#  Copyright (c) 2022 Theo Jehl
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformInitPei
+  FILE_GUID                      = 82d851fe-3106-4175-8b6c-87fda1f2d0ac
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PlatformInit
+
+[Packages]
+  OvmfPkg/OvmfPkg.dec
+  MdePkg/MdePkg.dec
+  QemuOpenBoardPkg/QemuOpenBoardPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[Sources]
+  PlatformInit.h
+  PlatformInit.c
+  Memory.c
+  Pcie.c
+  Pci.c
+  Cpu.c
+
+[LibraryClasses]
+  PeimEntryPoint
+  QemuOpenFwCfgLib
+  HobLib
+  PcdLib
+  PciLib
+
+[Guids]
+  gUefiOvmfPkgPlatformInfoGuid
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes
+
+[FeaturePcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[Depex]
+  TRUE
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Include/Library/QemuOpenFwCfgLib.h b/Platform/Qemu/QemuOpenBoardPkg/Include/Library/QemuOpenFwCfgLib.h
new file mode 100644
index 000000000000..8e5f8ccf70e2
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Include/Library/QemuOpenFwCfgLib.h
@@ -0,0 +1,105 @@
+/** @file QemuOpenFwCfgLib.h
+  QemuOpenFwCfgLib Headers
+
+  Implements a minimal library to interact with Qemu FW CFG device
+
+  QEMU FW CFG device allow the OS to retrieve files passed by QEMU or the user.
+  Files can vary from E820 entries to ACPI tables.
+
+  Copyright (c) 2022 Theo Jehl All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+
+#ifndef QEMU_OPEN_BOARD_PKG_QEMU_FW_CFG_LIB_H_
+#define QEMU_OPEN_BOARD_PKG_QEMU_FW_CFG_LIB_H_
+
+#include <PiPei.h>
+#include <Library/IoLib.h>
+
+// QEMU fw_cfg registers
+#define FW_CFG_PORT_SEL   0x510
+#define FW_CFG_PORT_DATA  0x511
+#define FW_CFG_PORT_DMA   0x514
+
+// QEMU Selectors
+#define FW_CFG_SIGNATURE  0x0000
+#define FW_CFG_ID         0x0001
+#define FW_CFG_FILE_DIR   0x0019
+
+#define FW_CFG_QEMU_SIGNATURE SIGNATURE_32('Q', 'E', 'M', 'U')
+
+typedef struct {
+  UINT32    Size;
+  UINT16    Select;
+  UINT16    Reserved;
+  CHAR8     Name[56];
+} QEMU_FW_CFG_FILE;
+
+/**
+  Checks for Qemu fw_cfg device by reading "QEMU" using the signature selector
+
+  @return EFI_SUCCESS - The fw_cfg device is present
+  @return EFI_UNSUPPORTED - The device is absent
+ */
+EFI_STATUS
+EFIAPI
+QemuFwCfgIsPresent (
+  VOID
+  );
+
+/**
+ Sets the selector register to the specified value
+
+  @param[in] Selector
+
+  @return EFI_SUCCESS
+  @return EFI_UNSUPPORTED
+ */
+EFI_STATUS
+EFIAPI
+QemuFwCfgSelectItem (
+  IN UINT16  Selector
+  );
+
+/**
+ Reads 8 bits from the data register
+
+  @return UINT8
+ */
+UINT8
+EFIAPI
+QemuFwCfgRead8 (
+  VOID
+  );
+
+/**
+  Reads N bytes from the data register
+
+  @param Size
+  @param Buffer
+ */
+VOID
+EFIAPI
+QemuFwCfgReadBytes (
+  IN UINTN  Size,
+  OUT VOID  *Buffer
+  );
+
+/**
+  Finds a file in fw_cfg by its name
+
+  @param[in]  String Pointer to an ASCII string to match in the database
+  @param[out] FWConfigFile Buffer for the config file
+
+  @return EFI_STATUS Entry was found, FWConfigFile is populated
+  @return EFI_ERROR Entry was not found
+ */
+EFI_STATUS
+EFIAPI
+QemuFwCfgFindFile (
+  IN  CHAR8              *String,
+  OUT QEMU_FW_CFG_FILE   *FWConfigFile
+  );
+
+#endif // QEMU_OPEN_BOARD_PKG_QEMU_FW_CFG_LIB_H_
diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.h b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.h
new file mode 100644
index 000000000000..771d2f958c40
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.h
@@ -0,0 +1,59 @@
+/** @file PlatformInit.h
+  Headers for PlatformInitPei PEIM
+
+  Copyright (c) 2022 Theo Jehl All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef QEMU_OPEN_BOARD_PKG_PLATFORM_INIT_H_
+#define QEMU_OPEN_BOARD_PKG_PLATFORM_INIT_H_
+
+#include <PiPei.h>
+#include <Uefi.h>
+
+#define PIIX4_PCI_IO_BASE  0xC000
+#define PIIX4_PCI_IO_SIZE  0x4000
+
+#define Q35_PCI_IO_BASE  0x6000
+#define Q35_PCI_IO_SIZE  0xA000
+
+#define PCI_MMIO_TOP_ADDRESS  0xFC000000
+
+EFI_STATUS
+EFIAPI
+PlatformInit (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  );
+
+UINT32
+EFIAPI
+GetMemoryBelow4Gb (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+InstallMemory (
+  IN CONST EFI_PEI_SERVICES  **PeiServices
+  );
+
+EFI_STATUS
+EFIAPI
+InitializePcie (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+InitializePciPIIX4 (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+MaxCpuInit (
+  VOID
+  );
+
+#endif //QEMU_OPEN_BOARD_PKG_PLATFORM_INIT_H_
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c
new file mode 100644
index 000000000000..7dedd4a2a561
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c
@@ -0,0 +1,231 @@
+/** @file
+  Board initialization library
+
+  Copyright (c) 2022 Theo Jehl All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BoardInitLib.h>
+#include <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PciCf8Lib.h>
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/I440FxPiix4.h>
+#include <IndustryStandard/Q35MchIch9.h>
+#include <Library/HobLib.h>
+
+#define QEMU_IO_DEBUG_MAGIC  0xE9
+
+/**
+  This board service detects the board type.
+
+  @retval EFI_SUCCESS   The board was detected successfully.
+  @retval EFI_NOT_FOUND The board could not be detected.
+**/
+EFI_STATUS
+EFIAPI
+BoardDetect (
+  VOID
+  )
+{
+  UINT16  DeviceID, VendorID;
+
+  DEBUG ((DEBUG_INFO, "BoardDetect()\n"));
+
+  //
+  // Retrieve chipset device ID and vendor ID
+  //
+  DeviceID = PciCf8Read16 (PCI_CF8_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET));
+  VendorID = PciCf8Read16 (PCI_CF8_LIB_ADDRESS (0, 0, 0, PCI_VENDOR_ID_OFFSET));
+
+  //
+  //  Qemu can emulate 2 chipsets:
+  //  Intel 440FX with PIIX4 southbridge
+  //  Intel Q35 memory host controller with ICH9 southbridge
+  //
+
+  switch (DeviceID) {
+    case INTEL_82441_DEVICE_ID:
+      DEBUG ((DEBUG_INFO, "Intel 440FX/PIIX4 platform detected!\n"));
+      return EFI_SUCCESS;
+
+    case INTEL_Q35_MCH_DEVICE_ID:
+      DEBUG ((DEBUG_INFO, "Intel Q35 MCH/ICH9 platform detected!\n"));
+      return EFI_SUCCESS;
+
+    default:
+      DEBUG ((DEBUG_ERROR, "Unable to detect board (Device id %u Vendor ID %u)\n", DeviceID, VendorID));
+      return EFI_NOT_FOUND;
+  }
+}
+
+/**
+  This board service initializes board-specific debug devices.
+
+  @retval EFI_SUCCESS   Board-specific debug initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardDebugInit (
+  VOID
+  )
+{
+  return EFI_SUCCESS;
+}
+
+EFI_BOOT_MODE
+EFIAPI
+BoardBootModeDetect (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "BoardBootModeDetect()\n"));
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+  A hook for board-specific initialization prior to memory initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeMemoryInit (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "BoardInitBeforeMemoryInit()\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization after memory initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterMemoryInit (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "BoardInitAfterMemoryInit()\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization prior to disabling temporary RAM.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeTempRamExit (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "BoardInitBeforeTempRamExit()\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization after disabling temporary RAM.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterTempRamExit (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "BoardInitAfterTempRamExit()\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization prior to silicon initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitBeforeSiliconInit (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "BoardInitBeforeSiliconInit()\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization after silicon initialization.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterSiliconInit (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "BoardInitAfterSiliconInit()\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific initialization after PCI enumeration.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitAfterPciEnumeration (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "BoardInitAfterPciEnumeration()\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific functionality for the ReadyToBoot event.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitReadyToBoot (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "BoardInitReadyToBoot()\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  A hook for board-specific functionality for the ExitBootServices event.
+
+  @retval EFI_SUCCESS   The board initialization was successful.
+  @retval EFI_NOT_READY The board has not been detected yet.
+**/
+EFI_STATUS
+EFIAPI
+BoardInitEndOfFirmware (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "BoardInitEndOfFirmware()\n"));
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c b/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
new file mode 100644
index 000000000000..809e69ce4381
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
@@ -0,0 +1,285 @@
+/** @file PeiReportFvLib.c
+  Source code file for Report Firmware Volume (FV) library
+
+  Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ReportFvLib.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Ppi/FirmwareVolumeInfo2.h>
+
+// Use a FV pointer PCD to get a pointer to the FileSystemGuid in the FV header
+#define PCD_TO_FV_HEADER_FILE_SYSTEM_GUID(Pcd)   (&((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN) PcdGet32 (Pcd))->FileSystemGuid)
+
+/**
+  Reports FVs necessary for MinPlarform pre-memory initialization
+ */
+VOID
+ReportPreMemFv (
+  VOID
+  )
+{
+  UINTN                              Index       = 0;
+  EFI_PEI_PPI_DESCRIPTOR             *Descriptor = NULL;
+  EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI  *Ppi        = NULL;
+  EFI_STATUS                         Status      = EFI_SUCCESS;
+  EFI_FIRMWARE_VOLUME_HEADER         *FvHeader   = NULL;
+  EFI_BOOT_MODE                      BootMode    = BOOT_WITH_FULL_CONFIGURATION;
+
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG_CODE (
+    for (Index = 0; Status == EFI_SUCCESS; Index++) {
+      Status = PeiServicesLocatePpi (&gEfiPeiFirmwareVolumeInfo2PpiGuid, Index, &Descriptor, (VOID**) &Ppi);
+      if (!EFI_ERROR (Status)) {
+        FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) Ppi->FvInfo;
+        DEBUG ((DEBUG_INFO, "Found FV at 0x%x, size 0x%x\n", FvHeader, FvHeader->FvLength));
+      }
+    }
+  );
+
+  //
+  // FvBspPreMemory and FvPreMemory are required for all stages.
+  //
+
+  DEBUG ((DEBUG_INFO, "Install FlashFvBspPreMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvBspPreMemoryBase), PcdGet32 (PcdFlashFvBspPreMemorySize)));
+  PeiServicesInstallFvInfo2Ppi (
+                                PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvBspPreMemoryBase),
+                                (VOID *)(UINTN)PcdGet32 (PcdFlashFvBspPreMemoryBase),
+                                PcdGet32 (PcdFlashFvBspPreMemorySize),
+                                NULL,
+                                NULL,
+                                0
+                                );
+
+  DEBUG ((DEBUG_INFO, "Install FlashFvPreMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvPreMemoryBase), PcdGet32 (PcdFlashFvPreMemorySize)));
+  PeiServicesInstallFvInfo2Ppi (
+                                PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvPreMemoryBase),
+                                (VOID *)(UINTN)PcdGet32 (PcdFlashFvPreMemoryBase),
+                                PcdGet32 (PcdFlashFvPreMemorySize),
+                                NULL,
+                                NULL,
+                                0
+                                );
+
+  //
+  // In API mode, do not publish FSP FV.
+  //
+  if (!PcdGetBool (PcdFspWrapperBootMode)) {
+    //
+    // FvFspT may be required for all stages
+    //
+    DEBUG ((DEBUG_INFO, "Install FlashFvFspT - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvFspTBase), PcdGet32 (PcdFlashFvFspTSize)));
+    PeiServicesInstallFvInfo2Ppi (
+                                  PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvFspTBase),
+                                  (VOID *)(UINTN)PcdGet32 (PcdFlashFvFspTBase),
+                                  PcdGet32 (PcdFlashFvFspTSize),
+                                  NULL,
+                                  NULL,
+                                  0
+                                  );
+
+    //
+    // FvFspM required for stage 2 and above
+    //
+    if (PcdGet8 (PcdBootStage) >= 2) {
+      DEBUG ((DEBUG_INFO, "Install FlashFvFspM - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvFspMBase), PcdGet32 (PcdFlashFvFspMSize)));
+      PeiServicesInstallFvInfo2Ppi (
+                                    PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvFspMBase),
+                                    (VOID *)(UINTN)PcdGet32 (PcdFlashFvFspMBase),
+                                    PcdGet32 (PcdFlashFvFspMSize),
+                                    NULL,
+                                    NULL,
+                                    0
+                                    );
+    }
+  }
+
+  //
+  // FvAdvanced not needed until stage 6
+  //
+  if (PcdGet8 (PcdBootStage) >= 6) {
+    DEBUG ((DEBUG_INFO, "Install FlashFvAdvancedPreMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvAdvancedPreMemoryBase), PcdGet32 (PcdFlashFvAdvancedPreMemorySize)));
+    PeiServicesInstallFvInfo2Ppi (
+                                  PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvAdvancedPreMemoryBase),
+                                  (VOID *)(UINTN)PcdGet32 (PcdFlashFvAdvancedPreMemoryBase),
+                                  PcdGet32 (PcdFlashFvAdvancedPreMemorySize),
+                                  NULL,
+                                  NULL,
+                                  0
+                                  );
+  }
+}
+/**
+  Reports FVs for MinPlarform post-memory initialization
+  This function also publish FV HOBs to ensure DXE phase is aware of those FVs
+ */
+VOID
+ReportPostMemFv (
+  VOID
+  )
+{
+  UINTN                              Index       = 0;
+  EFI_PEI_PPI_DESCRIPTOR             *Descriptor = NULL;
+  EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI  *Ppi        = NULL;
+  EFI_STATUS                         Status      = EFI_SUCCESS;
+  EFI_FIRMWARE_VOLUME_HEADER         *FvHeader   = NULL;
+
+  DEBUG_CODE (
+    for (Index = 0; Status == EFI_SUCCESS; Index++) {
+      Status = PeiServicesLocatePpi (&gEfiPeiFirmwareVolumeInfo2PpiGuid, Index, &Descriptor, (VOID**) &Ppi);
+      if (!EFI_ERROR (Status)) {
+        FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) Ppi->FvInfo;
+        DEBUG ((DEBUG_INFO, "Found FV at 0x%x, size 0x%x\n", FvHeader, FvHeader->FvLength));
+      }
+    }
+  );
+
+  //
+  // FvFspS, FvPostMemory, and FvBsp may be required for completing stage 2
+  //
+  if (PcdGet8 (PcdBootStage) >= 2) {
+    //
+    // In API mode, do not publish FSP FV.
+    //
+    if (!PcdGetBool (PcdFspWrapperBootMode)) {
+      DEBUG ((DEBUG_INFO, "Install FlashFvFspS - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvFspSBase), PcdGet32 (PcdFlashFvFspSSize)));
+      PeiServicesInstallFvInfo2Ppi (
+                                    PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvFspSBase),
+                                    (VOID *)(UINTN)PcdGet32 (PcdFlashFvFspSBase),
+                                    PcdGet32 (PcdFlashFvFspSSize),
+                                    NULL,
+                                    NULL,
+                                    0
+                                    );
+    }
+
+    DEBUG ((DEBUG_INFO, "Install FlashFvPostMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvPostMemoryBase), PcdGet32 (PcdFlashFvPostMemorySize)));
+    PeiServicesInstallFvInfo2Ppi (
+                                  PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvPostMemoryBase),
+                                  (VOID *)(UINTN)PcdGet32 (PcdFlashFvPostMemoryBase),
+                                  PcdGet32 (PcdFlashFvPostMemorySize),
+                                  NULL,
+                                  NULL,
+                                  0
+                                  );
+
+    DEBUG ((DEBUG_INFO, "%Build FlashFvPostMemory FV Hob at %Lx \n", (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvPostMemoryBase)));
+
+    BuildFvHob (
+                (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvPostMemoryBase),
+                PcdGet32 (PcdFlashFvPostMemorySize)
+                );
+
+    DEBUG ((DEBUG_INFO, "Install FlashFvBsp - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvBspBase), PcdGet32 (PcdFlashFvBspSize)));
+    PeiServicesInstallFvInfo2Ppi (
+                                  PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvBspBase),
+                                  (VOID *)(UINTN)PcdGet32 (PcdFlashFvBspBase),
+                                  PcdGet32 (PcdFlashFvBspSize),
+                                  NULL,
+                                  NULL,
+                                  0
+                                  );
+  }
+
+  //
+  // FvUefiBoot required for completing stage 3
+  //
+  if (PcdGet8 (PcdBootStage) >= 3) {
+    DEBUG ((DEBUG_INFO, "Install FlashFvUefiBoot - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvUefiBootBase), PcdGet32 (PcdFlashFvUefiBootSize)));
+    PeiServicesInstallFvInfo2Ppi (
+                                  PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvUefiBootBase),
+                                  (VOID *)(UINTN)PcdGet32 (PcdFlashFvUefiBootBase),
+                                  PcdGet32 (PcdFlashFvUefiBootSize),
+                                  NULL,
+                                  NULL,
+                                  0
+                                  );
+
+    DEBUG ((DEBUG_INFO, "%Build FlashFvUefiBoot FV Hob at %Lx \n", (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvUefiBootBase)));
+
+    BuildFvHob (
+                (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvUefiBootBase),
+                PcdGet32 (PcdFlashFvUefiBootSize)
+                );
+  }
+
+  //
+  // FvOsBoot required for completing stage 4
+  //
+  if (PcdGet8 (PcdBootStage) >= 4) {
+    DEBUG ((DEBUG_INFO, "Install FlashFvOsBoot - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvOsBootBase), PcdGet32 (PcdFlashFvOsBootSize)));
+    PeiServicesInstallFvInfo2Ppi (
+                                  PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvOsBootBase),
+                                  (VOID *)(UINTN)PcdGet32 (PcdFlashFvOsBootBase),
+                                  PcdGet32 (PcdFlashFvOsBootSize),
+                                  NULL,
+                                  NULL,
+                                  0
+                                  );
+
+    DEBUG ((DEBUG_INFO, "%Build FlashFvOsBoot FV Hob at %Lx \n", (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvUefiBootBase)));
+
+    BuildFvHob (
+                (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFlashFvOsBootBase),
+                PcdGet32 (PcdFlashFvOsBootSize)
+                );
+  }
+
+  //
+  // FvSecurity required for completing stage 5
+  //
+  if (PcdGet8 (PcdBootStage) >= 5) {
+    DEBUG ((DEBUG_INFO, "Install FlashFvSecurity - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvSecurityBase), PcdGet32 (PcdFlashFvSecuritySize)));
+    PeiServicesInstallFvInfo2Ppi (
+                                  PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvSecurityBase),
+                                  (VOID *)(UINTN)PcdGet32 (PcdFlashFvSecurityBase),
+                                  PcdGet32 (PcdFlashFvSecuritySize),
+                                  NULL,
+                                  NULL,
+                                  0
+                                  );
+  }
+
+  //
+  // FvAdvanced required for completing stage 6
+  //
+  if (PcdGet8 (PcdBootStage) >= 6) {
+    DEBUG ((DEBUG_INFO, "Install FlashFvAdvanced - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvAdvancedBase), PcdGet32 (PcdFlashFvAdvancedSize)));
+    PeiServicesInstallFvInfo2Ppi (
+                                  PCD_TO_FV_HEADER_FILE_SYSTEM_GUID (PcdFlashFvAdvancedBase),
+                                  (VOID *)(UINTN)PcdGet32 (PcdFlashFvAdvancedBase),
+                                  PcdGet32 (PcdFlashFvAdvancedSize),
+                                  NULL,
+                                  NULL,
+                                  0
+                                  );
+  }
+
+  //
+  // Report resource related HOB for flash FV to reserve space in GCD and memory map
+  //
+
+  BuildResourceDescriptorHob (
+                              EFI_RESOURCE_MEMORY_MAPPED_IO,
+                              (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
+                               EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+                               EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+                              (UINTN)PcdGet32 (PcdFlashAreaBaseAddress),
+                              (UINTN)PcdGet32 (PcdFlashAreaSize)
+                              );
+
+  BuildMemoryAllocationHob (
+                            (UINTN)PcdGet32 (PcdFlashAreaBaseAddress),
+                            (UINTN)PcdGet32 (PcdFlashAreaSize),
+                            EfiMemoryMappedIO
+                            );
+}
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.c b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.c
new file mode 100644
index 000000000000..5d56df812c3f
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.c
@@ -0,0 +1,140 @@
+/** @file
+  PlatformSecLib library functions
+
+  Copyright (c) 2022 Theo Jehl All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/TemporaryRamSupport.h>
+#include <Library/PcdLib.h>
+#include <Ppi/PeiCoreFvLocation.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/PlatformSecLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/IoLib.h>
+
+#include <Library/LocalApicLib.h>
+
+EFI_PEI_CORE_FV_LOCATION_PPI  gEfiPeiCoreFvLocationPpi = {
+  (VOID *)FixedPcdGet32 (PcdFlashFvFspMBase)
+};
+
+STATIC EFI_PEI_PPI_DESCRIPTOR  mPeiSecPlatformPpi[] = {
+  //
+  // This must be the second PPI in the list because it will be patched in SecPlatformMain ();
+  //
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gTopOfTemporaryRamPpiGuid,
+    NULL
+  }
+};
+
+EFI_PEI_PPI_DESCRIPTOR  gEfiPeiCoreFvLocationDescriptor = {
+  EFI_PEI_PPI_DESCRIPTOR_PPI,
+  &gEfiPeiCoreFvLocationPpiGuid,
+  &gEfiPeiCoreFvLocationPpi
+};
+
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+  IN OUT   EFI_SEC_PEI_HAND_OFF  *SecCoreData
+  )
+{
+  // Use half of available heap size for PpiList
+  EFI_PEI_PPI_DESCRIPTOR  *PpiList;
+
+  PpiList = (VOID *)((UINTN)SecCoreData->PeiTemporaryRamBase + (UINTN)SecCoreData->PeiTemporaryRamSize / 2);
+
+  CopyMem (PpiList, &gEfiPeiCoreFvLocationDescriptor, sizeof (EFI_PEI_PPI_DESCRIPTOR));
+
+  CopyMem (&PpiList[1], &mPeiSecPlatformPpi, sizeof (EFI_PEI_PPI_DESCRIPTOR));
+
+  // Patch the top of RAM PPI
+  PpiList[1].Ppi = (VOID *)((UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize);
+  DEBUG ((DEBUG_INFO, "SecPlatformMain(): Top of memory %p\n", PpiList[1].Ppi));
+
+  return PpiList;
+}
+
+/**
+  This interface conveys state information out of the Security (SEC) phase into PEI.
+
+  @param  PeiServices               Pointer to the PEI Services Table.
+  @param  StructureSize             Pointer to the variable describing size of the input buffer.
+  @param  PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+  @retval EFI_SUCCESS           The data was successfully returned.
+  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+  IN CONST EFI_PEI_SERVICES                  **PeiServices,
+  IN OUT   UINT64                            *StructureSize,
+  OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord
+  )
+{
+  UINT32      TopOfTemporaryRam;
+  VOID        *TopOfRamPpi;
+  EFI_STATUS  Status;
+  UINT32      Count;
+  UINT32      *BistStart;
+  UINT32      Length;
+
+  Status = (*PeiServices)->LocatePpi (PeiServices, &gTopOfTemporaryRamPpiGuid, 0, NULL, &TopOfRamPpi);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  TopOfTemporaryRam = (UINT32)TopOfRamPpi;
+
+  DEBUG ((DEBUG_INFO, "SecPlatformInformation: Top of memory is %p\n", TopOfRamPpi));
+
+  Count  = *(UINT32 *)(TopOfTemporaryRam - sizeof (UINT32));
+  Length = Count * sizeof (UINT32);
+
+  BistStart = (UINT32 *)(TopOfTemporaryRam - sizeof (UINT32) - Length);
+
+  DEBUG ((DEBUG_INFO, "SecPlatformInformation: Found %u processors with BISTs starting at %p\n", Count, BistStart));
+
+  if (*StructureSize < Length) {
+    *StructureSize = Length;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  CopyMem (PlatformInformationRecord, BistStart, Length);
+  *StructureSize = Length;
+
+  // Mask the PIC to avoid any interruption down the line
+  IoWrite8 (0x21, 0xff);
+  IoWrite8 (0xA1, 0xff);
+
+  DEBUG ((DEBUG_INFO, "Initialize APIC Timer \n"));
+  InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
+
+  DEBUG ((DEBUG_INFO, "Disable APIC Timer interrupt\n"));
+  DisableApicTimerInterrupt ();
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This interface disables temporary memory in SEC Phase.
+**/
+VOID
+EFIAPI
+SecPlatformDisableTemporaryMemory (
+  VOID
+  )
+{
+  return;
+}
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.c b/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.c
new file mode 100644
index 000000000000..4733a2899329
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgLib.c
@@ -0,0 +1,136 @@
+/** @file QemuOpenFwCfgLib.c
+  QemuOpenFwCfgLib library
+
+  Implements a minimal library to interact with Qemu FW CFG device
+
+  QEMU FW CFG device allow the OS to retrieve files passed by QEMU or the user.
+  Files can vary from E820 entries to ACPI tables.
+
+  Copyright (c) 2022 Theo Jehl All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/QemuOpenFwCfgLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+/**
+  Reads 8 bits from the data register.
+
+  @retval UINT8
+**/
+UINT8
+EFIAPI
+QemuFwCfgRead8 (
+  VOID
+  )
+{
+  return IoRead8 (FW_CFG_PORT_DATA);
+}
+
+/**
+  Sets the selector register to the specified value
+
+  @param Selector
+
+  @retval EFI_SUCCESS
+  @retval EFI_UNSUPPORTED
+**/
+EFI_STATUS
+EFIAPI
+QemuFwCfgSelectItem (
+  IN UINT16  Selector
+  )
+{
+  UINT16  WritenSelector;
+
+  WritenSelector = IoWrite16 (FW_CFG_PORT_SEL, Selector);
+
+  if (WritenSelector != Selector) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads N bytes from the data register
+
+  @param Size
+  @param Buffer
+**/
+VOID
+EFIAPI
+QemuFwCfgReadBytes (
+  IN UINTN  Size,
+  OUT VOID  *Buffer
+  )
+{
+  IoReadFifo8 (FW_CFG_PORT_DATA, Size, Buffer);
+}
+
+/**
+  Checks for Qemu fw_cfg device by reading "QEMU" using the signature selector
+
+  @retval EFI_SUCCESS - The fw_cfg device is present
+  @retval EFI_UNSUPPORTED - The device is absent
+**/
+EFI_STATUS
+EFIAPI
+QemuFwCfgIsPresent (
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      Control;
+
+  Status = QemuFwCfgSelectItem (FW_CFG_SIGNATURE);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  QemuFwCfgReadBytes (4, &Control);
+  if (Control != FW_CFG_QEMU_SIGNATURE) {
+    ASSERT (Control == FW_CFG_QEMU_SIGNATURE);
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Finds a file in fw_cfg by its name
+
+  @param String Pointer to an ASCII string to match in the database
+  @param FWConfigFile Buffer for the config file
+
+  @retval EFI_STATUS Entry was found, FWConfigFile is populated
+  @retval EFI_ERROR Entry was not found
+**/
+EFI_STATUS
+EFIAPI
+QemuFwCfgFindFile (
+  IN  CHAR8             *String,
+  OUT QEMU_FW_CFG_FILE  *FWConfigFile
+  )
+{
+  QEMU_FW_CFG_FILE  FirmwareConfigFile;
+  UINT32            FilesCount;
+  UINT32            Idx;
+
+  QemuFwCfgSelectItem (FW_CFG_FILE_DIR);
+  QemuFwCfgReadBytes (sizeof (UINT32), &FilesCount);
+
+  FilesCount = SwapBytes32 (FilesCount);
+
+  for (Idx = 0; Idx < FilesCount; Idx++) {
+    QemuFwCfgReadBytes (sizeof (QEMU_FW_CFG_FILE), &FirmwareConfigFile);
+    if (AsciiStrCmp ((CHAR8 *)&(FirmwareConfigFile.Name), String) == 0) {
+      FirmwareConfigFile.Select = SwapBytes16 (FirmwareConfigFile.Select);
+      FirmwareConfigFile.Size   = SwapBytes32 (FirmwareConfigFile.Size);
+      CopyMem (FWConfigFile, &FirmwareConfigFile, sizeof (QEMU_FW_CFG_FILE));
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_UNSUPPORTED;
+}
diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c
new file mode 100644
index 000000000000..e203b2654226
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c
@@ -0,0 +1,64 @@
+/** @file Cpu.c
+  CPU Count initialization
+
+  Copyright (c) 2022 Theo Jehl All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PlatformInit.h"
+#include <IndustryStandard/Pci.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/QemuOpenFwCfgLib.h>
+#include <IndustryStandard/QemuFwCfg.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Acpi30.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+
+/**
+  Probe Qemu FW CFG device for current CPU count and report to MpInitLib.
+
+  @return EFI_SUCCESS      Detection was successful.
+  @retval EFI_UNSUPPORTED  QEMU FW CFG device is not present.
+ */
+EFI_STATUS
+EFIAPI
+MaxCpuInit (
+  VOID
+  )
+{
+  UINT16      BootCpuCount;
+  EFI_STATUS  Status;
+
+  Status = QemuFwCfgIsPresent ();
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "QemuFwCfg not present, unable to detect CPU count \n"));
+    ASSERT_EFI_ERROR (Status);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  //  Probe Qemu FW CFG device for CPU count
+  //
+
+  Status = QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount);
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  QemuFwCfgReadBytes (sizeof (BootCpuCount), &BootCpuCount);
+
+  //
+  //  Report count to MpInitLib
+  //
+
+  PcdSet32S (PcdCpuBootLogicalProcessorNumber, BootCpuCount);
+
+  PcdSet32S (PcdCpuMaxLogicalProcessorNumber, 64);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Memory.c b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Memory.c
new file mode 100644
index 000000000000..21705256191b
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Memory.c
@@ -0,0 +1,254 @@
+/** @file Memory.c
+  Memory probing and installation
+
+  Copyright (c) 2022 Theo Jehl All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PlatformInit.h>
+#include <Library/DebugLib.h>
+#include <Library/QemuOpenFwCfgLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/HobLib.h>
+#include <IndustryStandard/E820.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+
+/**
+  Return the memory size below 4GB.
+
+  @return Size of memory below 4GB, in bytes.
+**/
+UINT32
+EFIAPI
+GetMemoryBelow4Gb (
+  VOID
+  )
+{
+  EFI_E820_ENTRY64  E820Entry;
+  QEMU_FW_CFG_FILE  FwCfgFile;
+  UINT32            Processed;
+  UINT64            Size;
+  EFI_STATUS        Status;
+
+  Status = QemuFwCfgIsPresent ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = QemuFwCfgFindFile ("etc/e820", &FwCfgFile);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Size = 0;
+  QemuFwCfgSelectItem (FwCfgFile.Select);
+  for (Processed = 0; Processed < FwCfgFile.Size / sizeof (EFI_E820_ENTRY); Processed++) {
+    QemuFwCfgReadBytes (sizeof (EFI_E820_ENTRY), &E820Entry);
+    if (E820Entry.Type != EfiAcpiAddressRangeMemory) {
+      continue;
+    }
+
+    if (E820Entry.BaseAddr + E820Entry.Length < SIZE_4GB) {
+      Size += E820Entry.Length;
+    } else {
+      ASSERT (Size == (UINT32)Size);
+      return (UINT32) Size;
+    }
+  }
+
+  ASSERT (Size == (UINT32)Size);
+  return (UINT32) Size;
+}
+
+/**
+  Reserve an MMIO region.
+
+  @param[in] Start  Start of the MMIO region.
+  @param[in] Length Length of the MMIO region.
+**/
+STATIC
+VOID
+ReserveMmioRegion (
+  EFI_PHYSICAL_ADDRESS  Start,
+  UINT64                Length
+  )
+{
+  EFI_RESOURCE_TYPE            ResourceType;
+  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttributes;
+
+  ResourceAttributes = EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_TESTED;
+  ResourceType       = EFI_RESOURCE_MEMORY_MAPPED_IO;
+
+  BuildResourceDescriptorHob (
+    ResourceType,
+    ResourceAttributes,
+    Start,
+    Length
+    );
+}
+
+/**
+  Install EFI memory by probing QEMU FW CFG devices for valid E820 entries.
+  It also reserves space for MMIO regions such as VGA, BIOS and APIC.
+
+  @param[in] PeiServices      PEI Services pointer.
+
+  @retval EFI_SUCCESS     Memory initialization succeded.
+  @retval EFI_UNSUPPORTED Installation failed (etc/e820 file was not found).
+  @retval EFI_NOT_FOUND   QEMU FW CFG device is not present.
+**/
+EFI_STATUS
+EFIAPI
+InstallMemory (
+  IN CONST EFI_PEI_SERVICES  **PeiServices
+  )
+{
+  EFI_STATUS                   Status;
+  CONST EFI_PEI_SERVICES       **PeiServicesTable;
+  EFI_E820_ENTRY64             E820Entry;
+  EFI_E820_ENTRY64             LargestE820Entry;
+  QEMU_FW_CFG_FILE             FwCfgFile;
+  UINT32                       Processed;
+  BOOLEAN                      ValidMemory;
+  EFI_RESOURCE_TYPE            ResourceType;
+  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttributes;
+  UINT32                       MemoryBelow4G;
+  UINT32                       RequiredBySmm;
+
+  Status = QemuFwCfgIsPresent ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "QEMU fw_cfg device is not present\n"));
+    return EFI_NOT_FOUND;
+  } else {
+    DEBUG ((DEBUG_INFO, "QEMU fw_cfg device is present\n"));
+  }
+
+  Status = QemuFwCfgFindFile ("etc/e820", &FwCfgFile);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "etc/e820 was not found \n"));
+    return EFI_UNSUPPORTED;
+  }
+
+  MemoryBelow4G = GetMemoryBelow4Gb ();
+
+  LargestE820Entry.Length = 0;
+  QemuFwCfgSelectItem (FwCfgFile.Select);
+  for (Processed = 0; Processed < FwCfgFile.Size / sizeof (EFI_E820_ENTRY); Processed++) {
+    QemuFwCfgReadBytes (sizeof (EFI_E820_ENTRY), &E820Entry);
+
+    ValidMemory        = E820Entry.Type == EfiAcpiAddressRangeMemory;
+    ResourceType       = EFI_RESOURCE_MEMORY_RESERVED;
+    ResourceAttributes = EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_TESTED;
+
+    if (ValidMemory) {
+      if (FeaturePcdGet (PcdSmmSmramRequire) && (E820Entry.BaseAddr + E820Entry.Length == MemoryBelow4G)) {
+        RequiredBySmm = PcdGet16 (PcdQ35TsegMbytes) * SIZE_1MB;
+        if (E820Entry.Length < RequiredBySmm) {
+          DEBUG ((
+            DEBUG_ERROR,
+            "Error: There's not enough memory below TOLUD for SMM (%lx < %x)\n",
+            E820Entry.Length,
+            RequiredBySmm
+            ));
+        }
+
+        E820Entry.Length -= RequiredBySmm;
+        DEBUG ((
+          DEBUG_INFO,
+          "SMM is enabled! Stealing [%lx, %lx](%u MiB) for SMRAM...\n",
+          E820Entry.BaseAddr + E820Entry.Length,
+          E820Entry.BaseAddr + E820Entry.Length + RequiredBySmm - 1,
+          PcdGet16 (PcdQ35TsegMbytes)
+          ));
+      }
+
+      ResourceType       = EFI_RESOURCE_SYSTEM_MEMORY;
+      ResourceAttributes = 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_RESOURCE_ATTRIBUTE_TESTED;
+
+      //
+      // Lets handle the lower 1MB in a special way
+      //
+
+      if (E820Entry.BaseAddr == 0) {
+        //
+        // 0 - 0xa0000 is system memory, everything above that up to 1MB is not
+        // Note that we check if we actually have 1MB
+        //
+
+        BuildResourceDescriptorHob (
+          ResourceType,
+          ResourceAttributes,
+          0,
+          MIN (0xa0000, E820Entry.Length)
+          );
+
+        E820Entry.BaseAddr += BASE_1MB;
+        E820Entry.Length   -= MIN (BASE_1MB, E820Entry.Length);
+      }
+
+      //
+      // Note that we can only check if this is the largest entry after reserving everything we have to reserve
+      //
+
+      if ((E820Entry.Length > LargestE820Entry.Length) && (E820Entry.BaseAddr + E820Entry.Length <= SIZE_4GB)) {
+        CopyMem (&LargestE820Entry, &E820Entry, sizeof (EFI_E820_ENTRY64));
+        DEBUG ((
+          DEBUG_INFO,
+          "New largest entry for PEI: BaseAddress %lx, Size %lx\n",
+          LargestE820Entry.BaseAddr,
+          LargestE820Entry.Length
+          ));
+      }
+    }
+
+    BuildResourceDescriptorHob (
+      ResourceType,
+      ResourceAttributes,
+      E820Entry.BaseAddr,
+      E820Entry.Length
+      );
+
+    DEBUG ((
+      DEBUG_INFO,
+      "Processed E820 entry [%lx, %lx] with type %x\n",
+      E820Entry.BaseAddr,
+      E820Entry.BaseAddr + E820Entry.Length - 1,
+      E820Entry.Type
+      ));
+  }
+
+  ASSERT (LargestE820Entry.Length != 0);
+  DEBUG ((
+    DEBUG_INFO,
+    "Largest memory chunk found: [%lx, %lx]\n",
+    LargestE820Entry.BaseAddr,
+    LargestE820Entry.BaseAddr + LargestE820Entry.Length - 1
+    ));
+
+  PeiServicesTable = GetPeiServicesTablePointer ();
+
+  Status = (*PeiServices)->InstallPeiMemory (PeiServicesTable, LargestE820Entry.BaseAddr, LargestE820Entry.Length);
+
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  //  Reserve architectural PC MMIO regions
+  //  VGA space + BIOS shadow mapping
+  //
+
+  ReserveMmioRegion (0xa0000, 0x100000 - 0xa0000);
+
+  //
+  // IO APIC and LAPIC space
+  //
+
+  ReserveMmioRegion (0xfec00000, 0xff000000 - 0xfec00000);
+  return Status;
+}
diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pci.c b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pci.c
new file mode 100644
index 000000000000..4e6b784d9890
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pci.c
@@ -0,0 +1,70 @@
+/** @file Pci.c
+  PCI Initialization for PIIX4 QEMU
+
+  Copyright (c) 2022 Theo Jehl All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PlatformInit.h"
+#include <IndustryStandard/Pci.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/QemuOpenFwCfgLib.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Acpi30.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+
+/**
+  Initialize PCI support for QEMU PIIX4 machine.
+
+  It also publishes PCI MMIO and IO ranges PCDs for OVMF PciHostBridgeLib.
+
+  @retval EFI_SUCCESS      Initialization was a success.
+  @retval EFI_UNSUPPORTED  Initialization failed (Memory below 4Gb probing failed).
+**/
+EFI_STATUS
+EFIAPI
+InitializePciPIIX4 (
+  VOID
+  )
+{
+  UINTN  PciIoBase;
+  UINTN  PciIoSize;
+  UINTN  PciMmio32Base;
+  UINTN  PciMmio32Size;
+
+  //
+  //  Setup PCI IO ranges for 440FX/PIIX4 platform
+  //
+  PciIoBase = PIIX4_PCI_IO_BASE;
+  PciIoSize = PIIX4_PCI_IO_SIZE;
+
+  PcdSet64S (PcdPciIoBase, PciIoBase);
+  PcdSet64S (PcdPciIoSize, PciIoSize);
+
+  //
+  //  QEMU only allow a maximum of 2.8Gb of real memory below 4G
+  //  PCI MMIO range below 4Gb starts at the end of real memory below 4G
+  //
+  PciMmio32Base = (UINTN)GetMemoryBelow4Gb ();
+
+  if (PciMmio32Base == 0) {
+    DEBUG ((DEBUG_ERROR, "Unable to detect memory below 4Gb\n"));
+    ASSERT (PciMmio32Base != 0);
+    return EFI_UNSUPPORTED;
+  }
+
+  DEBUG ((DEBUG_ERROR, "Memory below 4Gb: %x \n", PciMmio32Base));
+
+  //
+  // Maximum size being PCI_MMIO_TOP_ADDRESS - TopOfLowMem to avoid overlapping with IO-APIC and other hardware mmio ranges
+  //
+  PciMmio32Size = PCI_MMIO_TOP_ADDRESS - PciMmio32Base;
+
+  PcdSet64S (PcdPciMmio32Base, PciMmio32Base);
+  PcdSet64S (PcdPciMmio32Size, PciMmio32Size);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pcie.c b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pcie.c
new file mode 100644
index 000000000000..0a5f0ff398de
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pcie.c
@@ -0,0 +1,106 @@
+/** @file Pcie.c
+  PCI Express initialization for QEMU Q35
+
+  Copyright (c) 2022 Theo Jehl All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PlatformInit.h"
+#include <IndustryStandard/Pci.h>
+#include <Library/PciCf8Lib.h>
+#include <IndustryStandard/Q35MchIch9.h>
+#include <Library/QemuOpenFwCfgLib.h>
+#include <IndustryStandard/QemuFwCfg.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Acpi30.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+
+/**
+  Initialize PCI Express support for QEMU Q35 system.
+  It also publishes PCI MMIO and IO ranges PCDs for OVMF PciHostBridgeLib.
+
+  @retval EFI_SUCCESS Initialization was successful
+**/
+EFI_STATUS
+EFIAPI
+InitializePcie (
+  VOID
+  )
+{
+  UINTN  PciBase;
+  UINTN  PciSize;
+  UINTN  PciIoBase;
+  UINTN  PciIoSize;
+
+  union {
+    UINT64    Uint64;
+    UINT32    Uint32[2];
+  } PciExBarBase;
+
+  PciExBarBase.Uint64 = FixedPcdGet64 (PcdPciExpressBaseAddress);
+
+  //
+  // Build a reserved memory space for PCIE MMIO
+  //
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_RESERVED,
+    EFI_RESOURCE_ATTRIBUTE_PRESENT |
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_TESTED,
+    PciExBarBase.Uint64,
+    SIZE_256MB
+    );
+
+  BuildMemoryAllocationHob (
+    PciExBarBase.Uint64,
+    SIZE_256MB,
+    EfiReservedMemoryType
+    );
+
+  //
+  // Clear lower 32 bits of register
+  //
+  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0);
+
+  //
+  // Program PCIE MMIO Base address in MCH PCIEXBAR register
+  //
+  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[1]);
+
+  //
+  // Enable 256Mb MMIO space
+  //
+  PciWrite32 (
+    DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW),
+    PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN
+    );
+
+  //
+  // Disable PCI/PCIe MMIO above 4Gb
+  //
+  PcdSet64S (PcdPciMmio64Size, 0);
+
+  //
+  // Set Pci MMIO space below 4GB
+  //
+  PciBase = (UINTN)(PcdGet64 (PcdPciExpressBaseAddress) + SIZE_256MB);
+  PciSize = PCI_MMIO_TOP_ADDRESS - PciBase;
+
+  PcdSet64S (PcdPciMmio32Base, PciBase);
+  PcdSet64S (PcdPciMmio32Size, PciSize);
+
+  //
+  // Set Pci IO port range
+  //
+  PciIoBase = Q35_PCI_IO_BASE;
+  PciIoSize = Q35_PCI_IO_SIZE;
+
+  PcdSet64S (PcdPciIoBase, PciIoBase);
+  PcdSet64S (PcdPciIoSize, PciIoSize);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.c b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.c
new file mode 100644
index 000000000000..7849298b52d5
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.c
@@ -0,0 +1,75 @@
+/** @file PlarformInit.c
+  Platform initialization PEIM for QEMU
+
+  Copyright (c) 2022 Theo Jehl All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PlatformInit.h"
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include "Library/DebugLib.h"
+#include <Library/PlatformInitLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciCf8Lib.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/Q35MchIch9.h>
+
+EFI_STATUS
+EFIAPI
+PlatformInit (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS             Status;
+  UINT16                 DeviceId;
+  EFI_HOB_PLATFORM_INFO  *EfiPlatformInfo;
+
+  //
+  // Install permanent memory
+  //
+  Status = InstallMemory (PeiServices);
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Memory installation failed\n"));
+    return Status;
+  } else {
+    DEBUG ((DEBUG_INFO, "Memory installation success\n"));
+  }
+
+  //
+  // Report CPU core count to MPInitLib
+  //
+  MaxCpuInit ();
+
+  EfiPlatformInfo = AllocateZeroPool (sizeof (EFI_HOB_PLATFORM_INFO));
+  if (EfiPlatformInfo == NULL) {
+    DEBUG ((DEBUG_ERROR, "Failed to allocate pool for EFI_HOB_PLATFORM_INFO\n"));
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Report gUefiOvmfPkgPlatformInfo HOB with only the necessary data for OVMF
+  //
+  DeviceId = PciCf8Read16 (PCI_CF8_LIB_ADDRESS (0, 0, 0, PCI_DEVICE_ID_OFFSET));
+  DEBUG ((DEBUG_INFO, "Building gUefiOvmfPkgPlatformInfoGuid with Host bridge dev ID %x \n", DeviceId));
+  (*EfiPlatformInfo).HostBridgeDevId = DeviceId;
+
+  BuildGuidDataHob (&gUefiOvmfPkgPlatformInfoGuid, EfiPlatformInfo, sizeof (EFI_HOB_PLATFORM_INFO));
+
+  PcdSet16S (PcdOvmfHostBridgePciDevId, DeviceId);
+
+  //
+  // Initialize PCI or PCIe based on current emulated system
+  //
+  if (DeviceId == INTEL_Q35_MCH_DEVICE_ID) {
+    DEBUG ((DEBUG_INFO, "Q35: Initialize PCIe\n"));
+    return InitializePcie ();
+  } else {
+    DEBUG ((DEBUG_INFO, "PIIX4: Initialize PCI\n"));
+    return InitializePciPIIX4 ();
+  }
+}
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc b/Platform/Qemu/QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc
new file mode 100644
index 000000000000..6797e223fca4
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc
@@ -0,0 +1,94 @@
+## @file
+# Flashmap and variable definitions for QemuOpenBoardPkg FVs and FD
+#
+# @copyright
+# Copyright (C) 2022 Theo Jehl
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+#
+# These three items are tightly coupled.
+# The spare area size must be >= the first two areas.
+# The total size must match the size in the EFI_FIRMWARE_VOLUME_HEADER.
+# The NvStorageVariableSize must also match the VARIABLE_STORE_HEADER size.
+# The EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER doesn't have size info.
+#
+# There isn't really a benefit to a larger spare area unless the FLASH device
+# block size is larger than the size specified.
+#
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize    = 0x0003C000
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize  = 0x00004000
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize    = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+
+#
+# Early FV
+#
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize           = 0x00081000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize        = 0x00040000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize                = 0x00010000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize                = 0x00040000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize                = 0x00020000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize          = 0x00080000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize                 = 0x00020000
+
+#
+# Later FV
+#
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize            = 0x00400000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize              = 0x00100000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize            = 0x00080000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize            = gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemorySize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize - gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize
+
+#
+# Calculate Offsets Once (Do not modify)
+# This layout is specified by the EDK II Minimum Platform Archicture specification.
+# Each offset is the prior region's offset plus the prior region's size.
+#
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset   = 0x00000000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset = gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageVariableOffset   + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset   = gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingOffset + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset          = 0x00000000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset          = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset          + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset            = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityOffset          + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset          = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootOffset            + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspOffset               = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootOffset          + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset        = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspOffset               + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset              = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryOffset        + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset              = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSOffset              + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset              = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMOffset              + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryOffset      = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTOffset              + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryOffset         = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryOffset      + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize
+
+#
+# Calculate base addresses
+# QemuOpenBoardPkgVars FD
+#
+
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase    = gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase  = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase    + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase    = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase  + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase      = gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase    = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize  + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase      = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase  +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+
+#
+# QemuOpenBoardPkg FD
+#
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase            = gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress           + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase            = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase            + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase              = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase            + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase            = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase              + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspBase                 = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase            + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase          = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspBase                 + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase                = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase          + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase                = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase                + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTBase                = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase                + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryBase        = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTBase                + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPreMemoryBase           = gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemoryBase        + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvBspPreMemorySize
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/Ia32/SecEntry.nasm b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/Ia32/SecEntry.nasm
new file mode 100644
index 000000000000..8ee8809ed0f5
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/Ia32/SecEntry.nasm
@@ -0,0 +1,117 @@
+;------------------------------------------------------------------------------
+;  @file SecEntry
+;  Sec entry implementation
+;
+;  Copyright (c) 2022 Theo Jehl
+;  SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+CODE_SEG equ CodeSegDescriptor - GDT_START
+DATA_SEG equ DataSegDescriptor - GDT_START
+
+extern ASM_PFX(SecStartup)
+
+extern ASM_PFX(PcdGet32 (PcdTemporaryRamBase))
+extern ASM_PFX(PcdGet32 (PcdTemporaryRamSize))
+
+SECTION .text
+
+BITS 16
+align 4
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+  cli
+  ; Save the BIST in mm0
+  movd mm0, eax
+  mov esi, GDT_Descriptor
+  db 66h
+  lgdt [cs:si]
+
+  mov     eax, cr0
+  or      eax, 1
+  mov     cr0, eax
+
+  mov ax, DATA_SEG
+  mov ds, ax
+  mov es, ax
+  mov fs, ax
+  mov gs, ax
+  mov ss, ax
+
+  mov esi, ProtectedModeEntryLinearAddress
+
+  jmp dword far [cs:si]
+
+BITS 32
+align 4
+ProtectedModeEntry:
+  PROTECTED_MODE equ $
+
+  mov ecx, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))]
+  mov edx, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))]
+
+  ; Initialize the stack at the end of base + size
+  mov esp, ecx
+  add esp, edx
+
+  ; Push 1 CPU, will be probed later with Qemu FW CFG device
+  push 1
+  ; For now, we push the BIST once
+  movd eax, mm0
+  push eax
+  ; Code in PlatformSecLib will look up this information we've just pushed
+  ;  ================= TOP OF MEMORY ======================
+  ;                    Count of BISTs
+  ;                    BISTs[1..n]
+  ;  ================= REST OF MEMORY =====================
+  ; Each BIST is always a DWORD in size
+
+  mov edi, 0xFFFFFFFC         ;BFV
+
+  push DWORD [edi]            ;Passes BFV
+
+  push ecx                    ;Passes RAM size
+
+  push edx                    ;Passes RAM base
+
+  call ASM_PFX(SecStartup)
+
+align 8
+NULL_SEGMENT    equ $ - GDT_START
+GDT_START:
+
+NullSegDescriptor:
+  dd 0x0
+  dd 0x0
+
+  CODE_SEL        equ $ - GDT_START
+
+CodeSegDescriptor:
+  dw 0xFFFF
+  dw 0x0
+  db 0x0
+  db 0x9B
+  db 0xCF
+  db 0x0
+
+  DATA_SEL        equ $ - GDT_START
+
+DataSegDescriptor:
+  dw 0xFFFF
+  dw 0x0
+  db 0x0
+  db 0x93
+  db 0xCF
+  db 0x0
+
+GDT_END:
+
+GDT_Descriptor:
+  dw GDT_END - GDT_START - 1
+  dd GDT_START
+
+ProtectedModeEntryLinearAddress:
+ProtectedModeEntryLinear:
+  DD      ProtectedModeEntry  ; Offset of our 32 bit code
+  DW      CODE_SEL
diff --git a/Platform/Qemu/QemuOpenBoardPkg/README.md b/Platform/Qemu/QemuOpenBoardPkg/README.md
new file mode 100644
index 000000000000..e1238c1f4e3e
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/README.md
@@ -0,0 +1,53 @@
+# QemuOpenBoardPkg
+
+This project brings UEFI support to QEMU x86_64 following the MinPlatform specification.
+
+## Capabilities
+
+- Supports IA-32 and hybrid X64 (IA32 PEI Core and X64 DXE Core)
+- Modern QEMU (Tested on 7.0.0)
+  - PIIX4 and Q35 machines
+- Boot UEFI Linux
+- Boot UEFI Windows
+
+## How to build
+
+### Pre-requesites
+
+- EDK2
+  - How to setup a local tree: https://github.com/tianocore/tianocore.github.io/wiki/Getting-Started-with-EDK-II
+
+- EDK2 Platforms
+  - https://github.com/tianocore/edk2-platforms
+
+- Environnements variables:
+  - WORKSPACE set to your current workspace
+  - PACKAGES_PATH should contain path to:
+    - edk2
+    - edk2-platforms
+    - edk2-platforms/Platform/Intel
+    - edk2-platforms/Platform/Qemu
+    - edk2-platforms/Silicon/Intel
+
+Currently QemuOpenBoardPkg's PEI Core is 32 bits only, DXE supports either 32 bits or 64 bits
+
+QemuOpenBoardPkg (IA32 PEI - IA32 DXE)
+
+```build -a IA32 -D PEI_ARCH=IA32 -D DXE_ARCH=IA32```
+
+QemuOpenBoardPkg (IA32 PEI - X64 DXE)
+
+```build -a IA32 -a X64 -D PEI_ARCH=IA32 -D DXE_ARCH=X64```
+
+## How to use
+
+Using qemu-system-x86_64, use
+
+```-bios <path to QemuOpenBoard FV>```
+
+To redirect serial output to the console
+
+```-serial stdio```
+
+## Important notes
+- Secure boot is not yet available due to QemuOpenBoardPkg NVRAM storage not being persistent yet.
-- 
2.37.0 (Apple Git-136)


  reply	other threads:[~2022-09-13 21:32 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-13 21:31 [edk2-devel][edk2-platforms][PATCH V3 0/4] QemuOpenBoardPkg: Add QemuOpenBoardPkg Théo Jehl
2022-09-13 21:31 ` Théo Jehl [this message]
2022-09-13 21:31 ` [edk2-devel][edk2-platforms][PATCH V3 2/4] QemuOpenBoardPkg: Enable stage 2 Théo Jehl
2022-09-13 21:31 ` [edk2-devel][edk2-platforms][PATCH V3 3/4] QemuOpenBoardPkg: Enable stage 3 Théo Jehl
2022-09-13 21:31 ` [edk2-devel][edk2-platforms][PATCH V3 4/4] QemuOpenBoardPkg: Enable stage 4 Théo Jehl
2022-09-13 21:45 ` [edk2-devel][edk2-platforms][PATCH V3 0/4] QemuOpenBoardPkg: Add QemuOpenBoardPkg Isaac Oram
2022-09-13 21:51   ` Michael D Kinney
2022-09-14 20:14     ` Isaac Oram
2022-09-15 10:16       ` Leif Lindholm
2022-09-15 15:53         ` Isaac Oram
2022-09-13 21:53 ` Pedro Falcato

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1abf84f82e191df746a7dcf13e0d73eb3aa0ff03.1663104246.git.theojehl76@gmail.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox