Date   

[PATCH V2 02/14] MdePkg: Increase EFI_RESOURCE_MAX_MEMORY_TYPE

Min Xu
 

From: Min M Xu <min.m.xu@...>

RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3937

EFI_RESOURCE_MEMORY_UNACCEPTED is defined for unaccepted memory.
But this defitinion has not been officially in the PI spec. Base
on the code-first we define EFI_RESOURCE_MEMORY_UNACCEPTED at
MdeModulePkg/Include/Pi/PrePiHob.h and update EFI_RESOURCE_MAX_MEMORY_TYPE
to 8. After EFI_RESOURCE_MEMORY_UNACCEPTED is officially published
in PI spec, we will re-visit here.

Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <gaoliming@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: Gerd Hoffmann <kraxel@...>
Cc: James Bottomley <jejb@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Reviewed-by: Jiewen Yao <jiewen.yao@...>
Signed-off-by: Min Xu <min.m.xu@...>
---
MdePkg/Include/Pi/PiHob.h | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/MdePkg/Include/Pi/PiHob.h b/MdePkg/Include/Pi/PiHob.h
index e9f0ab4309d1..9af2e957fee5 100644
--- a/MdePkg/Include/Pi/PiHob.h
+++ b/MdePkg/Include/Pi/PiHob.h
@@ -232,7 +232,16 @@ typedef UINT32 EFI_RESOURCE_TYPE;
#define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT 0x00000004
#define EFI_RESOURCE_MEMORY_RESERVED 0x00000005
#define EFI_RESOURCE_IO_RESERVED 0x00000006
-#define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000007
+//
+// EFI_RESOURCE_MEMORY_UNACCEPTED is defined for unaccepted memory.
+// But this defitinion has not been officially in the PI spec. Base
+// on the code-first we define EFI_RESOURCE_MEMORY_UNACCEPTED at
+// MdeModulePkg/Include/Pi/PrePiHob.h and update EFI_RESOURCE_MAX_MEMORY_TYPE
+// to 8. After EFI_RESOURCE_MEMORY_UNACCEPTED is officially published
+// in PI spec, we will re-visit here.
+//
+// #define EFI_RESOURCE_MEMORY_UNACCEPTED 0x00000007
+#define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000008

///
/// A type of recount attribute type.
--
2.29.2.windows.2


[PATCH V2 01/14] MdeModulePkg: Add PrePiHob.h

Min Xu
 

From: Min M Xu <min.m.xu@...>

RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3937

EFI_RESOURCE_MEMORY_UNACCEPTED is defined for unaccepted memory.
But this defitinion has not been officially in the PI spec. Base
on the code-first we define EFI_RESOURCE_MEMORY_UNACCEPTED at
MdeModulePkg/Include/Pi/PrePiHob.h.

Cc: Jian J Wang <jian.j.wang@...>
Cc: Liming Gao <gaoliming@...>
Cc: Ray Ni <ray.ni@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: Gerd Hoffmann <kraxel@...>
Cc: James Bottomley <jejb@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Signed-off-by: Min Xu <min.m.xu@...>
---
MdeModulePkg/Include/Pi/PrePiHob.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 MdeModulePkg/Include/Pi/PrePiHob.h

