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)
next prev parent 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