diff --git a/MdeModulePkg/Include/Pi/PrePiHob.h b/MdeModulePkg/Include/Pi/PrePiHob.h
new file mode 100644
index 000000000000..38a8f1be149d
--- /dev/null
+++ b/MdeModulePkg/Include/Pi/PrePiHob.h
@@ -0,0 +1,20 @@
+/** @file
+ HOB related definitions which has not been officially published in PI.
+
+Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MDE_MODULEPKG_PRE_PI_HOB_H_
+#define MDE_MODULEPKG_PRE_PI_HOB_H_
+
+//
+// EFI_RESOURCE_MEMORY_UNACCEPTED is defined for unaccepted memory.
+// But this defitinion has not been officially in the PI spec. Base
+// on the code-first we define EFI_RESOURCE_MEMORY_UNACCEPTED at
+// MdeModulePkg/Include/Pi/PrePiHob.h.
+//
+#define EFI_RESOURCE_MEMORY_UNACCEPTED 0x00000007
+
+#endif
--
2.29.2.windows.2


[PATCH V2 00/14] Introduce Lazy-accept for Tdx guest

Min Xu
 

RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3937

UnacceptedMemory is one of the four defined types of TD memory in Intel
TDX guest. TDVF must invoke TDCALL [TDG.MEM.PAGE.ACCEPT] the unaccepted
memory before use it. See [TDVF] Section 7.1.
TDVF: https://www.intel.com/content/dam/develop/external/us/en/
documents/tdx-virtual-firmware-design-guide-rev-1.01.pdf

It is a time-consuming task which impacts the boot performance badly.
One of the mitigation is the lazy-accept mechanism. That the whole system
memory is divided into 2 parts, one is accepted in bios phase, the other
is tagged as EfiGcdMemoryTypeUnaccepted and OS will handle these
"unaccepted" memories.
See "UEFI Spec v2.9 Table 7-5 Memory Type Usage before ExitBootServices()"

In current implementation, we configure the lazy accept memory size with
PcdLazyAcceptPartialMemorySize in build time. If the
PcdLazyAcceptPartialMemorySize is 0, it means to accept all the memory
under 4G. This is to optimize the performance.

Patch 1-4:
Introduce lazy-accept related definitions.

Patch 5-6:
Update Dxe and shell for unaccepted memory.

Patch 7 - 11:
Update OvmfPkg for unaccepted memory.

Patch 12 - 13:
Introduce EfiMemoryAcceptProtocol and realize it in TdxDxe.

Patch 14:
Update Pool and Page functions to accept memory when OOM occurs.

Code: https://github.com/mxu9/edk2/tree/lazyaccept.v2

v2 changes:
- Fix a typo that change EfiUnacceptedMemory to EfiUnacceptedMemoryType.
- Define EFI_GCD_MEMORY_TYPE_UNACCEPTED in PrePiDxeCis.h because it has
not been defined in PI spec.
- AllocatePages should return EFI_INVALID_PARAMETERS if input MemoryType
is EfiUnacceptedMemoryType.
- Use EDKII_ prefix instead of EFI_ prefix in the protocol name of
EDKII_MEMORY_ACCEPT_PROTOCOL_GUID. Because this protocol is not EFI
defined.
- Accept memory under 4G even if the PcdLazyAcceptPartialMemorySize is
bigger than 4G. So with this setting, even if the
PcdLazyAcceptPartialMemorySize is 0 (which means to accept all
memories), only the memory under 4G will be accepted. This is to
optimize the performance.

Cc: Zhichao Gao <zhichao.gao@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Liming Gao <gaoliming@...>
Cc: Ray Ni <ray.ni@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: Gerd Hoffmann <kraxel@...>
Cc: James Bottomley <jejb@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Signed-off-by: Jiaqi Gao <jiaqi.gao@...>
Signed-off-by: Min Xu <min.m.xu@...>

Jiaqi Gao (2):
MdePkg: The prototype definition of EdkiiMemoryAcceptProtocol
MdeModulePkg: Pool and page functions accept memory when OOM occurs

Min M Xu (12):
MdeModulePkg: Add PrePiHob.h
MdePkg: Increase EFI_RESOURCE_MAX_MEMORY_TYPE
OvmfPkg: Use EFI_RESOURCE_MEMORY_UNACCEPTED which defined in
MdeModulePkg
MdePkg: Add UEFI Unaccepted memory definition
MdeModulePkg: Update Dxe to handle unaccepted memory type
ShellPkg: Update shell command memmap to show unaccepted memory
OvmfPkg: Add PCD and DEFINEs for Lazy Accept page.
OvmfPkg: Add MaxAcceptedMemoryAddress in TDX work area
OvmfPkg: Introduce lazy accept in PlatformInitLib and PlatformPei
OvmfPkg: Update ConstructFwHobList for lazy accept
OvmfPkg: Realize EdkiiMemoryAcceptProtocol in TdxDxe
OvmfPkg: Call gEdkiiMemoryAcceptProtocolGuid to accept pages

MdeModulePkg/Core/Dxe/DxeMain.inf | 1 +
MdeModulePkg/Core/Dxe/Gcd/Gcd.c | 6 +
MdeModulePkg/Core/Dxe/Mem/Imem.h | 16 ++
MdeModulePkg/Core/Dxe/Mem/Page.c | 253 ++++++++++++++++--
MdeModulePkg/Core/Dxe/Mem/Pool.c | 14 +
MdeModulePkg/Include/Pi/PrePiDxeCis.h | 25 ++
MdeModulePkg/Include/Pi/PrePiHob.h | 20 ++
MdePkg/Include/Pi/PiDxeCis.h | 10 +-
MdePkg/Include/Pi/PiHob.h | 11 +-
MdePkg/Include/Protocol/MemoryAccept.h | 37 +++
MdePkg/Include/Uefi/UefiMultiPhase.h | 5 +
MdePkg/MdePkg.dec | 3 +
OvmfPkg/Include/Library/PlatformInitLib.h | 6 +
OvmfPkg/Include/WorkArea.h | 1 +
OvmfPkg/IntelTdx/IntelTdxX64.dsc | 8 +
.../BaseMemEncryptTdxLib.inf | 3 +
.../BaseMemEncryptTdxLib/MemoryEncryption.c | 12 +-
OvmfPkg/Library/PeilessStartupLib/Hob.c | 26 +-
.../PeilessStartupLib/PeilessStartupLib.inf | 1 +
OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 154 ++++++++++-
OvmfPkg/Library/PlatformInitLib/MemDetect.c | 27 ++
.../PlatformInitLib/PlatformInitLib.inf | 1 +
OvmfPkg/OvmfPkg.dec | 4 +
OvmfPkg/OvmfPkgX64.dsc | 9 +
OvmfPkg/PlatformPei/MemDetect.c | 5 +
OvmfPkg/TdxDxe/TdxDxe.c | 103 +++++++
OvmfPkg/TdxDxe/TdxDxe.inf | 2 +
.../UefiShellDebug1CommandsLib/MemMap.c | 13 +
.../UefiShellDebug1CommandsLib.uni | 3 +-
29 files changed, 741 insertions(+), 38 deletions(-)
create mode 100644 MdeModulePkg/Include/Pi/PrePiDxeCis.h
create mode 100644 MdeModulePkg/Include/Pi/PrePiHob.h
create mode 100644 MdePkg/Include/Protocol/MemoryAccept.h

--
2.29.2.windows.2


[edk2-platforms][PATCH v1 02/02] Maintainers: Add maintainers for QemuOpenBoardPkg

Théo Jehl
 

From: Théo Jehl <theojehl76@...>

Cc: Leif Lindholm <quic_llindhol@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Isaac Oram <isaac.w.oram@...>
Cc: Pedro Falcato <pedro.falcato@...>
Cc: Isaac Oram <isaac.w.oram@...>

Signed-off-by: Theo Jehl <theojehl76@...>
---
Maintainers.txt | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/Maintainers.txt b/Maintainers.txt
index a4a0e4b90715..4b77b05e3aad 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -356,6 +356,13 @@ M: Leif Lindholm <quic_llindhol@...>
R: Graeme Gregory <graeme@...>
R: Radoslaw Biernacki <rad@...>

+QEMU MinPlatform Arch spec based port
+F: Platform/Qemu/QemuOpenBoardPkg/
+F: Silicon/Qemu/QemuOpenBoardPkg/
+M: Isaac Oram <isaac.w.oram@...>
+M: Pedro Falcato <pedro.falcato@...>
+R: Theo Jehl <theojehl76@...>
+
Raspberry Pi platforms and silicon
F: Platform/RaspberryPi/
F: Silicon/Broadcom/
--
2.32.1 (Apple Git-133)


[edk2-platforms][PATCH v1 01/02] QemuOpenBoardPkg: Add QemuOpenBoardPkg

Théo Jehl
 

From: Théo Jehl <theojehl76@...>

QemuOpenBoardPkg adds a MinPlatform port to Qemu x86_64
It can boots UEFI Linux and Windows, and works on PIIX4 and Q35
This board port provides a simple starting place for investigating edk2 and
MinPlatform Arch.
Currently we implement up to stage 4 of the MinPlatform spec and can boot
Windows/Linux.

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

Signed-off-by: Théo Jehl <theojehl76@...>
---
Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec | 32 +
Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc | 55 ++
Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage2.dsc.inc | 31 +
Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage3.dsc.inc | 100 +++
Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage4.dsc.inc | 56 ++
Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc | 144 +++++
Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf | 313 ++++++++++
Platform/Qemu/QemuOpenBoardPkg/Library/BoardBootManagerLib/BoardBootManagerLib.inf | 39 ++
Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf | 29 +
Platform/Qemu/QemuOpenBoardPkg/Library/OpenQemuFwCfgLib/OpenQemuFwCfgLib.inf | 23 +
Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf | 63 ++
Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf | 49 ++
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf | 59 ++
Platform/Qemu/QemuOpenBoardPkg/Include/Library/OpenQemuFwCfgLib.h | 102 +++
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.h | 59 ++
Platform/Qemu/QemuOpenBoardPkg/Library/BoardBootManagerLib/BoardBootManager.c | 105 ++++
Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c | 222 +++++++
Platform/Qemu/QemuOpenBoardPkg/Library/OpenQemuFwCfgLib/OpenQemuFwCfgLib.c | 130 ++++
Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c | 285 +++++++++
Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.c | 140 +++++
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c | 56 ++
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Memory.c | 244 ++++++++
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pci.c | 59 ++
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pcie.c | 91 +++
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.c | 67 ++
Platform/Qemu/QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc | 85 +++
Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/Ia32/SecEntry.nasm | 117 ++++
Platform/Qemu/QemuOpenBoardPkg/README.md | 53 ++
28 files changed, 2808 insertions(+)

diff --git a/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec
new file mode 100644
index 000000000000..3b5300a0c309
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec
@@ -0,0 +1,32 @@
+## @file QemuOpenBoardPkg.dec
+# Declaration file for QemuOpenBoardPkg.
+#
+# This package supports a simple QEMU port implemented per the MinPlatform
+# Arch specification.
+#
+# Copyright (c) 2022 Théo 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]
+ OpenQemuFwCfgLib|Include/Library/OpenQemuFwCfgLib.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
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/Include/Dsc/Stage2.dsc.inc b/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage2.dsc.inc
new file mode 100644
index 000000000000..4b331c4ed1fc
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage2.dsc.inc
@@ -0,0 +1,31 @@
+## @file
+# Common DSC content to begin Stage 2 enabling
+#
+# @copyright
+# Copyright (C) 2022 Jehl Théo
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[LibraryClasses.Common]
+ ResetSystemLib | OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf
+ PciHostBridgeLib | OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+ PciHostBridgeUtilityLib | OvmfPkg/Library/PciHostBridgeUtilityLib/PciHostBridgeUtilityLib.inf
+ DxeHardwareInfoLib | OvmfPkg/Library/HardwareInfoLib/DxeHardwareInfoLib.inf
+
+[LibraryClasses.Common.PEIM]
+ MpInitLib | UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+ 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]
+ PciLib | OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+
+[Components.$(PEI_ARCH)]
+ UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+ MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
+ MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf
+ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+[Components.$(DXE_ARCH)]
+ MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+ MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage3.dsc.inc b/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage3.dsc.inc
new file mode 100644
index 000000000000..0435fb2da81d
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage3.dsc.inc
@@ -0,0 +1,100 @@
+## @file
+# Common DSC content to begin Stage 3 enabling
+#
+# @copyright
+# Copyright (C) 2022 Jehl Théo
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[LibraryClasses.Common]
+ PlatformBootManagerLib | OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+ BootLogoLib | MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+ NvVarsFileLib | OvmfPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
+ QemuFwCfgS3Lib | OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
+ QemuLoadImageLib | OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.inf
+ QemuBootOrderLib | OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
+ PlatformBmPrintScLib | OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf
+ XenPlatformLib | OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
+ LoadLinuxLib | OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
+ SerializeVariablesLib | OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
+ BoardBootManagerLib | QemuOpenBoardPkg/Library/BoardBootManagerLib/BoardBootManagerLib.inf
+ LocalApicLib | UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
+ IoLib | MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+ PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+ PcdLib | MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ PciLib | MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+ DebugLib | MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+ SerialPortLib | PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf
+
+[Components.$(DXE_ARCH)]
+ MdeModulePkg/Core/Dxe/DxeMain.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+ MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+ <LibraryClasses>
+ PcdLib | MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+ MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+ MdeModulePkg/Universal/Metronome/Metronome.inf
+ MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+ PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+ MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+ MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ UefiCpuPkg/CpuDxe/CpuDxe.inf
+ PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+ MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+ MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+ UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+ OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+ MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+ MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ MdeModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
+ MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf
+ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ FatPkg/EnhancedFatDxe/Fat.inf
+ OvmfPkg/QemuRamfbDxe/QemuRamfbDxe.inf
+
+ ShellPkg/Application/Shell/Shell.inf {
+ <LibraryClasses>
+ ShellCommandLib | ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+ NULL | ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+ NULL | ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+ NULL | ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+ NULL | ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+ NULL | ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+ NULL | ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+ NULL | ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+ HandleParsingLib | ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+ PrintLib | MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ BcfgCommandLib | ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+ <PcdsFixedAtBuild>
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0xFF
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize | FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize | 8000
+ }
+
+ MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ OvmfPkg/PlatformDxe/Platform.inf
+ MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
+ MdeModulePkg/Application/UiApp/UiApp.inf
+ OvmfPkg/IoMmuDxe/IoMmuDxe.inf
+ MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+ OvmfPkg/SioBusDxe/SioBusDxe.inf
+ MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage4.dsc.inc b/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage4.dsc.inc
new file mode 100644
index 000000000000..4a1f9c7d0124
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage4.dsc.inc
@@ -0,0 +1,56 @@
+## @file
+# Common DSC content to begin Stage 4 enabling
+#
+# @copyright
+# Copyright (C) 2022 Jehl Théo
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[LibraryClasses]
+ !if $(SMM_REQUIRED) == TRUE
+ SpiFlashCommonLib | IntelSiliconPkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
+ !endif
+
+[LibraryClasses.Common.DXE_SMM_DRIVER]
+ LockBoxLib | MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf
+ SmmCpuPlatformHookLib | OvmfPkg/Library/SmmCpuPlatformHookLibQemu/SmmCpuPlatformHookLibQemu.inf
+ SmmCpuFeaturesLib | OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
+
+[Components.$(DXE_ARCH)]
+ OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+ MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+ MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+ MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+ MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+ MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+ MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+ MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+
+ !if $(SMM_REQUIRED) == TRUE
+ OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
+ OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
+ MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+ MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+
+ MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+
+ MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf
+ MdeModulePkg/Universal/StatusCodeHandler/Smm/StatusCodeHandlerSmm.inf
+ UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
+ IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+ !endif
+
+ #
+ # SMBIOS Support
+ #
+ MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf {
+ <LibraryClasses>
+ NULL | OvmfPkg/Library/SmbiosVersionLib/DetectSmbiosVersionLib.inf
+ }
+ OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
diff --git a/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc
new file mode 100644
index 000000000000..958d6b9537c9
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc
@@ -0,0 +1,144 @@
+## @file
+# QemuOpenBoardPkg.dsc
+#
+# Description file for QemuOpenBoardPkg
+#
+# Copyright (c) 2022 Théo 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
+
+[PcdsFixedAtBuild]
+ gMinPlatformPkgTokenSpaceGuid.PcdBootStage | 4
+
+ 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
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress | 0xB0000000
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable | TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange | FALSE
+
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase | 0x00000000 # Will be updated by build
+
+[PcdsFeatureFlag]
+ gMinPlatformPkgTokenSpaceGuid.PcdSmiHandlerProfileEnable | TRUE
+ gMinPlatformPkgTokenSpaceGuid.PcdUefiSecureBootEnable | FALSE
+ gMinPlatformPkgTokenSpaceGuid.PcdPerformanceEnable | FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|TRUE
+
+ !if $(DXE_ARCH) == X64
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode | TRUE
+ !else
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode | FALSE
+ !endif
+
+ gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly | TRUE
+ gMinPlatformPkgTokenSpaceGuid.PcdSerialTerminalEnable | TRUE
+ gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable | FALSE
+
+ !if $(SMM_REQUIRED) == TRUE
+ gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire | TRUE
+ 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
+!include QemuOpenBoardPkg/Include/Dsc/Stage2.dsc.inc
+!include QemuOpenBoardPkg/Include/Dsc/Stage3.dsc.inc
+!include QemuOpenBoardPkg/Include/Dsc/Stage4.dsc.inc
+
+[LibraryClasses.Common]
+ OpenQemuFwCfgLib | QemuOpenBoardPkg/Library/OpenQemuFwCfgLib/OpenQemuFwCfgLib.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)]
+ MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+ OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+ MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+ MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+ MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
diff --git a/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf
new file mode 100644
index 000000000000..2f39ce3860f6
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf
@@ -0,0 +1,313 @@
+## @file
+# QemuOpenBoardPkg.fdf
+#
+# Copyright (c) 2022 Théo Jehl
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress = 0xFF800000
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize = 0x800000
+
+!include QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc
+
+[FD.QemuOpenBoardPkg]
+ BaseAddress = 0xFF800000
+ Size = 0x800000
+ ErasePolarity = 1
+ BlockSize = 0x1000
+ NumBlocks = 0x800
+
+ #
+ # 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
+
+ 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
+
+ INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+
+ INF MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
+ INF MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf
+
+ INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+ INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+ INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
+[FV.FvBsp]
+ !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+ FvNameGuid = FCA0BC4A-994D-4EF9-BD56-A8C45872C2A8
+
+###########################
+#
+# Stage 3 Firmware Volumes
+#
+###########################
+
+[FV.FvUefiBootUnCompressed]
+ !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+ FvNameGuid = D2F110DB-2388-4963-BEFD-5889EEE01569
+
+ INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+ INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+ INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+
+ INF MdeModulePkg/Universal/Metronome/Metronome.inf
+ INF PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
+ INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+ INF UefiCpuPkg/CpuDxe/CpuDxe.inf
+ INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+ INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+ INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+ INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+ INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+
+ INF OvmfPkg/IoMmuDxe/IoMmuDxe.inf
+ INF OvmfPkg/PlatformDxe/Platform.inf
+
+ INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+ INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+ INF MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf
+ INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+
+ INF MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
+ INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ INF ShellPkg/Application/Shell/Shell.inf
+
+ INF OvmfPkg/SioBusDxe/SioBusDxe.inf
+ INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+ INF MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf
+
+
+[FV.FvUefiBoot]
+ !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+ FvNameGuid = D0C15ADB-FE38-4331-841C-0E96C1B0FBFA
+
+ INF MdeModulePkg/Core/Dxe/DxeMain.inf
+
+ FILE FV_IMAGE = D2F110DB-2388-4963-BEFD-5889EEE01569 {
+ SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+ SECTION FV_IMAGE = FvUefiBootUncompressed
+ }
+ }
+
+
+###########################
+#
+# Stage 4 Firmware Volumes
+#
+###########################
+[FV.FvOsBoot]
+ !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+ FvNameGuid = AE8F0EA0-1614-422D-ABC1-C518596F1678
+
+ INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+
+ INF PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf
+ INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ INF FatPkg/EnhancedFatDxe/Fat.inf
+
+ INF MdeModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
+ INF MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
+
+ # ACPI
+ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+
+ # Buses
+
+ INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+ INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+ INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+ INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+ INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+
+ INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+ INF OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+
+ INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+ INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+
+ INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+ !if $(SMM_REQUIRED) == TRUE
+ INF OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
+ INF OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
+ INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+ INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+ INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+ INF MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf
+ INF MdeModulePkg/Universal/StatusCodeHandler/Smm/StatusCodeHandlerSmm.inf
+ INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+ INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
+ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
+ INF IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm.inf
+ !endif
+ INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+ INF OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+
+###########################
+#
+# Stage 5 Firmware Volumes
+#
+###########################
+[FV.FvSecurity]
+ !include MinPlatformPkg/Include/Fdf/CommonSpiFvHeaderInfo.fdf
+ FvNameGuid = 1AE6AB90-9431-425B-9A92-ED2708A4E982
+ !include MinPlatformPkg/Include/Fdf/CoreSecurityLateInclude.fdf
+ !include MinPlatformPkg/Include/Fdf/CoreSecurityPreMemoryInclude.fdf
+
+
+###########################
+#
+# 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/BoardBootManagerLib/BoardBootManagerLib.inf b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardBootManagerLib/BoardBootManagerLib.inf
new file mode 100644
index 000000000000..37425d711010
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardBootManagerLib/BoardBootManagerLib.inf
@@ -0,0 +1,39 @@
+## @file
+# The module definition file for BoardBootManagerLib.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BoardBootManagerLib
+ FILE_GUID = 3fe4b589-8bd9-46df-9322-d06fa2c278d6
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BoardBootManagerLib|DXE_DRIVER
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ BoardBootManager.c
+
+[LibraryClasses]
+ BaseLib
+ UefiBootServicesTableLib
+ DebugLib
+ UefiLib
+ HobLib
+ UefiBootManagerLib
+ TimerLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
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/OpenQemuFwCfgLib/OpenQemuFwCfgLib.inf b/Platform/Qemu/QemuOpenBoardPkg/Library/OpenQemuFwCfgLib/OpenQemuFwCfgLib.inf
new file mode 100644
index 000000000000..cfabf412d5bb
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/OpenQemuFwCfgLib/OpenQemuFwCfgLib.inf
@@ -0,0 +1,23 @@
+## @file
+# OpenQemuFwCfgLib.inf
+#
+# Simple implementation of the QemuFwCfgLib that reads data from the QEMU
+# FW_CFG device
+#
+# Copyright (c) 2022 Théo 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 = OpenQemuFwCfgLib
+
+[Sources]
+ OpenQemuFwCfgLib.c
+
+[LibraryClasses]
+ IoLib
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..a4c793af05cd
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.inf
@@ -0,0 +1,49 @@
+## @file
+# PlatformSecLib for QEMU OpenBoardPkg
+#
+# Copyright (c) 2022 Théo 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/PlatformInitPei/PlatformInitPei.inf b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf
new file mode 100644
index 000000000000..c800d14a02b5
--- /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 Théo 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
+ OpenQemuFwCfgLib
+ 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/OpenQemuFwCfgLib.h b/Platform/Qemu/QemuOpenBoardPkg/Include/Library/OpenQemuFwCfgLib.h
new file mode 100644
index 000000000000..ec82cc9c89f0
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Include/Library/OpenQemuFwCfgLib.h
@@ -0,0 +1,102 @@
+/** @file OpenQemuFwCfgLib.h
+ OpenQemuFwCfgLib Headers
+
+ Implements a minimal library to interact with Qemu FW CFG device
+
+ Copyright (c) 2022 Théo 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..7f84e5d9724b
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.h
@@ -0,0 +1,59 @@
+/** @file PlatformInit.h
+ Headers for PlatformInitPei PEIM
+
+ Copyright (c) 2022 Théo 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/BoardBootManagerLib/BoardBootManager.c b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardBootManagerLib/BoardBootManager.c
new file mode 100644
index 000000000000..9fad6bc56dfd
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardBootManagerLib/BoardBootManager.c
@@ -0,0 +1,105 @@
+/** @file
+ This file include board specific boot manager callbacks
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/PlatformBootManagerLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HobLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/BoardBootManagerLib.h>
+
+BOOLEAN mHotKeypressed = FALSE;
+EFI_EVENT HotKeyEvent = NULL;
+UINTN mBootMenuOptionNumber;
+
+/**
+ This function is called each second during the boot manager waits timeout.
+
+ @param TimeoutRemain The remaining timeout.
+**/
+VOID
+EFIAPI
+BoardBootManagerWaitCallback (
+ UINT16 TimeoutRemain
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TxtInEx;
+ EFI_KEY_DATA KeyData;
+ BOOLEAN PausePressed;
+
+ //
+ // Pause on PAUSE key
+ //
+ Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **)&TxtInEx);
+ ASSERT_EFI_ERROR (Status);
+
+ PausePressed = FALSE;
+
+ while (TRUE) {
+ Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (KeyData.Key.ScanCode == SCAN_PAUSE) {
+ PausePressed = TRUE;
+ break;
+ }
+ }
+
+ //
+ // Loop until non-PAUSE key pressed
+ //
+ while (PausePressed) {
+ Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
+ if (!EFI_ERROR (Status)) {
+ DEBUG (
+ (
+ DEBUG_INFO, "[PauseCallback] %x/%x %x/%x\n",
+ KeyData.Key.ScanCode, KeyData.Key.UnicodeChar,
+ KeyData.KeyState.KeyShiftState, KeyData.KeyState.KeyToggleState
+ )
+ );
+ PausePressed = (BOOLEAN)(KeyData.Key.ScanCode == SCAN_PAUSE);
+ }
+ }
+}
+
+/**
+ The function is called when no boot option could be launched,
+ including platform recovery options and options pointing to applications
+ built into firmware volumes.
+
+ If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+BoardBootManagerUnableToBoot (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MANAGER_LOAD_OPTION BootDeviceList;
+ CHAR16 OptionName[sizeof ("Boot####")];
+
+ if (mBootMenuOptionNumber == LoadOptionNumberUnassigned) {
+ return;
+ }
+
+ UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", mBootMenuOptionNumber);
+ Status = EfiBootManagerVariableToLoadOption (OptionName, &BootDeviceList);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ for ( ;;) {
+ EfiBootManagerBoot (&BootDeviceList);
+ }
+}
diff --git a/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c
new file mode 100644
index 000000000000..ae7c77915b5e
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c
@@ -0,0 +1,222 @@
+/** @file
+ Board initialization library
+
+ Copyright (c) 2022 Théo 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"));
+
+ 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));
+
+ switch (DeviceID) {
+ case INTEL_82441_DEVICE_ID:
+ DEBUG ((DEBUG_INFO, "PIIX4\n"));
+ return EFI_SUCCESS;
+
+ case INTEL_Q35_MCH_DEVICE_ID:
+ DEBUG ((DEBUG_INFO, "ICH9\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/OpenQemuFwCfgLib/OpenQemuFwCfgLib.c b/Platform/Qemu/QemuOpenBoardPkg/Library/OpenQemuFwCfgLib/OpenQemuFwCfgLib.c
new file mode 100644
index 000000000000..c02c263f03b3
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/OpenQemuFwCfgLib/OpenQemuFwCfgLib.c
@@ -0,0 +1,130 @@
+/** @file
+ Qemu FW CFG device library
+
+ Copyright (c) 2022 Théo Jehl All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/OpenQemuFwCfgLib.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/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..ff632494c4a3
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.c
@@ -0,0 +1,140 @@
+/** @file
+ PlatformSecLib library functions
+
+ Copyright (c) 2022 Théo 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/PlatformInitPei/Cpu.c b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c
new file mode 100644
index 000000000000..ff3e008aa96b
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c
@@ -0,0 +1,56 @@
+/** @file Cpu.c
+ CPU Count initialization
+
+ Copyright (c) 2022 Théo Jehl All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PlatformInit.h"
+#include <IndustryStandard/Pci.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/OpenQemuFwCfgLib.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;
+ }
+
+ Status = QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ QemuFwCfgReadBytes (sizeof (BootCpuCount), &BootCpuCount);
+
+ 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..8e378c17d851
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Memory.c
@@ -0,0 +1,244 @@
+/** @file Memory.c
+ Memory probing and installation
+
+ Copyright (c) 2022 Théo Jehl All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PlatformInit.h>
+#include <Library/DebugLib.h>
+#include <Library/OpenQemuFwCfgLib.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 UINT32
+**/
+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 {
+ return Size;
+ }
+ }
+
+ return Size;
+}
+
+/**
+ Reserve an MMIO region
+
+ @param Start
+ @param Length
+**/
+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 reserve space for MMIO regions such as VGA, BIOS and APIC
+
+ @param PeiServices
+ @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..a66cbf6005fb
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pci.c
@@ -0,0 +1,59 @@
+/** @file Pci.c
+ PCI Initialization for PIIX4 QEMU
+
+ Copyright (c) 2022 Théo Jehl All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PlatformInit.h"
+#include <IndustryStandard/Pci.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/OpenQemuFwCfgLib.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;
+
+ PciIoBase = PIIX4_PCI_IO_BASE;
+ PciIoSize = PIIX4_PCI_IO_SIZE;
+
+ PcdSet64S (PcdPciIoBase, PciIoBase);
+ PcdSet64S (PcdPciIoSize, PciIoSize);
+
+ 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));
+ 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..a61fd6447e91
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pcie.c
@@ -0,0 +1,91 @@
+/** @file Pcie.c
+ PCI Express initialization for QEMU Q35
+
+ Copyright (c) 2022 Théo 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/OpenQemuFwCfgLib.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 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..f69518301cd2
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.c
@@ -0,0 +1,67 @@
+/** @file PlarformInit.c
+ Platform initialization PEIM for QEMU
+
+ Copyright (c) 2022 Théo 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..29f49f914171
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc
@@ -0,0 +1,85 @@
+## @file
+# Flashmap and variable definitions for QemuOpenBoardPkg FVs and FD
+#
+# @copyright
+# Copyright (C) 2022 Jehl Théo
+#
+# 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 = gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+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
+#
+
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+
+SET gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase = gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset
+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..bd90a466f790
--- /dev/null
+++ b/Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/Ia32/SecEntry.nasm
@@ -0,0 +1,117 @@
+;------------------------------------------------------------------------------
+; @file SecEntry
+; Sec entry implementation
+;
+; Copyright (c) 2022 Théo 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
+
+ ; TODO: Multiprocessor support
+ 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.32.1 (Apple Git-133)


[edk2-platforms][PATCH v1 00/02] Add QemuOpenBoardPkg

Théo Jehl
 

QemuOpenBoardPkg adds a MinPlatform port to QEMU x86_64.
This package can boot UEFI Linux and Windows.
This port brings a starting place for understanding the MinPlatform,
and board porting.
QemuOpenBoardPkg is my project for Google Summer of Code 2022.
I proposed this project to better understand UEFI inner workings,
and to get started with platform level code.

CCing Gerd Hoffmann and Stefan Hajnoczi for their feedback,
because of their work on OVMF and QEMU.


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

Signed-off-by: Théo Jehl <theojehl76@...>

Théo Jehl (2):
QemuOpenBoardPkg: Add QemuOpenBoardPkg
Add maintainers and reviewers for MinPlatform Arch QEMU board port.

--
2.32.1 (Apple Git-133)


[PATCH V4 2/2] OvmfPkg: Update CcProbeLib to DxeCcProbeLib

Min Xu
 

From: Min M Xu <min.m.xu@...>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3974

CcProbeLib once was designed to probe the Confidential Computing guest
type by checking the PcdOvmfWorkArea. But this memory is allocated with
either EfiACPIMemoryNVS or EfiBootServicesData. It cannot be accessed
after ExitBootService. Please see the detailed analysis in BZ#3974.

To fix this issue, CcProbeLib is redesigned as 2 implementation:
- SecPeiCcProbeLib
- DxeCcProbeLib

In SecPeiCcProbeLib we check the CC guest type by reading the
PcdOvmfWorkArea. Because it is used in SEC / PEI and we don't worry about
the issues in BZ#3974.

In DxeCcProbeLib we cache the GuestType in Ovmf work area in a variable.
After that the Guest type is returned with the cached value. So that we
don't need to worry about the access to Ovmf work area after
ExitBootService.

To gurantee the GuestType is cached, we read the value in both
constructor and CcProbe. Because in some corner case, the constructor
may be called after CcProbe. For example in MdeModulePkg/Core/Dxe/DxeMain,
BaseDebugLibSerialPortConstructor is called before
DxeCcProbeLibConstructor. While CcProbe () is called in
BaseDebugLibSerialPortConstructor.

The reason why we probe CC guest type in 2 different ways is the global
varialbe. Global variable cannot be used in SEC/PEI and CcProbe is called
very frequently.

Cc: Gerd Hoffmann <kraxel@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: James Bottomley <jejb@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Signed-off-by: Min Xu <min.m.xu@...>
---
OvmfPkg/IntelTdx/IntelTdxX64.dsc | 3 +-
OvmfPkg/Library/CcProbeLib/CcProbeLib.c | 31 ---------
OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.c | 68 +++++++++++++++++++
.../{CcProbeLib.inf => DxeCcProbeLib.inf} | 7 +-
OvmfPkg/OvmfPkgX64.dsc | 5 +-
5 files changed, 78 insertions(+), 36 deletions(-)
delete mode 100644 OvmfPkg/Library/CcProbeLib/CcProbeLib.c
create mode 100644 OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.c
rename OvmfPkg/Library/CcProbeLib/{CcProbeLib.inf => DxeCcProbeLib.inf} (65%)

diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 71b1cf8e7090..1a7ecd503e50 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -140,7 +140,7 @@
PciCapLib|OvmfPkg/Library/BasePciCapLib/BasePciCapLib.inf
PciCapPciSegmentLib|OvmfPkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.inf
PciCapPciIoLib|OvmfPkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.inf
- CcProbeLib|OvmfPkg/Library/CcProbeLib/CcProbeLib.inf
+ CcProbeLib|OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf
@@ -234,6 +234,7 @@
HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
PeilessStartupLib|OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
+ CcProbeLib|OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf

[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
diff --git a/OvmfPkg/Library/CcProbeLib/CcProbeLib.c b/OvmfPkg/Library/CcProbeLib/CcProbeLib.c
deleted file mode 100644
index d698e5c8d7f8..000000000000
--- a/OvmfPkg/Library/CcProbeLib/CcProbeLib.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/** @file
-
- CcProbeLib is used to probe the Confidential computing guest type.
-
- Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Library/CcProbeLib.h>
-#include <WorkArea.h>
-
-/**
- Probe the ConfidentialComputing Guest type. See defition of
- CC_GUEST_TYPE in <ConfidentialComputingGuestAttr.h>.
-
- @return The guest type
-
-**/
-UINT8
-EFIAPI
-CcProbe (
- VOID
- )
-{
- OVMF_WORK_AREA *WorkArea;
-
- WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
-
- return WorkArea != NULL ? WorkArea->Header.GuestType : CcGuestTypeNonEncrypted;
-}
diff --git a/OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.c b/OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.c
new file mode 100644
index 000000000000..868e32bf7f60
--- /dev/null
+++ b/OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.c
@@ -0,0 +1,68 @@
+/** @file
+
+ CcProbeLib is used to probe the Confidential computing guest type.
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/CcProbeLib.h>
+#include <WorkArea.h>
+
+STATIC UINT8 mCcProbeGuestType = 0;
+STATIC BOOLEAN mCcProbed = FALSE;
+
+/**
+ * Read the the ConfidentialComputing Guest type from Ovmf work-area.
+ *
+ * @return The ConfidentialComputing Guest type
+ */
+STATIC
+UINT8
+ReadCcGuestType (
+ VOID
+ )
+{
+ OVMF_WORK_AREA *WorkArea;
+
+ if (!mCcProbed) {
+ WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
+ mCcProbeGuestType = WorkArea != NULL ? WorkArea->Header.GuestType : CcGuestTypeNonEncrypted;
+ mCcProbed = TRUE;
+ }
+
+ return mCcProbeGuestType;
+}
+
+/**
+ Probe the ConfidentialComputing Guest type. See defition of
+ CC_GUEST_TYPE in <ConfidentialComputingGuestAttr.h>.
+
+ @return The guest type
+
+**/
+UINT8
+EFIAPI
+CcProbe (
+ VOID
+ )
+{
+ return ReadCcGuestType ();
+}
+
+/**
+ * Constructor of DxeCcProbeLib
+ *
+ * @return EFI_SUCCESS Successfully called of constructor
+ */
+EFI_STATUS
+EFIAPI
+DxeCcProbeLibConstructor (
+ VOID
+ )
+{
+ ReadCcGuestType ();
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/Library/CcProbeLib/CcProbeLib.inf b/OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.inf
similarity index 65%
rename from OvmfPkg/Library/CcProbeLib/CcProbeLib.inf
rename to OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.inf
index 5300c9ba2644..2fd0b4d46d10 100644
--- a/OvmfPkg/Library/CcProbeLib/CcProbeLib.inf
+++ b/OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.inf
@@ -8,14 +8,15 @@

[Defines]
INF_VERSION = 0x00010005
- BASE_NAME = CcProbeLib
+ BASE_NAME = DxeCcProbeLib
FILE_GUID = 05184ec9-abb0-4491-8584-e388639a7c48
MODULE_TYPE = BASE
VERSION_STRING = 1.0
- LIBRARY_CLASS = CcProbeLib
+ LIBRARY_CLASS = CcProbeLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
+ CONSTRUCTOR = DxeCcProbeLibConstructor

[Sources]
- CcProbeLib.c
+ DxeCcProbeLib.c

[Packages]
MdePkg/MdePkg.dec
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 6e68f60dc90f..2741f4d988b7 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -199,7 +199,7 @@

!if $(SMM_REQUIRE) == FALSE
LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
- CcProbeLib|OvmfPkg/Library/CcProbeLib/CcProbeLib.inf
+ CcProbeLib|OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.inf
!else
CcProbeLib|MdePkg/Library/CcProbeLibNull/CcProbeLibNull.inf
!endif
@@ -287,6 +287,7 @@
!endif
VmgExitLib|OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf
MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
+ CcProbeLib|OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf

[LibraryClasses.common.PEI_CORE]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -303,6 +304,7 @@
DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
!endif
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ CcProbeLib|OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf

[LibraryClasses.common.PEIM]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -332,6 +334,7 @@
PlatformInitLib|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf

MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+ CcProbeLib|OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf

[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
--
2.29.2.windows.2


[PATCH V4 1/2] OvmfPkg: Add SecPeiCcProbeLib

Min Xu
 

From: Min M Xu <min.m.xu@...>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3974

SecPeiCcProbeLib is designed to probe the Confidential Computing guest
type in SEC/PEI phase. The CC guest type was set by each CC guest at
the beginning of boot up and saved in PcdOvmfWorkArea.

Cc: Erdem Aktas <erdemaktas@...>
Cc: James Bottomley <jejb@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Gerd Hoffmann <kraxel@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Signed-off-by: Min Xu <min.m.xu@...>
---
OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.c | 31 +++++++++++++++++++
.../Library/CcProbeLib/SecPeiCcProbeLib.inf | 25 +++++++++++++++
2 files changed, 56 insertions(+)
create mode 100644 OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.c
create mode 100644 OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf

diff --git a/OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.c b/OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.c
new file mode 100644
index 000000000000..d698e5c8d7f8
--- /dev/null
+++ b/OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.c
@@ -0,0 +1,31 @@
+/** @file
+
+ CcProbeLib is used to probe the Confidential computing guest type.
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/CcProbeLib.h>
+#include <WorkArea.h>
+
+/**
+ Probe the ConfidentialComputing Guest type. See defition of
+ CC_GUEST_TYPE in <ConfidentialComputingGuestAttr.h>.
+
+ @return The guest type
+
+**/
+UINT8
+EFIAPI
+CcProbe (
+ VOID
+ )
+{
+ OVMF_WORK_AREA *WorkArea;
+
+ WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
+
+ return WorkArea != NULL ? WorkArea->Header.GuestType : CcGuestTypeNonEncrypted;
+}
diff --git a/OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf b/OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf
new file mode 100644
index 000000000000..f63ed71e7c28
--- /dev/null
+++ b/OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf
@@ -0,0 +1,25 @@
+## @file
+# CcProbeLib is used to probe Confidential Computing guest type.
+#
+# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SecPeiCcProbeLib
+ FILE_GUID = 78eb7f2a-a42a-4b01-b160-5a05a0a52bac
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CcProbeLib|SEC PEIM PEI_CORE
+
+[Sources]
+ SecPeiCcProbeLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
--
2.29.2.windows.2


[PATCH V4 0/2] Re-design CcProbeLib

Min Xu
 

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3974

CcProbeLib once was designed to probe the Confidential Computing guest
type by checking the PcdOvmfWorkArea. But this memory is allocated with
either EfiACPIMemoryNVS or EfiBootServicesData. It cannot be accessed
after ExitBootService. Please see the detailed analysis in BZ#3974.

To fix this issue, CcProbeLib is re-designed as 2 implementation:
- SecPeiCcProbeLib
- DxeCcProbeLib

In SecPeiCcProbeLib we check the CC guest type by reading the
PcdOvmfWorkArea. Because it is used in SEC / PEI and we don't worry about
the issues in BZ#3974.

In DxeCcProbeLib we cache the GuestType in Ovmf work area in a global
variable. After that the Guest type is returned with the cached value.
So that we don't need to worry about the access to Ovmf work area after
ExitBootService.

The reason why we probe CC guest type in 2 different ways is the global
varialbe. Global variable cannot be used in SEC/PEI and CcProbe is called
very frequently.

Code: https://github.com/mxu9/edk2/tree/CcProbeLib.BZ3974.v4

v4 changes:
- Read Cc guest type in both DxeCcProbeLib's constructor and CcProbe. So
that we guarantee the Cc guest type is read early enough.

v3 changes:
- Re-design CcProbeLib to 2 implementation: SecPeiCcProbeLib and
DxeCcProbeLib. The difference between the 2 implementation is the
cache of the CcGuestType.

v2 changes:
- Reserve Ovmf work-area as RT_DATA. See
https://edk2.groups.io/g/devel/message/92599

Cc: Gerd Hoffmann <kraxel@...>
Cc: Erdem Aktas <erdemaktas@...>
Cc: James Bottomley <jejb@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Cc: Yuan Yu <yuanyu@...>
Signed-off-by: Min Xu <min.m.xu@...>

Min M Xu (2):
OvmfPkg: Add SecPeiCcProbeLib
OvmfPkg: Update CcProbeLib to DxeCcProbeLib

OvmfPkg/IntelTdx/IntelTdxX64.dsc | 3 +-
OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.c | 68 +++++++++++++++++++
OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.inf | 26 +++++++
.../{CcProbeLib.c => SecPeiCcProbeLib.c} | 0
.../{CcProbeLib.inf => SecPeiCcProbeLib.inf} | 8 +--
OvmfPkg/OvmfPkgX64.dsc | 5 +-
6 files changed, 104 insertions(+), 6 deletions(-)
create mode 100644 OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.c
create mode 100644 OvmfPkg/Library/CcProbeLib/DxeCcProbeLib.inf
rename OvmfPkg/Library/CcProbeLib/{CcProbeLib.c => SecPeiCcProbeLib.c} (100%)
rename OvmfPkg/Library/CcProbeLib/{CcProbeLib.inf => SecPeiCcProbeLib.inf} (65%)

--
2.29.2.windows.2


[PATCH 2/2] DynamicTablesPkg: Add Smbios Type17 Table generator

Girish Mahadevan
 

Add a new CM object to describe memory devices and setup a new
Generator Library for SMBIOS Type17 table.

Signed-off-by: Girish Mahadevan <gmahadevan@...>
---
.../Include/ArmNameSpaceObjects.h | 59 +++
.../SmbiosType17Lib/SmbiosType17Generator.c | 338 ++++++++++++++++++
.../SmbiosType17Lib/SmbiosType17LibArm.inf | 32 ++
3 files changed, 429 insertions(+)
create mode 100644 DynamicTablesPkg/Library/Smbios/Arm/SmbiosType17Lib/SmbiosType17Generator.c
create mode 100644 DynamicTablesPkg/Library/Smbios/Arm/SmbiosType17Lib/SmbiosType17LibArm.inf

diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index 102e0f96be..199a19e997 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -63,6 +63,7 @@ typedef enum ArmObjectID {
EArmObjPciInterruptMapInfo, ///< 39 - Pci Interrupt Map Info
EArmObjRmr, ///< 40 - Reserved Memory Range Node
EArmObjMemoryRangeDescriptor, ///< 41 - Memory Range Descriptor
+ EArmObjMemoryDeviceInfo, ///< 42 - Memory Device Information
EArmObjMax
} EARM_OBJECT_ID;

@@ -1070,6 +1071,64 @@ typedef struct CmArmRmrDescriptor {
UINT64 Length;
} CM_ARM_MEMORY_RANGE_DESCRIPTOR;

+/** A structure that describes the physical memory device.
+
+ The physical memory devices on the system are described by this object.
+
+ SMBIOS Specification v3.5.0 Type17
+
+ ID: EArmObjMemoryDeviceInfo,
+*/
+typedef struct CmArmMemoryDeviceInfo {
+ /** Size of the device.
+ Size of the device in bytes.
+ */
+ UINT64 Size;
+
+ /** Device Set */
+ UINT8 DeviceSet;
+
+ /** Speed of the device
+ Speed of the device in MegaTransfers/second.
+ */
+ UINT32 Speed;
+
+ /** Serial Number of device */
+ CHAR8 *SerialNum;
+
+ /** AssetTag identifying the device */
+ CHAR8 *AssetTag;
+
+ /** Device Locator String for the device.
+ String that describes the slot or position of the device on the board.
+ */
+ CHAR8 *DeviceLocator;
+
+ /** Bank locator string for the device.
+ String that describes the bank where the device is located.
+ */
+ CHAR8 *BankLocator;
+
+ /** Firmware version of the memory device */
+ CHAR8 *FirmwareVersion;
+
+ /** Manufacturer Id.
+ 2 byte Manufacturer Id as per JEDEC Standard JEP106AV
+ */
+ UINT16 ModuleManufacturerId;
+
+ /** Manufacturer Product Id
+ 2 byte Manufacturer Id as designated by Manufacturer.
+ */
+ UINT16 ModuleProductId;
+
+ /** Device Attributes */
+ UINT8 Attributes;
+
+ /** Device Configured Voltage in millivolts */
+ UINT16 ConfiguredVoltage;
+} CM_ARM_MEMORY_DEVICE_INFO;
+
#pragma pack()

#endif // ARM_NAMESPACE_OBJECTS_H_
diff --git a/DynamicTablesPkg/Library/Smbios/Arm/SmbiosType17Lib/SmbiosType17Generator.c b/DynamicTablesPkg/Library/Smbios/Arm/SmbiosType17Lib/SmbiosType17Generator.c
new file mode 100644
index 0000000000..5683ca570f
--- /dev/null
+++ b/DynamicTablesPkg/Library/Smbios/Arm/SmbiosType17Lib/SmbiosType17Generator.c
@@ -0,0 +1,338 @@
+/** @file
+ SMBIOS Type17 Table Generator.
+
+ Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SmbiosType17FixupLib.h>
+
+// Module specific include files.
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+
+/** This macro expands to a function that retrieves the Memory Device
+ information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjMemoryDeviceInfo,
+ CM_ARM_MEMORY_DEVICE_INFO
+ )
+
+// Default Values for Memory Device
+STATIC SMBIOS_TABLE_TYPE17 MemDeviceInfoTemplate = {
+ { // Hdr
+ EFI_SMBIOS_TYPE_MEMORY_DEVICE, // Type
+ sizeof (SMBIOS_TABLE_TYPE17), // Length
+ 0 // Handle
+ },
+ 0, // MemoryArrayHandle
+ 0, // MemoryErrorInformationHandle
+ 0xFFFF, // TotalWidth
+ 0xFFFF, // DataWIdth
+ 0x7FFF, // Size (always use Extended Size)
+ MemoryTypeUnknown, // FormFactor
+ 0xFF, // DeviceSet
+ 1, // Device Locator
+ 2, // Bank Locator
+ MemoryTypeSdram, // MemoryType
+ { // TypeDetail
+ 0
+ },
+ 0xFFFF, // Speed (Use Extended Speed)
+ 0, // Manufacturer
+ // (Unused Use ModuleManufactuerId)
+ 3, // SerialNumber
+ 4, // AssetTag
+ 0, // PartNumber
+ // (Unused Use ModuleProductId)
+ 0, // Attributes
+ 0, // ExtendedSize
+ 2000, // ConfiguredMemoryClockSpeed
+ 0, // MinimumVoltage
+ 0, // MaximumVoltage
+ 0, // ConfiguredVoltage
+ MemoryTechnologyDram, // MemoryTechnology
+ { // MemoryOperatingModeCapability
+ .Uint16 = 0x000
+ },
+ 5, // FirmwareVersion
+ 0, // ModuleManufacturerId
+ 0, // ModuleProductId
+ 0, // MemorySubsystemContollerManufacturerId
+ 0, // MemorySybsystemControllerProductId
+ 0, // NonVolatileSize
+ 0, // VolatileSize
+ 0, // CacheSize
+ 0, // LogicalSize
+ 0, // ExtendedSpeed
+ 0, // ExtendedConfiguredMemorySpeed
+};
+
+STATIC CHAR8 UnknownStr[] = "Unknown\0";
+
+STATIC
+EFI_STATUS
+EFIAPI
+FreeSmbiosType17TableEx (
+ IN CONST SMBIOS_TABLE_GENERATOR *CONST This,
+ IN CONST CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT SMBIOS_STRUCTURE ***CONST Table,
+ IN CONST UINTN TableCount
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/** Construct SMBIOS Type17 Table describing memory devices.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the SMBIOS table generator.
+ @param [in] SmbiosTableInfo Pointer to the SMBIOS table information.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol interface.
+ @param [out] Table Pointer to the SMBIOS table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for
+ the requested object.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Could not find information.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
+ @retval EFI_UNSUPPORTED Unsupported configuration.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildSmbiosType17TableEx (
+ IN CONST SMBIOS_TABLE_GENERATOR *This,
+ IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ OUT SMBIOS_STRUCTURE ***Table,
+ OUT UINTN *CONST TableCount
+ )
+{
+ EFI_STATUS Status;
+ UINT32 NumMemDevices;
+ SMBIOS_STRUCTURE **TableList;
+ CM_ARM_MEMORY_DEVICE_INFO *MemoryDevicesInfo;
+ UINTN Index;
+ UINTN SerialNumLen;
+ CHAR8 *SerialNum;
+ UINTN AssetTagLen;
+ CHAR8 *AssetTag;
+ UINTN DeviceLocatorLen;
+ CHAR8 *DeviceLocator;
+ UINTN BankLocatorLen;
+ CHAR8 *BankLocator;
+ UINTN FirmwareVersionLen;
+ CHAR8 *FirmwareVersion;
+ CHAR8 *OptionalStrings;
+ SMBIOS_TABLE_TYPE17 *SmbiosRecord;
+
+ ASSERT (This != NULL);
+ ASSERT (SmbiosTableInfo != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Table != NULL);
+ ASSERT (TableCount != NULL);
+ ASSERT (SmbiosTableInfo->TableGeneratorId == This->GeneratorID);
+
+ DEBUG ((DEBUG_ERROR, "%a : Start \n", __FUNCTION__));
+ *Table = NULL;
+ Status = GetEArmObjMemoryDeviceInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &MemoryDevicesInfo,
+ &NumMemDevices
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "Failed to get Memory Devices CM Object %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ TableList = (SMBIOS_STRUCTURE **)AllocateZeroPool (sizeof (SMBIOS_STRUCTURE *) * NumMemDevices);
+ if (TableList == NULL) {
+ DEBUG ((DEBUG_ERROR, "Failed to alloc memory for %u devices table\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+
+ for (Index = 0; Index < NumMemDevices; Index++) {
+ if (MemoryDevicesInfo[Index].SerialNum != NULL) {
+ SerialNumLen = AsciiStrLen (MemoryDevicesInfo[Index].SerialNum);
+ SerialNum = MemoryDevicesInfo[Index].SerialNum;
+ } else {
+ SerialNumLen = AsciiStrLen (UnknownStr);
+ SerialNum = UnknownStr;
+ }
+
+ if (MemoryDevicesInfo[Index].AssetTag != NULL) {
+ AssetTagLen = AsciiStrLen (MemoryDevicesInfo[Index].AssetTag);
+ AssetTag = MemoryDevicesInfo[Index].AssetTag;
+ } else {
+ AssetTagLen = AsciiStrLen (UnknownStr);
+ AssetTag = UnknownStr;
+ }
+
+ if (MemoryDevicesInfo[Index].DeviceLocator != NULL) {
+ DeviceLocatorLen = AsciiStrLen (MemoryDevicesInfo[Index].DeviceLocator);
+ DeviceLocator = MemoryDevicesInfo[Index].DeviceLocator;
+ } else {
+ DeviceLocatorLen = AsciiStrLen (UnknownStr);
+ DeviceLocator = UnknownStr;
+ }
+
+ if (MemoryDevicesInfo[Index].BankLocator != NULL) {
+ BankLocatorLen = AsciiStrLen (MemoryDevicesInfo[Index].BankLocator);
+ BankLocator = MemoryDevicesInfo[Index].BankLocator;
+ } else {
+ BankLocatorLen = AsciiStrLen (UnknownStr);
+ BankLocator = UnknownStr;
+ }
+
+ if (MemoryDevicesInfo[Index].FirmwareVersion != NULL) {
+ FirmwareVersionLen = AsciiStrLen (MemoryDevicesInfo[Index].FirmwareVersion);
+ FirmwareVersion = MemoryDevicesInfo[Index].FirmwareVersion;
+ } else {
+ FirmwareVersionLen = AsciiStrLen (UnknownStr);
+ FirmwareVersion = UnknownStr;
+ }
+
+ SmbiosRecord = (SMBIOS_TABLE_TYPE17 *)AllocateZeroPool (
+ sizeof (SMBIOS_TABLE_TYPE17) +
+ SerialNumLen + 1 +
+ AssetTagLen + 1 + DeviceLocatorLen + 1 +
+ BankLocatorLen + 1 + FirmwareVersionLen + 1 + 1
+ );
+ if (SmbiosRecord == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+
+ CopyMem (SmbiosRecord, &MemDeviceInfoTemplate, sizeof (SMBIOS_TABLE_TYPE17));
+ SmbiosRecord->ExtendedSize = MemoryDevicesInfo[Index].Size;
+ SmbiosRecord->DeviceSet = MemoryDevicesInfo[Index].DeviceSet;
+ SmbiosRecord->ModuleManufacturerID =
+ MemoryDevicesInfo[Index].ModuleManufacturerId;
+ SmbiosRecord->ModuleProductID =
+ MemoryDevicesInfo[Index].ModuleProductId;
+ SmbiosRecord->Attributes =
+ MemoryDevicesInfo[Index].Attributes;
+ SmbiosRecord->ExtendedSpeed = MemoryDevicesInfo[Index].Speed;
+ OptionalStrings = (CHAR8 *)(SmbiosRecord + 1);
+ AsciiSPrint (OptionalStrings, DeviceLocatorLen + 1, DeviceLocator);
+ OptionalStrings = OptionalStrings + DeviceLocatorLen + 1;
+ AsciiSPrint (OptionalStrings, BankLocatorLen + 1, BankLocator);
+ OptionalStrings = OptionalStrings + BankLocatorLen + 1;
+ AsciiSPrint (OptionalStrings, SerialNumLen + 1, SerialNum);
+ OptionalStrings = OptionalStrings + SerialNumLen + 1;
+ AsciiSPrint (OptionalStrings, AssetTagLen + 1, AssetTag);
+ OptionalStrings = OptionalStrings + AssetTagLen + 1;
+ AsciiSPrint (OptionalStrings, FirmwareVersionLen + 1, FirmwareVersion);
+ OptionalStrings = OptionalStrings + FirmwareVersionLen + 1;
+ TableList[Index] = (SMBIOS_STRUCTURE *)SmbiosRecord;
+ }
+
+ *Table = TableList;
+ *TableCount = NumMemDevices;
+
+exit:
+ DEBUG ((DEBUG_ERROR, "%a : Done \n", __FUNCTION__));
+ return Status;
+}
+
+/** The interface for the SMBIOS Type17 Table Generator.
+*/
+STATIC
+CONST
+SMBIOS_TABLE_GENERATOR SmbiosType17Generator = {
+ // Generator ID
+ CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdType17),
+ // Generator Description
+ L"SMBIOS.TYPE17.GENERATOR",
+ // SMBIOS Table Type
+ EFI_SMBIOS_TYPE_MEMORY_DEVICE,
+ NULL,
+ NULL,
+ // Build table function Extended.
+ BuildSmbiosType17TableEx,
+ // Free function Extended.
+ FreeSmbiosType17TableEx
+};
+
+/** Register the Generator with the SMBIOS Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+SmbiosType17LibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = RegisterSmbiosTableGenerator (&SmbiosType17Generator);
+ DEBUG ((
+ DEBUG_INFO,
+ "SMBIOS Type 17: Register Generator. Status = %r\n",
+ Status
+ ));
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/** Deregister the Generator from the SMBIOS Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+SmbiosType17LibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = DeregisterSmbiosTableGenerator (&SmbiosType17Generator);
+ DEBUG ((
+ DEBUG_INFO,
+ "SMBIOS Type17: Deregister Generator. Status = %r\n",
+ Status
+ ));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Smbios/Arm/SmbiosType17Lib/SmbiosType17LibArm.inf b/DynamicTablesPkg/Library/Smbios/Arm/SmbiosType17Lib/SmbiosType17LibArm.inf
new file mode 100644
index 0000000000..78a80b75f0
--- /dev/null
+++ b/DynamicTablesPkg/Library/Smbios/Arm/SmbiosType17Lib/SmbiosType17LibArm.inf
@@ -0,0 +1,32 @@
+## @file
+# SMBIOS Type17 Table Generator
+#
+# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = SmbiosType17LibArm
+ FILE_GUID = 1f063bac-f8f1-4e08-8ffd-9aae52c75497
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = NULL|DXE_DRIVER
+ CONSTRUCTOR = SmbiosType17LibConstructor
+ DESTRUCTOR = SmbiosType17LibDestructor
+
+[Sources]
+ SmbiosType17Generator.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
--
2.17.1


[PATCH 1/2] DynamicTablesPkg: Add SMBIOS table generation

Girish Mahadevan
 

Modify the DynamicTableManagerDxe driver to install SMBIOS tables in
addition to ACPI tables.
Instead of adding gEfiSmbiosProtocolGuid to the DEPEX list, setup
callback notifications for gEfiSmbiosProtocolGuid and
gEfiAcpiTableProtocolGuid and install the SMBIOS and ACPI tables
in the respective notification ready callback functions.

Add the ability to install multiple SMBIOS tables to the SMBIOS
factory generator similar to ACPI.

Signed-off-by: Girish Mahadevan <gmahadevan@...>
---
.../DynamicTableManagerDxe.c | 585 +++++++++++++++++-
.../DynamicTableManagerDxe.inf | 2 +-
.../Include/SmbiosTableGenerator.h | 50 ++
3 files changed, 628 insertions(+), 9 deletions(-)

diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
index ed62299f9b..1642d6c387 100644
--- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
@@ -8,9 +8,11 @@
**/

#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/AcpiTable.h>
+#include <Protocol/Smbios.h>

// Module specific include files.
#include <AcpiTableGenerator.h>
@@ -31,6 +33,18 @@ GET_OBJECT_LIST (
CM_STD_OBJ_ACPI_TABLE_INFO
)

+/** This macro expands to a function that retrieves the SMBIOS Table
+ List from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceStandard,
+ EStdObjSmbiosTableList,
+ CM_STD_OBJ_SMBIOS_TABLE_INFO
+ )
+
+STATIC VOID *AcpiTableProtocolRegistration;
+STATIC VOID *SmbiosProtocolRegistration;
+
/** A helper function to build and install a single ACPI table.

This is a helper function that invokes the Table generator interface
@@ -478,6 +492,449 @@ VerifyMandatoryTablesArePresent (
return Status;
}

+/** A helper function to build and install an SMBIOS table.
+
+ This is a helper function that invokes the Table generator interface
+ for building an SMBIOS table. It uses the SmbiosProtocol to install the
+ table, then frees the resources allocated for generating it.
+
+ @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
+ interface.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] SmbiosProtocol Pointer to the SMBIOS protocol.
+ @param [in] SmbiosTableInfo Pointer to the SMBIOS table Info.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Required object is not found.
+ @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
+ is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildAndInstallSingleSmbiosTable (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CONST SMBIOS_TABLE_GENERATOR *CONST Generator,
+ IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol,
+ IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ SMBIOS_STRUCTURE *SmbiosTable;
+ EFI_SMBIOS_HANDLE TableHandle;
+
+ SmbiosTable = NULL;
+ Status = Generator->BuildSmbiosTable (
+ Generator,
+ SmbiosTableInfo,
+ CfgMgrProtocol,
+ &SmbiosTable
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Build Table." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->TableGeneratorId,
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ if (SmbiosTable == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto exit_handler;
+ }
+
+ TableHandle = SMBIOS_HANDLE_PI_RESERVED;
+ // Install SMBIOS table
+ Status = SmbiosProtocol->Add (
+ SmbiosProtocol,
+ NULL,
+ &TableHandle,
+ SmbiosTable
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Install SMBIOS Table. Status = %r\n",
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: SMBIOS Table installed. Status = %r\n",
+ Status
+ ));
+
+exit_handler:
+ // Free any resources allocated for generating the tables.
+ if (Generator->FreeTableResources != NULL) {
+ Status1 = Generator->FreeTableResources (
+ Generator,
+ SmbiosTableInfo,
+ CfgMgrProtocol,
+ &SmbiosTable
+ );
+ if (EFI_ERROR (Status1)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Free Table Resources." \
+ "TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->TableGeneratorId,
+ Status1
+ ));
+ }
+
+ // Return the first error status in case of failure
+ if (!EFI_ERROR (Status)) {
+ Status = Status1;
+ }
+ }
+
+ return Status;
+}
+
+/** A helper function to build and install multiple SMBIOS tables.
+
+ This is a helper function that invokes the Table generator interface
+ for building SMBIOS tables. It uses the SmbiosProtocol to install the
+ tables, then frees the resources allocated for generating it.
+
+ @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
+ interface.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Generator Pointer to the SmbiosTable generator.
+ @param [in] SmbiosProtocol Pointer to the Smbios protocol.
+ @param [in] AcpiTableInfo Pointer to the SMBIOS table Info.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Required object is not found.
+ @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
+ is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildAndInstallMultipleSmbiosTables (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CONST SMBIOS_TABLE_GENERATOR *CONST Generator,
+ IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol,
+ IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ SMBIOS_STRUCTURE **SmbiosTable;
+ EFI_SMBIOS_HANDLE TableHandle;
+ UINTN TableCount;
+ UINTN Index;
+
+ TableCount = 0;
+ Status = Generator->BuildSmbiosTableEx (
+ Generator,
+ SmbiosTableInfo,
+ CfgMgrProtocol,
+ &SmbiosTable,
+ &TableCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Build Table." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->TableGeneratorId,
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ if ((SmbiosTable == NULL) || (TableCount == 0)) {
+ Status = EFI_NOT_FOUND;
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: TableCount %u SmbiosTable %p \n",
+ __FUNCTION__,
+ TableCount,
+ SmbiosTable
+ ));
+ goto exit_handler;
+ }
+
+ for (Index = 0; Index < TableCount; Index++) {
+ TableHandle = SMBIOS_HANDLE_PI_RESERVED;
+ // Install SMBIOS table
+ Status = SmbiosProtocol->Add (
+ SmbiosProtocol,
+ NULL,
+ &TableHandle,
+ SmbiosTable[Index]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Install SMBIOS Table. Status = %r\n",
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: SMBIOS Table installed. Status = %r\n",
+ Status
+ ));
+ }
+
+exit_handler:
+ // Free any resources allocated for generating the tables.
+ if (Generator->FreeTableResourcesEx != NULL) {
+ Status1 = Generator->FreeTableResourcesEx (
+ Generator,
+ SmbiosTableInfo,
+ CfgMgrProtocol,
+ &SmbiosTable,
+ TableCount
+ );
+ if (EFI_ERROR (Status1)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Free Table Resources." \
+ "TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->TableGeneratorId,
+ Status1
+ ));
+ }
+
+ // Return the first error status in case of failure
+ if (!EFI_ERROR (Status)) {
+ Status = Status1;
+ }
+ }
+
+ return Status;
+}
+
+/** A helper function to invoke a Table generator
+
+ This is a helper function that invokes the Table generator interface
+ for building an SMBIOS table. It uses the SmbiosProtocol to install the
+ table, then frees the resources allocated for generating it.
+
+ @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
+ interface.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] SmbiosProtocol Pointer to the SMBIOS protocol.
+ @param [in] SmbiosTableInfo Pointer to the SMBIOS table Info.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Required object is not found.
+ @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
+ is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildAndInstallSmbiosTable (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol,
+ IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo
+ )
+{
+ EFI_STATUS Status;
+ CONST SMBIOS_TABLE_GENERATOR *Generator;
+
+ ASSERT (TableFactoryProtocol != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (SmbiosProtocol != NULL);
+ ASSERT (SmbiosTableInfo != NULL);
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: EStdObjSmbiosTableList: Address = 0x%p," \
+ " TableGeneratorId = 0x%x\n",
+ SmbiosTableInfo,
+ SmbiosTableInfo->TableGeneratorId
+ ));
+
+ Generator = NULL;
+ Status = TableFactoryProtocol->GetSmbiosTableGenerator (
+ TableFactoryProtocol,
+ SmbiosTableInfo->TableGeneratorId,
+ &Generator
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Table Generator not found." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->TableGeneratorId,
+ Status
+ ));
+ return Status;
+ }
+
+ if (Generator == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: Generator found : %s\n",
+ Generator->Description
+ ));
+
+ if (Generator->BuildSmbiosTableEx != NULL) {
+ Status = BuildAndInstallMultipleSmbiosTables (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ Generator,
+ SmbiosProtocol,
+ SmbiosTableInfo
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find build and install SMBIOS Tables." \
+ " Status = %r\n",
+ Status
+ ));
+ }
+ } else if (Generator->BuildSmbiosTable != NULL) {
+ Status = BuildAndInstallSingleSmbiosTable (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ Generator,
+ SmbiosProtocol,
+ SmbiosTableInfo
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find build and install SMBIOS Table." \
+ " Status = %r\n",
+ Status
+ ));
+ }
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Table Generator does not implement the" \
+ "SMBIOS_TABLE_GENERATOR_BUILD_TABLE interface." \
+ " TableGeneratorId = 0x%x. Status = %r\n",
+ SmbiosTableInfo->TableGeneratorId,
+ Status
+ ));
+ }
+
+ return Status;
+}
+
+/** Generate and install SMBIOS tables.
+
+ The function gathers the information necessary for installing the
+ SMBIOS tables from the Configuration Manager, invokes the generators
+ and installs them (via BuildAndInstallAcpiTable).
+
+ @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
+ interface.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_NOT_FOUND If a mandatory table or a generator is not found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ProcessSmbiosTables (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBIOS_PROTOCOL *SmbiosProtocol;
+ CM_STD_OBJ_SMBIOS_TABLE_INFO *SmbiosTableInfo;
+ UINT32 SmbiosTableCount;
+ UINT32 Idx;
+
+ Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&SmbiosProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol. %r\n", Status));
+ return Status;
+ }
+
+ Status = GetEStdObjSmbiosTableList (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &SmbiosTableInfo,
+ &SmbiosTableCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to get SMBIOS Table List. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ if (SmbiosTableCount == 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: EStdObjSmbiosTableList: SmbiosTableCount = %d\n",
+ SmbiosTableCount
+ ));
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: EStdObjSmbiosTableList: SmbiosTableCount = %d\n",
+ SmbiosTableCount
+ ));
+
+ for (Idx = 0; Idx < SmbiosTableCount; Idx++) {
+ Status = BuildAndInstallSmbiosTable (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ SmbiosProtocol,
+ &SmbiosTableInfo[Idx]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to install SMBIOS Table." \
+ " Id = %u Status = %r\n",
+ SmbiosTableInfo[Idx].TableGeneratorId,
+ Status
+ ));
+ }
+ }
+
+ return Status;
+}
+
/** Generate and install ACPI tables.

The function gathers the information necessary for installing the
@@ -664,11 +1121,11 @@ ProcessAcpiTables (
@retval EFI_NOT_FOUND Required interface/object was not found.
@retval EFI_INVALID_PARAMETER Some parameter is incorrect/invalid.
**/
-EFI_STATUS
-EFIAPI
-DynamicTableManagerDxeInitialize (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
+STATIC
+VOID
+AcpiTableProtocolReady (
+ IN EFI_EVENT Event,
+ IN VOID *Context
)
{
EFI_STATUS Status;
@@ -689,7 +1146,7 @@ DynamicTableManagerDxeInitialize (
" Status = %r\n",
Status
));
- return Status;
+ return;
}

// Locate the Configuration Manager for the Platform
@@ -704,7 +1161,7 @@ DynamicTableManagerDxeInitialize (
"ERROR: Failed to find Configuration Manager protocol. Status = %r\n",
Status
));
- return Status;
+ return;
}

Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo);
@@ -714,7 +1171,7 @@ DynamicTableManagerDxeInitialize (
"ERROR: Failed to get Configuration Manager info. Status = %r\n",
Status
));
- return Status;
+ return;
}

DEBUG ((
@@ -737,6 +1194,118 @@ DynamicTableManagerDxeInitialize (
Status
));
}
+}
+
+STATIC
+VOID
+SmbiosProtocolReady (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgrProtocol;
+ CM_STD_OBJ_CONFIGURATION_MANAGER_INFO *CfgMfrInfo;
+ EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *TableFactoryProtocol;
+
+ // Locate the Dynamic Table Factory
+ Status = gBS->LocateProtocol (
+ &gEdkiiDynamicTableFactoryProtocolGuid,
+ NULL,
+ (VOID **)&TableFactoryProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find Dynamic Table Factory protocol." \
+ " Status = %r\n",
+ Status
+ ));
+ return;
+ }
+
+ // Locate the Configuration Manager for the Platform
+ Status = gBS->LocateProtocol (
+ &gEdkiiConfigurationManagerProtocolGuid,
+ NULL,
+ (VOID **)&CfgMgrProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find Configuration Manager protocol. Status = %r\n",
+ Status
+ ));
+ return;
+ }
+
+ Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to get Configuration Manager info. Status = %r\n",
+ Status
+ ));
+ return;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: Configuration Manager Version = 0x%x, OemID = %c%c%c%c%c%c\n",
+ CfgMfrInfo->Revision,
+ CfgMfrInfo->OemId[0],
+ CfgMfrInfo->OemId[1],
+ CfgMfrInfo->OemId[2],
+ CfgMfrInfo->OemId[3],
+ CfgMfrInfo->OemId[4],
+ CfgMfrInfo->OemId[5]
+ ));
+
+ Status = ProcessSmbiosTables (TableFactoryProtocol, CfgMgrProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SMBIOS Table processing failure. Status = %r\n",
+ Status
+ ));
+ }
+}
+
+EFI_STATUS
+EFIAPI
+DynamicTableManagerDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT AcpiEvent;
+ EFI_EVENT SmbiosEvent;
+
+ AcpiEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiAcpiTableProtocolGuid,
+ TPL_CALLBACK,
+ AcpiTableProtocolReady,
+ NULL,
+ &AcpiTableProtocolRegistration
+ );
+ if (AcpiEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to ACPI create protocol event\r\n", __FUNCTION__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ SmbiosEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiSmbiosProtocolGuid,
+ TPL_CALLBACK,
+ SmbiosProtocolReady,
+ NULL,
+ &SmbiosProtocolRegistration
+ );
+ if (SmbiosEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to SMBIOS create protocol event\r\n", __FUNCTION__));
+ gBS->CloseEvent (AcpiEvent);
+ return EFI_OUT_OF_RESOURCES;
+ }

return Status;
}
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
index 028c3d413c..ccf58f6099 100644
--- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
@@ -36,12 +36,12 @@

[Protocols]
gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED

gEdkiiConfigurationManagerProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEdkiiDynamicTableFactoryProtocolGuid # PROTOCOL ALWAYS_CONSUMED

[Depex]
- gEfiAcpiTableProtocolGuid AND
gEdkiiConfigurationManagerProtocolGuid AND
gEdkiiDynamicTableFactoryProtocolGuid

diff --git a/DynamicTablesPkg/Include/SmbiosTableGenerator.h b/DynamicTablesPkg/Include/SmbiosTableGenerator.h
index 934d56c90d..7bf6300d90 100644
--- a/DynamicTablesPkg/Include/SmbiosTableGenerator.h
+++ b/DynamicTablesPkg/Include/SmbiosTableGenerator.h
@@ -168,6 +168,48 @@ typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_FREE_TABLE) (
IN SMBIOS_STRUCTURE **Table
);

+/** This function pointer describes the interface to SMBIOS table build
+ functions provided by the SMBIOS table generator and called by the
+ Table Manager to build an SMBIOS table.
+
+ @param [in] Generator Pointer to the SMBIOS table generator.
+ @param [in] SmbiosTableInfo Pointer to the SMBIOS table information.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol interface.
+ @param [out] Table Pointer to the generated SMBIOS table.
+
+ @return EFI_SUCCESS If the table is generated successfully or other
+ failure codes as returned by the generator.
+**/
+typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_BUILD_TABLEEX) (
+ IN CONST SMBIOS_TABLE_GENERATOR *Generator,
+ IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ OUT SMBIOS_STRUCTURE ***Table,
+ OUT UINTN *CONST TableCount
+ );
+
+/** This function pointer describes the interface to used by the
+ Table Manager to give the generator an opportunity to free
+ any resources allocated for building the SMBIOS table.
+
+ @param [in] Generator Pointer to the SMBIOS table generator.
+ @param [in] SmbiosTableInfo Pointer to the SMBIOS table information.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol interface.
+ @param [in] Table Pointer to the generated SMBIOS table.
+
+ @return EFI_SUCCESS If freed successfully or other failure codes
+ as returned by the generator.
+**/
+typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_FREE_TABLEEX) (
+ IN CONST SMBIOS_TABLE_GENERATOR *Generator,
+ IN CONST CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN SMBIOS_STRUCTURE ***Table,
+ IN CONST UINTN TableCount
+ );
+
/** The SMBIOS_TABLE_GENERATOR structure provides an interface that the
Table Manager can use to invoke the functions to build SMBIOS tables.
*/
@@ -189,6 +231,14 @@ typedef struct SmbiosTableGenerator {
allocated for building the SMBIOS table.
*/
SMBIOS_TABLE_GENERATOR_FREE_TABLE FreeTableResources;
+
+ /// SMBIOS table extended build function pointer.
+ SMBIOS_TABLE_GENERATOR_BUILD_TABLEEX BuildSmbiosTableEx;
+
+ /** The function to free any resources
+ allocated for building the SMBIOS table.
+ */
+ SMBIOS_TABLE_GENERATOR_FREE_TABLEEX FreeTableResourcesEx;
} SMBIOS_TABLE_GENERATOR;

/** Register SMBIOS table factory generator.
--
2.17.1


Re: [edk2-platforms][PATCH v2 1/1] MinPlatformPkg: Add FspNvsBuffer compression option

Michael Kubacki
 

Honestly, I forgot about the open board packages, I can definitely update support for thosee.

Automating Contribution Expectations
------------------------------------
As Tianocore modernizes its development process, PR template checklists and CI including board package builds would automate a broad range of contribution expectations including what packages need to build against what targets, toolchains, analysis tools, etc.

In this case, I understand what needs to be done but others might not.

Board vs FSP Compression
------------------------
I agree that the wrapper should be responsible for determining how to manage data.

For the reasons Isaac mentioned - platform selection of compression algorithms, cohesive platform data managment in its data store, minimizing FSP size, etc.

By FSP focusing on only what it requires, it provides opportunity for simpler and more flexible integration and optimization around its interface.

LargeVariableLib Support
------------------------
I am in favor of not modifying LargeVariableLib.

Going back to the FSP compression topic, I prefer simple (single responsibility) interfaces. FSP initializes silicon. As part of its input interface, it needs some context data (NVS buffer data) to determine its internal state transitions.

By decoupling peripheral functionality from within FSP, it can easily be reasoned that data compression is not silicon init, therefore, FSP should not perform data compression.

Interfaces often require data input. We (everyone) have a tendency to extend those interface with various options for data transformation over time. For example, this has made the UEFI variable interface error prone and cumbersome to adapt to different environments.

When I look at LargeVariableWriteLib.h and LargeVariableReadLib.h, I see a wrapper around the UEFI variable services that is relatively easy to understand and to determine if it fits my use case - I want to work around the maximum UEFI variable size set on a platform.

On the surface at least, the interface is simple - it mostly mirrors the UEFI RT Services functions, the use case is easy to understand, and the expected behavior is easy to comprehend.

I'm trying to understand what advantage there is to complicating this.

Compression already has an abstraction in its library classes - CompressLib and UefiDecompressLib. Those could be more symmetrical, etc. but they're relatively easy to understand and reason about as well.

So this is a question of whether to invoke that abstraction outside the LargeVariableLib interfaces or underneath its implementation.

When outside:
- The caller is given a simpler LargeVariableLib interface to use.
- The caller does not need to understand LargeVariableLib compression
implementation details.
- The caller is free to choose a different compression abstraction.
- The caller is given flexibility to transform data given to
LargeVariableLib in the order they choose.
- Example: Encrypt then compress vs compress then encrypt

When in VariableLargeLib:
- The caller has to understand a more complex configuration interface.
- The caller loses most of the above and still has to worry about
linking suitable compression code.
- They might save some lines of code but that is not valuable.

As you can see, I would personlly prefer for LargeVariableLib to stay simple and let integration of data transformations occur as needed based on the caller's needs.

But, I can try to add this in a reasonable way if it is strongly preferred.

V2 Proposal
-----------
For V2, would it be okay to simply add support for the boards as Isaac mentioned in the first mail. It could be taken further in the future if desired.


Thanks,
Michael

On 8/23/2022 8:55 PM, Oram, Isaac W wrote:
A PCD to control library class instance seems redundant. The build already has capabilities to control library class instance per driver, per driver type, per architecture, etc. Let me know if there is some benefit to overriding PCD in board DSC vs overriding library class in board DSC that I am missing.
We want to simplify what developers need to see and deal with. Minimize the number of basic decisions needed to get a functional port. I would prefer a single instance of LargeVariable*Lib. As a board port developer, if your silicon FSP supports compressing the data and your board port doesn't want the redundancy, that is a stage 7 optimization to write your own instance of the library class or your own version of SaveMemoryConfigDxe. No need to burden the rest of the boards with needing to know about and configure this to optimize a corner case.
I also think decompression and compression decisions should reside at the boot loader level not internal to FSP. First to minimize FSP content, second because bootloaders already typically decide and implement decompression that matches their build specific compression. I will grant that it is probably mostly the same common algorithm implementation.
Ultimately though, those are mostly philosophical objections. If you really want two instances of the library, I can live with it. I will be able to have reasonable default behavior that is pretty simple for most.
The more concrete objection is the asymmetric design, where common code implements compression and per platform code implements decompression. That seems distasteful. I can live with this too because it is kind of already this way, but more consistent combined with more encapsulated seems better than expanding the asymmetric design.
Regards,
Isaac
-----Original Message-----
From: Desimone, Nathaniel L <nathaniel.l.desimone@...>
Sent: Tuesday, August 23, 2022 12:51 PM
To: Oram, Isaac W <isaac.w.oram@...>; devel@edk2.groups.io; mikuback@...
Cc: Chiu, Chasel <chasel.chiu@...>; Gao, Liming <gaoliming@...>; Dong, Eric <eric.dong@...>
Subject: RE: [edk2-devel] [edk2-platforms][PATCH v2 1/1] MinPlatformPkg: Add FspNvsBuffer compression option
Agreed with Isaac that having the compression capability be more general use would be nice. However, I think it would better match the EDK II design style if we had a second implementation of LargeVariable*Lib that added the compression capability on top of the original LargeVariable*Lib.
I also think having a PCD to explicitly control whether to apply compression to the FSP NVS buffer is important. Because there are some FSP implementations like ICX and SPR that already include the CompressLib inside the FSP binary itself. On those FSP implementations, the data in the FSP_NON_VOLATILE_STORAGE_HOB is already compressed. Said PCD would simply control which instance of the LibraryClass gets linked with SaveMemoryConfigDxe.
Also agreed with Isaac to please be careful to make sure that any new LibraryClasses are in the Include/*.dsc files somewhere so existing boards don't need modifications to their BoardPkg.dsc file.
Thanks,
Nate
-----Original Message-----
From: Oram, Isaac W <isaac.w.oram@...>
Sent: Tuesday, August 23, 2022 11:34 AM
To: devel@edk2.groups.io; mikuback@...
Cc: Chiu, Chasel <chasel.chiu@...>; Desimone, Nathaniel L <nathaniel.l.desimone@...>; Gao, Liming <gaoliming@...>; Dong, Eric <eric.dong@...>
Subject: RE: [edk2-devel] [edk2-platforms][PATCH v2 1/1] MinPlatformPkg: Add FspNvsBuffer compression option
Implementing this way will break the build for most of the open MinPlatform ports. At minimum, please add the CompressLib to CoreCommonLib.dsc next to the UefiDecompressLib instantiation so that it is included automatically for most boards.
Regarding the design, I agree this is a good capability. And it makes sense to me to be board controlled rather than FSP controlled.
I wonder if it might be better to modify the LargeVariableRead/Write such that it compresses/decompresses large variables automatically. Could be controlled via library class instance or maybe via PatchablePerModule PCD. Boards would still have a lot of control if they wanted.
Regards,
Isaac
-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Michael Kubacki
Sent: Monday, August 22, 2022 8:23 PM
To: devel@edk2.groups.io
Cc: Chiu, Chasel <chasel.chiu@...>; Desimone, Nathaniel L <nathaniel.l.desimone@...>; Oram, Isaac W <isaac.w.oram@...>; Gao, Liming <gaoliming@...>; Dong, Eric <eric.dong@...>
Subject: [edk2-devel] [edk2-platforms][PATCH v2 1/1] MinPlatformPkg: Add FspNvsBuffer compression option
From: Michael Kubacki <michael.kubacki@...>
Adds a PCD called "PcdEnableCompressedFspNvsBuffer" that allows the "FspNvsBuffer" UEFI variable data to be saved as compressed data.
Especially due to the nature of the data saved in this variable, it compresses well. For example, it has been found to reduce ~63KB of data to ~13KB. Boot time impact has been found to be negligible.
The default value is FALSE to keep default behavior consistent.
Decompression can be performed on the variable data using the standard UefiDecompressLib.
Cc: Chasel Chiu <chasel.chiu@...>
Cc: Nate DeSimone <nathaniel.l.desimone@...>
Cc: Isaac Oram <isaac.w.oram@...>
Cc: Liming Gao <gaoliming@...>
Cc: Eric Dong <eric.dong@...>
Signed-off-by: Michael Kubacki <michael.kubacki@...>
---
Notes:
v2: Rebase onto 9769bf28d1fc
Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c | 62 ++++++++++++++++----
Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf | 4 ++
Platform/Intel/MinPlatformPkg/MinPlatformPkg.dec | 6 ++
Platform/Intel/MinPlatformPkg/MinPlatformPkg.dsc | 1 +
4 files changed, 60 insertions(+), 13 deletions(-)
diff --git a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c
index 0215e8eeddfb..95b8cef8b32b 100644
--- a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c
+++ b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemo
+++ ryConfig.c
@@ -3,6 +3,7 @@
exists, and saves the data to nvRAM.
Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -10,6 +11,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include <Base.h> #include <Uefi.h> #include <Library/BaseLib.h>
+#include <Library/CompressLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/HobLib.h>
@@ -19,6 +21,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include <Library/BaseMemoryLib.h> #include <Library/LargeVariableReadLib.h> #include <Library/LargeVariableWriteLib.h>
+#include <Library/PcdLib.h>
#include <Library/VariableWriteLib.h>
#include <Guid/FspNonVolatileStorageHob2.h>
@@ -38,20 +41,26 @@ SaveMemoryConfigEntryPoint (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
- EFI_STATUS Status;
- EFI_HOB_GUID_TYPE *GuidHob;
- VOID *HobData;
- VOID *VariableData;
- UINTN DataSize;
- UINTN BufferSize;
- BOOLEAN DataIsIdentical;
+ EFI_STATUS Status;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VOID *HobData;
+ VOID *VariableData;
+ UINTN DataSize;
+ UINTN BufferSize;
+ BOOLEAN DataIsIdentical;
+ VOID *CompressedData;
+ UINT64 CompressedSize;
+ UINTN CompressedAllocationPages;
- DataSize = 0;
- BufferSize = 0;
- VariableData = NULL;
- GuidHob = NULL;
- HobData = NULL;
- DataIsIdentical = FALSE;
+ DataSize = 0;
+ BufferSize = 0;
+ VariableData = NULL;
+ GuidHob = NULL;
+ HobData = NULL;
+ DataIsIdentical = FALSE;
+ CompressedData = NULL;
+ CompressedSize = 0;
+ CompressedAllocationPages = 0;
//
// Search for the Memory Configuration GUID HOB. If it is not present, then @@ -73,6 +82,29 @@ SaveMemoryConfigEntryPoint (
}
}
+ if (PcdGetBool (PcdEnableCompressedFspNvsBuffer)) {
+ if (DataSize > 0) {
+ CompressedAllocationPages = EFI_SIZE_TO_PAGES (DataSize);
+ CompressedData = AllocatePages (CompressedAllocationPages);
+ if (CompressedData == NULL) {
+ DEBUG ((DEBUG_ERROR, "[%a] - Failed to allocate compressed data buffer.\n", __FUNCTION__));
+ ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CompressedSize = EFI_PAGES_TO_SIZE (CompressedAllocationPages);
+ Status = Compress (HobData, DataSize, CompressedData, &CompressedSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "[%a] - failed to compress data. Status = %r\n", __FUNCTION__, Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
+
+ HobData = CompressedData;
+ DataSize = (UINTN)CompressedSize;
+ }
+
if (HobData != NULL) {
DEBUG ((DEBUG_INFO, "FspNvsHob.NvsDataLength:%d\n", DataSize));
DEBUG ((DEBUG_INFO, "FspNvsHob.NvsDataPtr : 0x%x\n", HobData));
@@ -136,6 +168,10 @@ SaveMemoryConfigEntryPoint (
DEBUG((DEBUG_ERROR, "Memory S3 Data HOB was not found\n"));
}
+ if (CompressedData != NULL) {
+ FreePages (CompressedData, CompressedAllocationPages); }
+
//
// This driver does not produce any protocol services, so always unload it.
//
diff --git a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf
index 61e85a658693..0f12deb131ca 100644
--- a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf
+++ b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemo
+++ ryConfig.inf
@@ -26,6 +26,7 @@ [LibraryClasses]
LargeVariableReadLib
LargeVariableWriteLib
BaseLib
+ CompressLib
[Packages]
MdePkg/MdePkg.dec
@@ -45,6 +46,9 @@ [Guids]
gFspNonVolatileStorageHob2Guid ## CONSUMES
gFspNvsBufferVariableGuid ## PRODUCES
+[Pcd]
+ gMinPlatformPkgTokenSpaceGuid.PcdEnableCompressedFspNvsBuffer
+
[Depex]
gEfiVariableArchProtocolGuid AND
gEfiVariableWriteArchProtocolGuid
\ No newline at end of file
diff --git a/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dec b/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dec
index 8e603b7bf94b..94353cb76824 100644
--- a/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dec
+++ b/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dec
@@ -306,6 +306,12 @@ [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
gMinPlatformPkgTokenSpaceGuid.PcdPlatformMemoryCheckLevel|0|UINT32|0x30000009
+ ## Controls whether the FSP NVS buffer is saved as compressed data.
+ # Data compression can significantly reduce variable storage usage for FSP NVS buffer data.
+ # Platforms that choose to compress the data will need to decompress
+ the variable data upon # extraction.
+
+ gMinPlatformPkgTokenSpaceGuid.PcdEnableCompressedFspNvsBuffer|FALSE|BO
+ OLEAN|0x30000010
+
## This PCD is to control which device is the potential trusted console input device.<BR><BR>
# For example:<BR>
# USB Short Form: UsbHID(0xFFFF,0xFFFF,0x1,0x1)<BR> diff --git a/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dsc b/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dsc
index 09aa6fe4d51c..ae170f87d548 100644
--- a/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dsc
+++ b/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dsc
@@ -106,6 +106,7 @@ [LibraryClasses.common.DXE_DRIVER]
FspWrapperPlatformLib|MinPlatformPkg/FspWrapper/Library/DxeFspWrapperPlatformLib/DxeFspWrapperPlatformLib.inf
TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLib/DxeTestPointCheckLib.inf
TestPointLib|MinPlatformPkg/Test/Library/TestPointLib/DxeTestPointLib.inf
+ CompressLib|MinPlatformPkg/Library/CompressLib/CompressLib.inf
[LibraryClasses.common.DXE_SMM_DRIVER]
TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLib/SmmTestPointCheckLib.inf
--
2.28.0.windows.1
-=-=-=-=-=-=
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#92644): https://edk2.groups.io/g/devel/message/92644
Mute This Topic: https://groups.io/mt/93197638/1492418
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [isaac.w.oram@...] -=-=-=-=-=-=


Re: How to restrict HTTPS boot to a single address

Andrew Fish
 

Rafael,

I’m not sure this matches exactly what you are looking for, but the OVMF (Virtual Machine) has some configuration options around HTTPS boot [1]. That might be a good place to start. 

[1] https://github.com/tianocore/edk2/blob/master/OvmfPkg/README#L232

Thanks,

Andrew Fish

On Aug 26, 2022, at 7:15 AM, Rafael Machado <rafaelrodrigues.machado@...> wrote:

Hello everyone.

Quick question for the ones that understand better the HTTPBoot architecture at the edk2 structure.

Suppose I have to restrict HTTPS boot to accept only the download of images from a specific url.
For example, instead of allowing the download of images from any valid CA certificate address, I would like to restrict HTTPSBoot to allow only downloads from some specific domain I have.

Probably filtering some information, CN or something like that, from the url certificate.

What is the best way to do that?
In which driver/library should this logic be added?

Thanks
Rafael


[PATCH v2] OvmfPkg/IncompatiblePciDeviceSupportDxe: Ignore OptionRom in Sev guest

Lee, Chun-Yi <joeyli.kernel@...>
 

Reference: https://bugzilla.tianocore.org/show_bug.cgi?id=4031

This patch is similar to the c477b2783f patch for Td guest.

Host VMM may inject OptionRom which is untrusted in Sev guest. So PCI
OptionRom needs to be ignored if it is Sev guest. According to
"Table 20. ACPI 2.0 & 3.0 QWORD Address Space Descriptor Usage"
PI spec 1.7, type-specific flags can be set to 0 when Address
Translation Offset == 6 to skip device option ROM.

Without this patch, Sev guest may shows invalid MMIO opcode error
as following:

Invalid MMIO opcode (F6)
ASSERT /home/abuild/rpmbuild/BUILD/edk2-edk2-stable202202/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c(1041): ((BOOLEAN)(0==1))

The OptionRom must be disabled both on Td and Sev guests, so we direct
use CcProbe().

v2: Use CcProbe() instead of TdIsEnabled() and MemEncryptSevIsEnabled().

Signed-off-by: "Lee, Chun-Yi" <jlee@...>
---
.../IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c | 5 +++--
.../IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf | 1 +
2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c b/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c
index 2d385d26ef..686d85633e 100644
--- a/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c
+++ b/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c
@@ -18,6 +18,7 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
+#include <Library/CcProbeLib.h>

#include <Protocol/IncompatiblePciDeviceSupport.h>
#include <Protocol/LegacyBios.h>
@@ -264,7 +265,7 @@ CheckDevice (
//
// In Td guest OptionRom is not allowed.
//
- if (TdIsEnabled ()) {
+ if (CcProbe ()) {
Length += sizeof mOptionRomConfiguration;
}

@@ -286,7 +287,7 @@ CheckDevice (
CopyMem (Ptr, &mMmio64Configuration, sizeof mMmio64Configuration);
Length = sizeof mMmio64Configuration;

- if (TdIsEnabled ()) {
+ if (CcProbe ()) {
CopyMem (Ptr + Length, &mOptionRomConfiguration, sizeof mOptionRomConfiguration);
Length += sizeof mOptionRomConfiguration;
}
diff --git a/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf b/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
index c3e6bb9447..ad38128fcb 100644
--- a/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
+++ b/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
@@ -24,6 +24,7 @@
OvmfPkg/OvmfPkg.dec

[LibraryClasses]
+ CcProbeLib
DebugLib
MemoryAllocationLib
PcdLib
--
2.12.3


Re: [PATCH] UefiCpuPkg: Use Top of each AP's stack to save CpuMpData

Lendacky, Thomas
 

On 8/16/22 02:57, Yuanhao Xie via groups.io wrote:
To remove the dependency of CPU register, 4/8 byte at the top of the stack
is occupied for CpuMpData. BIST information is also taken care here.
This modification is only for PEI phase, since in DXE phase CpuMpData is
accessed via global variable.
Signed-off-by: Yuanhao <yuanhao.xie@...>
Cc: Eric Dong <eric.dong@...>
Cc: Ray Ni <ray.ni@...>
Cc: Rahul Kumar <rahul1.kumar@...>
---
.../Library/MpInitLib/Ia32/MpFuncs.nasm | 5 +++
UefiCpuPkg/Library/MpInitLib/MpLib.c | 41 ++++++++++++++-----
UefiCpuPkg/Library/MpInitLib/MpLib.h | 8 ++++
UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 10 +++--
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 6 +++
5 files changed, 56 insertions(+), 14 deletions(-)
@@ -1796,30 +1806,41 @@ MpInitLibInitialize (
AsmGetAddressMap (&AddressMap);
GetApResetVectorSize (&AddressMap, &ApResetVectorSizeBelow1Mb, &ApResetVectorSizeAbove1Mb);
ApStackSize = PcdGet32 (PcdCpuApStackSize);
- ApLoopMode = GetApLoopMode (&MonitorFilterSize);
+ //
+ // ApStackSize must be power of 2
+ //
+ ASSERT ((ApStackSize & (ApStackSize - 1)) == 0);
+ ApLoopMode = GetApLoopMode (&MonitorFilterSize);
//
// Save BSP's Control registers for APs.
//
SaveVolatileRegisters (&VolatileRegisters);
+ //
+ // Allocate extra ApStackSize to let AP stack align on ApStackSize bounday
+ //
BufferSize = ApStackSize * MaxLogicalProcessorNumber;
+ BufferSize += ApStackSize;
BufferSize += MonitorFilterSize * MaxLogicalProcessorNumber;
BufferSize += ApResetVectorSizeBelow1Mb;
BufferSize = ALIGN_VALUE (BufferSize, 8);
BufferSize += VolatileRegisters.Idtr.Limit + 1;
BufferSize += sizeof (CPU_MP_DATA);
BufferSize += (sizeof (CPU_AP_DATA) + sizeof (CPU_INFO_IN_HOB))* MaxLogicalProcessorNumber;
- MpBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));
+ //
+ // Allocate extra ApStackSize to let stack align on ApStackSize bounday
+ //
+ MpBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));
If you're allocating pages, is all the alignment stuff really necessary? The allocated value is going to be page aligned already, right?

Thanks,
Tom

ASSERT (MpBuffer != NULL);
ZeroMem (MpBuffer, BufferSize);
- Buffer = (UINTN)MpBuffer;
+ Buffer = ALIGN_VALUE ((UINTN)MpBuffer, ApStackSize);


How to restrict HTTPS boot to a single address

Rafael Machado
 

Hello everyone.

Quick question for the ones that understand better the HTTPBoot architecture at the edk2 structure.

Suppose I have to restrict HTTPS boot to accept only the download of images from a specific url.
For example, instead of allowing the download of images from any valid CA certificate address, I would like to restrict HTTPSBoot to allow only downloads from some specific domain I have.

Probably filtering some information, CN or something like that, from the url certificate.

What is the best way to do that?
In which driver/library should this logic be added?

Thanks
Rafael


Re: [PATCH] OvmfPkg/IncompatiblePciDeviceSupportDxe: Ignore OptionRom in Sev guest

joeyli
 

Hi Gerd,

On Fri, Aug 26, 2022 at 07:27:17AM +0200, Gerd Hoffmann wrote:
Hi,

- if (TdIsEnabled ()) {
+ if (TdIsEnabled () || MemEncryptSevIsEnabled()) {
I think you can just use CcProbeLib and CcProbe() function to cover both
tdx and sev.
Thanks for your review and suggestion! It works to me.

I will send version 2 patch.

Joey Lee


Re: 回复: [edk2-devel] Regarding review for Bug 3755

Prakash K
 

Hi Gaoliming
 

Regarding Bugzilla Bug 3755, I have sent the patch to devel@edk2.groups.io and you have updated that you have received the patch. But the changes are not merged into EDK2 source.

Kindly let us know the status of Bug 3755.

Thanks,
Prakash K


Re: 回复: [edk2-devel] Regarding review for Bug 3755

Prakash K
 

Hi Gaoliming,

Regarding Bugzilla Bug 3755, I have sent the patch to devel@edk2.groups.io and you have updated that you have received the patch. But the changes are not merged into EDK2 source.

Kindly let us know the status of Bug 3755.

Thanks,
Prakash K


[PATCH] Maintainers.txt: update Gary's email address

Gary Lin
 

Update Gary's email address from HPE to SUSE.

Cc: Ard Biesheuvel <ardb+tianocore@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Gerd Hoffmann <kraxel@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Signed-off-by: Gary Lin <glin@...>
---
Maintainers.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Maintainers.txt b/Maintainers.txt
index 23f775c0ea..d6425e698f 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -487,7 +487,7 @@ R: Abner Chang <abner.chang@...> [changab]

OvmfPkg: LsiScsi driver
F: OvmfPkg/LsiScsiDxe/
-R: Gary Lin <gary.lin@...> [lcp]
+R: Gary Lin <glin@...> [lcp]

OvmfPkg: TCG- and TPM2-related modules
F: OvmfPkg/Include/IndustryStandard/QemuTpm.h
--
2.35.3