public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg
@ 2022-03-08  2:36 Min Xu
  2022-03-08  2:36 ` [PATCH 01/14] OvmfPkg: Create initial version of PlatformInitLib Min Xu
                   ` (15 more replies)
  0 siblings, 16 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

There are 3 variants of PlatformPei in OvmfPkg:
 - OvmfPkg/PlatformPei
 - OvmfPkg/Bhyve/PlatformPei
 - OvmfPkg/XenPlatformPei

A lot of common code can be shared in above PlatformPeis. Further more,
with the upstreaming of TDVF (Pei-less boot mode), a library which
wraps the common functions is needed. PlatformInitLib is designed
to meet this requirement.

PlatformInitLib is designed to run in both PEI and SEC. So global
variables and dynamic PCDs are avoided.

As the first stage, OvmfPkg/PlatformPei will be refactored with
PlatformInitLib. In the future we will refactor other PlatformPeis
with this lib as well.

Patch 1 - 2: 
Create initial version of PlatformInitLib and move Cmos / Hob functions
to the lib.

Patch 3:
Move global variables in PlatformPei to PlatformInfoHob. Changes are
all in OvmfPkg/PlatformPei.

Patch 4 - 12:
These patches restruct the functions which set PCDs into two, one for
PlatformInitLib, one for PlatformPei.

Patch 13 - 14:
Pure move from PlatformPei to PlatformInitLib.

Code at: https://github.com/mxu9/edk2/tree/platform-init-lib-v1

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>

Min Xu (14):
  OvmfPkg: Create initial version of PlatformInitLib
  OvmfPkg/PlatformInitLib: Add hob functions
  OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob
  OvmfPkg/PlatformPei: Refactor MiscInitialization
  OvmfPkg/PlatformPei: Refactor MiscInitialization for CloudHV
  OvmfPkg/PlatformPei: Refactor AddressWidthInitialization
  OvmfPkg/PlatformPei: Refactor MaxCpuCountInitialization
  OvmfPkg/PlatformPei: Refactor QemuUc32BaseInitialization
  OvmfPkg/PlatformPei: Refactor InitializeRamRegions
  OvmfPkg/PlatformPei: Refactor MemMapInitialization
  OvmfPkg/PlatformPei: Refactor NoexecDxeInitialization
  OvmfPkg/PlatformPei: Refactor MiscInitialization
  OvmfPkg/PlatformInitLib: Create MemDetect.c
  OvmfPkg/PlatformInitLib: Move functions to Platform.c

 OvmfPkg/AmdSev/AmdSevX64.dsc                  |   1 +
 OvmfPkg/CloudHv/CloudHvX64.dsc                |   1 +
 OvmfPkg/Include/Library/PlatformInitLib.h     | 206 +++++
 .../PlatformInitLib}/Cmos.c                   |  32 +-
 OvmfPkg/Library/PlatformInitLib/MemDetect.c   | 842 +++++++++++++++++
 OvmfPkg/Library/PlatformInitLib/Platform.c    | 571 ++++++++++++
 .../PlatformInitLib/PlatformInitLib.inf       |  87 ++
 OvmfPkg/Microvm/MicrovmX64.dsc                |   1 +
 OvmfPkg/OvmfPkg.dec                           |   4 +
 OvmfPkg/OvmfPkgIa32.dsc                       |   1 +
 OvmfPkg/OvmfPkgIa32X64.dsc                    |   1 +
 OvmfPkg/OvmfPkgX64.dsc                        |   1 +
 OvmfPkg/PlatformPei/AmdSev.c                  |  10 +-
 OvmfPkg/PlatformPei/Cmos.h                    |  48 -
 OvmfPkg/PlatformPei/Fv.c                      |   6 +-
 OvmfPkg/PlatformPei/MemDetect.c               | 874 ++----------------
 OvmfPkg/PlatformPei/MemTypeInfo.c             |   4 +-
 OvmfPkg/PlatformPei/Platform.c                | 616 ++----------
 OvmfPkg/PlatformPei/Platform.h                |  80 +-
 OvmfPkg/PlatformPei/PlatformPei.inf           |   3 +-
 20 files changed, 1912 insertions(+), 1477 deletions(-)
 create mode 100644 OvmfPkg/Include/Library/PlatformInitLib.h
 rename OvmfPkg/{PlatformPei => Library/PlatformInitLib}/Cmos.c (61%)
 create mode 100644 OvmfPkg/Library/PlatformInitLib/MemDetect.c
 create mode 100644 OvmfPkg/Library/PlatformInitLib/Platform.c
 create mode 100644 OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
 delete mode 100644 OvmfPkg/PlatformPei/Cmos.h

-- 
2.29.2.windows.2


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

* [PATCH 01/14] OvmfPkg: Create initial version of PlatformInitLib
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 02/14] OvmfPkg/PlatformInitLib: Add hob functions Min Xu
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann

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

There are 3 variants of PlatformPei in OvmfPkg:
 - OvmfPkg/PlatformPei
 - OvmfPkg/XenPlatformPei
 - OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf
These PlatformPeis can share many common codes, such as
Cmos / Hob / Memory / Platform related functions. This commit
(and its following several patches) are to create a PlatformInitLib
which wraps the common code called in above PlatformPeis.

In this initial version of PlatformInitLib, below Cmos related functions
are introduced:
 - PlatformCmosRead8
 - PlatformCmosWrite8
 - PlatformDebugDumpCmos

They correspond to the functions in OvmfPkg/PlatformPei:
 - CmosRead8
 - CmosWrite8
 - DebugDumpCmos

Considering this PlatformInitLib will be used in SEC phase, global
variables and dynamic PCDs are avoided. We use PlatformInfoHob
to exchange information between functions.

EFI_HOB_PLATFORM_INFO is the data struct which contains the platform
information, such as HostBridgeDevId, BootMode, S3Supported,
SmmSmramRequire, etc.

After PlatformInitLib is created, OvmfPkg/PlatformPei is refactored
with this library.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/AmdSev/AmdSevX64.dsc                  |  1 +
 OvmfPkg/CloudHv/CloudHvX64.dsc                |  1 +
 OvmfPkg/Include/Library/PlatformInitLib.h     | 99 +++++++++++++++++++
 .../PlatformInitLib}/Cmos.c                   | 32 +++++-
 .../PlatformInitLib/PlatformInitLib.inf       | 36 +++++++
 OvmfPkg/Microvm/MicrovmX64.dsc                |  1 +
 OvmfPkg/OvmfPkg.dec                           |  4 +
 OvmfPkg/OvmfPkgIa32.dsc                       |  1 +
 OvmfPkg/OvmfPkgIa32X64.dsc                    |  1 +
 OvmfPkg/OvmfPkgX64.dsc                        |  1 +
 OvmfPkg/PlatformPei/Cmos.h                    | 48 ---------
 OvmfPkg/PlatformPei/MemDetect.c               |  8 +-
 OvmfPkg/PlatformPei/Platform.c                | 29 +-----
 OvmfPkg/PlatformPei/PlatformPei.inf           |  3 +-
 14 files changed, 183 insertions(+), 82 deletions(-)
 create mode 100644 OvmfPkg/Include/Library/PlatformInitLib.h
 rename OvmfPkg/{PlatformPei => Library/PlatformInitLib}/Cmos.c (61%)
 create mode 100644 OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
 delete mode 100644 OvmfPkg/PlatformPei/Cmos.h

diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index fd56176796d5..785049c88962 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -280,6 +280,7 @@
 !include OvmfPkg/OvmfTpmLibsPeim.dsc.inc
 
   MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+  PlatformInitLib|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
 
 [LibraryClasses.common.DXE_CORE]
   HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index b4d855d80f56..b8a82380202c 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -307,6 +307,7 @@
 !include OvmfPkg/OvmfTpmLibsPeim.dsc.inc
 
   MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+  PlatformInitLib|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
 
 [LibraryClasses.common.DXE_CORE]
   HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h
new file mode 100644
index 000000000000..2ebac5ccb013
--- /dev/null
+++ b/OvmfPkg/Include/Library/PlatformInitLib.h
@@ -0,0 +1,99 @@
+/** @file
+  PlatformInitLib header file.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_INIT_LIB_H_
+#define PLATFORM_INIT_LIB_H_
+
+#include <PiPei.h>
+
+#pragma pack(1)
+typedef struct {
+  EFI_HOB_GUID_TYPE    GuidHeader;
+  UINT16               HostBridgeDevId;
+
+  UINT64               PcdConfidentialComputingGuestAttr;
+  BOOLEAN              SevEsIsEnabled;
+
+  UINT32               BootMode;
+  BOOLEAN              S3Supported;
+
+  BOOLEAN              SmmSmramRequire;
+  BOOLEAN              Q35SmramAtDefaultSmbase;
+  UINT16               Q35TsegMbytes;
+
+  UINT64               FirstNonAddress;
+  UINT8                PhysMemAddressWidth;
+  UINT32               Uc32Base;
+  UINT32               Uc32Size;
+
+  BOOLEAN              PcdSetNxForStack;
+  UINT64               PcdTdxSharedBitMask;
+
+  UINT64               PcdPciMmio64Base;
+  UINT64               PcdPciMmio64Size;
+  UINT32               PcdPciMmio32Base;
+  UINT32               PcdPciMmio32Size;
+  UINT64               PcdPciIoBase;
+  UINT64               PcdPciIoSize;
+
+  UINT64               PcdEmuVariableNvStoreReserved;
+  UINT32               PcdCpuBootLogicalProcessorNumber;
+  UINT32               PcdCpuMaxLogicalProcessorNumber;
+  UINT32               DefaultMaxCpuNumber;
+
+  UINT32               S3AcpiReservedMemoryBase;
+  UINT32               S3AcpiReservedMemorySize;
+} EFI_HOB_PLATFORM_INFO;
+#pragma pack()
+
+/**
+  Reads 8-bits of CMOS data.
+
+  Reads the 8-bits of CMOS data at the location specified by Index.
+  The 8-bit read value is returned.
+
+  @param  Index  The CMOS location to read.
+
+  @return The value read.
+
+**/
+UINT8
+EFIAPI
+PlatformCmosRead8 (
+  IN      UINTN  Index
+  );
+
+/**
+  Writes 8-bits of CMOS data.
+
+  Writes 8-bits of CMOS data to the location specified by Index
+  with the value specified by Value and returns Value.
+
+  @param  Index  The CMOS location to write.
+  @param  Value  The value to write to CMOS.
+
+  @return The value written to CMOS.
+
+**/
+UINT8
+EFIAPI
+PlatformCmosWrite8 (
+  IN      UINTN  Index,
+  IN      UINT8  Value
+  );
+
+/**
+   Dump the CMOS content
+ */
+VOID
+EFIAPI
+PlatformDebugDumpCmos (
+  VOID
+  );
+
+#endif // PLATFORM_INIT_LIB_H_
diff --git a/OvmfPkg/PlatformPei/Cmos.c b/OvmfPkg/Library/PlatformInitLib/Cmos.c
similarity index 61%
rename from OvmfPkg/PlatformPei/Cmos.c
rename to OvmfPkg/Library/PlatformInitLib/Cmos.c
index a01b3866bee4..977aa97aea8c 100644
--- a/OvmfPkg/PlatformPei/Cmos.c
+++ b/OvmfPkg/Library/PlatformInitLib/Cmos.c
@@ -6,7 +6,8 @@
 
 **/
 
-#include "Cmos.h"
+#include <Library/PlatformInitLib.h>
+#include <Library/DebugLib.h>
 #include "Library/IoLib.h"
 
 /**
@@ -22,7 +23,7 @@
 **/
 UINT8
 EFIAPI
-CmosRead8 (
+PlatformCmosRead8 (
   IN      UINTN  Index
   )
 {
@@ -44,7 +45,7 @@ CmosRead8 (
 **/
 UINT8
 EFIAPI
-CmosWrite8 (
+PlatformCmosWrite8 (
   IN      UINTN  Index,
   IN      UINT8  Value
   )
@@ -53,3 +54,28 @@ CmosWrite8 (
   IoWrite8 (0x71, Value);
   return Value;
 }
+
+/**
+   Dump the CMOS content
+ */
+VOID
+EFIAPI
+PlatformDebugDumpCmos (
+  VOID
+  )
+{
+  UINT32  Loop;
+
+  DEBUG ((DEBUG_INFO, "CMOS:\n"));
+
+  for (Loop = 0; Loop < 0x80; Loop++) {
+    if ((Loop % 0x10) == 0) {
+      DEBUG ((DEBUG_INFO, "%02x:", Loop));
+    }
+
+    DEBUG ((DEBUG_INFO, " %02x", PlatformCmosRead8 (Loop)));
+    if ((Loop % 0x10) == 0xf) {
+      DEBUG ((DEBUG_INFO, "\n"));
+    }
+  }
+}
diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
new file mode 100644
index 000000000000..4ea2da86274f
--- /dev/null
+++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
@@ -0,0 +1,36 @@
+## @file
+#  Platform Initialization Lib
+#
+#  This module provides platform specific function to detect boot mode.
+#  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformInitLib
+  FILE_GUID                      = 89f886b0-7109-46e1-9d28-503ad4ab6ee0
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformInitLib|PEIM
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  Cmos.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 1ea43443ae97..27005eec89f2 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -300,6 +300,7 @@
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
 
   MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLib.inf
+  PlatformInitLib|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
 
 [LibraryClasses.common.DXE_CORE]
   HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 7aa94ca02863..6322d2e4de15 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -109,6 +109,10 @@
   #
   XenPlatformLib|Include/Library/XenPlatformLib.h
 
+  ##  @libraryclass  PlatformInitLib
+  #
+  PlatformInitLib|Include/Library/PlatformInitLib.h
+
 [Guids]
   gUefiOvmfPkgTokenSpaceGuid            = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}}
   gEfiXenInfoGuid                       = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 85abed24c1a7..8f02dca63869 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -300,6 +300,7 @@
   QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
   PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
+  PlatformInitLib|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
 
 !include OvmfPkg/OvmfTpmLibsPeim.dsc.inc
 
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index a9c1daecc1a8..c58ef8494470 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -304,6 +304,7 @@
   QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
   PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
+  PlatformInitLib|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
 
 !include OvmfPkg/OvmfTpmLibsPeim.dsc.inc
 
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 718399299f57..227b9845619f 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -305,6 +305,7 @@
   QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/PeiQemuFwCfgS3LibFwCfg.inf
   PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPeiLib.inf
+  PlatformInitLib|OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
 
 !include OvmfPkg/OvmfTpmLibsPeim.dsc.inc
 
diff --git a/OvmfPkg/PlatformPei/Cmos.h b/OvmfPkg/PlatformPei/Cmos.h
deleted file mode 100644
index 2b3124d7ba36..000000000000
--- a/OvmfPkg/PlatformPei/Cmos.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/** @file
-  PC/AT CMOS access routines
-
-  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __CMOS_H__
-#define __CMOS_H__
-
-/**
-  Reads 8-bits of CMOS data.
-
-  Reads the 8-bits of CMOS data at the location specified by Index.
-  The 8-bit read value is returned.
-
-  @param  Index  The CMOS location to read.
-
-  @return The value read.
-
-**/
-UINT8
-EFIAPI
-CmosRead8 (
-  IN      UINTN  Index
-  );
-
-/**
-  Writes 8-bits of CMOS data.
-
-  Writes 8-bits of CMOS data to the location specified by Index
-  with the value specified by Value and returns Value.
-
-  @param  Index  The CMOS location to write.
-  @param  Value  The value to write to CMOS.
-
-  @return The value written to CMOS.
-
-**/
-UINT8
-EFIAPI
-CmosWrite8 (
-  IN      UINTN  Index,
-  IN      UINT8  Value
-  );
-
-#endif
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index 8ecc8257f9b9..9c5bf240e3ba 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -37,9 +37,9 @@ Module Name:
 #include <Library/MtrrLib.h>
 #include <Library/QemuFwCfgLib.h>
 #include <Library/QemuFwCfgSimpleParserLib.h>
+#include <Library/PlatformInitLib.h>
 
 #include "Platform.h"
-#include "Cmos.h"
 
 UINT8  mPhysMemAddressWidth;
 
@@ -412,8 +412,8 @@ GetSystemMemorySizeBelow4gb (
   //   into the calculation to get the total memory size.
   //
 
-  Cmos0x34 = (UINT8)CmosRead8 (0x34);
-  Cmos0x35 = (UINT8)CmosRead8 (0x35);
+  Cmos0x34 = (UINT8)PlatformCmosRead8 (0x34);
+  Cmos0x35 = (UINT8)PlatformCmosRead8 (0x35);
 
   return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
 }
@@ -436,7 +436,7 @@ GetSystemMemorySizeAbove4gb (
 
   Size = 0;
   for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
-    Size = (UINT32)(Size << 8) + (UINT32)CmosRead8 (CmosIndex);
+    Size = (UINT32)(Size << 8) + (UINT32)PlatformCmosRead8 (CmosIndex);
   }
 
   return LShiftU64 (Size, 16);
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index d0323c645162..594891786440 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -36,10 +36,10 @@
 #include <IndustryStandard/Pci22.h>
 #include <IndustryStandard/Q35MchIch9.h>
 #include <IndustryStandard/QemuCpuHotplug.h>
+#include <Library/PlatformInitLib.h>
 #include <OvmfPlatforms.h>
 
 #include "Platform.h"
-#include "Cmos.h"
 
 EFI_PEI_PPI_DESCRIPTOR  mPpiBootMode[] = {
   {
@@ -505,11 +505,11 @@ BootModeInitialization (
 {
   EFI_STATUS  Status;
 
-  if (CmosRead8 (0xF) == 0xFE) {
+  if (PlatformCmosRead8 (0xF) == 0xFE) {
     mBootMode = BOOT_ON_S3_RESUME;
   }
 
-  CmosWrite8 (0xF, 0x00);
+  PlatformCmosWrite8 (0xF, 0x00);
 
   Status = PeiServicesSetBootMode (mBootMode);
   ASSERT_EFI_ERROR (Status);
@@ -546,27 +546,6 @@ ReserveEmuVariableNvStore (
   ASSERT_RETURN_ERROR (PcdStatus);
 }
 
-VOID
-DebugDumpCmos (
-  VOID
-  )
-{
-  UINT32  Loop;
-
-  DEBUG ((DEBUG_INFO, "CMOS:\n"));
-
-  for (Loop = 0; Loop < 0x80; Loop++) {
-    if ((Loop % 0x10) == 0) {
-      DEBUG ((DEBUG_INFO, "%02x:", Loop));
-    }
-
-    DEBUG ((DEBUG_INFO, " %02x", CmosRead8 (Loop)));
-    if ((Loop % 0x10) == 0xf) {
-      DEBUG ((DEBUG_INFO, "\n"));
-    }
-  }
-}
-
 VOID
 S3Verification (
   VOID
@@ -810,7 +789,7 @@ InitializePlatform (
 
   DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));
 
-  DebugDumpCmos ();
+  PlatformDebugDumpCmos ();
 
   if (QemuFwCfgS3Enabled ()) {
     DEBUG ((DEBUG_INFO, "S3 support was detected on QEMU\n"));
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 212aa7b04751..f6bfc09c2dd5 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -25,8 +25,6 @@
 [Sources]
   AmdSev.c
   ClearCache.c
-  Cmos.c
-  Cmos.h
   FeatureControl.c
   Fv.c
   MemDetect.c
@@ -64,6 +62,7 @@
   MemEncryptSevLib
   PcdLib
   VmgExitLib
+  PlatformInitLib
 
 [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
-- 
2.29.2.windows.2


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

* [PATCH 02/14] OvmfPkg/PlatformInitLib: Add hob functions
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
  2022-03-08  2:36 ` [PATCH 01/14] OvmfPkg: Create initial version of PlatformInitLib Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 03/14] OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob Min Xu
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann

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

In this patch of PlatformInitLib, below hob functions are introduced:
 - PlatformAddIoMemoryBaseSizeHob
 - PlatformAddIoMemoryRangeHob
 - PlatformAddMemoryBaseSizeHob
 - PlatformAddMemoryRangeHob
 - PlatformAddReservedMemoryBaseSizeHob

They correspond the below functions in OvmfPkg/PlatformPei:
 - AddIoMemoryBaseSizeHob
 - AddIoMemoryRangeHob
 - AddMemoryBaseSizeHob
 - AddMemoryRangeHob
 - AddReservedMemoryBaseSizeHob

After above hob functions are introduced in PlatformInitLib,
OvmfPkg/PlatformPei is refactored with this library.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Include/Library/PlatformInitLib.h     |  36 ++++++
 OvmfPkg/Library/PlatformInitLib/Platform.c    | 106 ++++++++++++++++++
 .../PlatformInitLib/PlatformInitLib.inf       |   2 +
 OvmfPkg/PlatformPei/MemDetect.c               |  20 ++--
 OvmfPkg/PlatformPei/Platform.c                | 101 ++---------------
 OvmfPkg/PlatformPei/Platform.h                |  31 -----
 6 files changed, 165 insertions(+), 131 deletions(-)
 create mode 100644 OvmfPkg/Library/PlatformInitLib/Platform.c

diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h
index 2ebac5ccb013..9b99d4c1f514 100644
--- a/OvmfPkg/Include/Library/PlatformInitLib.h
+++ b/OvmfPkg/Include/Library/PlatformInitLib.h
@@ -96,4 +96,40 @@ PlatformDebugDumpCmos (
   VOID
   );
 
+VOID
+EFIAPI
+PlatformAddIoMemoryBaseSizeHob (
+  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
+  IN UINT64                MemorySize
+  );
+
+VOID
+EFIAPI
+PlatformAddIoMemoryRangeHob (
+  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
+  IN EFI_PHYSICAL_ADDRESS  MemoryLimit
+  );
+
+VOID
+EFIAPI
+PlatformAddMemoryBaseSizeHob (
+  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
+  IN UINT64                MemorySize
+  );
+
+VOID
+EFIAPI
+PlatformAddMemoryRangeHob (
+  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
+  IN EFI_PHYSICAL_ADDRESS  MemoryLimit
+  );
+
+VOID
+EFIAPI
+PlatformAddReservedMemoryBaseSizeHob (
+  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
+  IN UINT64                MemorySize,
+  IN BOOLEAN               Cacheable
+  );
+
 #endif // PLATFORM_INIT_LIB_H_
diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c b/OvmfPkg/Library/PlatformInitLib/Platform.c
new file mode 100644
index 000000000000..e41f230ff563
--- /dev/null
+++ b/OvmfPkg/Library/PlatformInitLib/Platform.c
@@ -0,0 +1,106 @@
+/**@file
+
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PlatformInitLib.h>
+
+VOID
+EFIAPI
+PlatformAddIoMemoryBaseSizeHob (
+  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
+  IN UINT64                MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+VOID
+EFIAPI
+PlatformAddReservedMemoryBaseSizeHob (
+  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
+  IN UINT64                MemorySize,
+  IN BOOLEAN               Cacheable
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_RESERVED,
+    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+    (Cacheable ?
+     EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+     EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+     EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :
+     0
+    ) |
+    EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+VOID
+EFIAPI
+PlatformAddIoMemoryRangeHob (
+  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
+  IN EFI_PHYSICAL_ADDRESS  MemoryLimit
+  )
+{
+  PlatformAddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+VOID
+EFIAPI
+PlatformAddMemoryBaseSizeHob (
+  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
+  IN UINT64                MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_SYSTEM_MEMORY,
+    EFI_RESOURCE_ATTRIBUTE_PRESENT |
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+    EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+VOID
+EFIAPI
+PlatformAddMemoryRangeHob (
+  IN EFI_PHYSICAL_ADDRESS  MemoryBase,
+  IN EFI_PHYSICAL_ADDRESS  MemoryLimit
+  )
+{
+  PlatformAddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
index 4ea2da86274f..21813458cb59 100644
--- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
+++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
@@ -24,6 +24,7 @@
 
 [Sources]
   Cmos.c
+  Platform.c
 
 [Packages]
   MdeModulePkg/MdeModulePkg.dec
@@ -34,3 +35,4 @@
   BaseLib
   DebugLib
   IoLib
+  HobLib
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index 9c5bf240e3ba..e5e105f377dd 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -275,10 +275,10 @@ ScanOrAdd64BitE820Ram (
         End  = (E820Entry.BaseAddr + E820Entry.Length) &
                ~(UINT64)EFI_PAGE_MASK;
         if (Base < End) {
-          AddMemoryRangeHob (Base, End);
+          PlatformAddMemoryRangeHob (Base, End);
           DEBUG ((
             DEBUG_VERBOSE,
-            "%a: AddMemoryRangeHob [0x%Lx, 0x%Lx)\n",
+            "%a: PlatformAddMemoryRangeHob [0x%Lx, 0x%Lx)\n",
             __FUNCTION__,
             Base,
             End
@@ -816,8 +816,8 @@ QemuInitializeRamBelow1gb (
   )
 {
   if (FeaturePcdGet (PcdSmmSmramRequire) && mQ35SmramAtDefaultSmbase) {
-    AddMemoryRangeHob (0, SMM_DEFAULT_SMBASE);
-    AddReservedMemoryBaseSizeHob (
+    PlatformAddMemoryRangeHob (0, SMM_DEFAULT_SMBASE);
+    PlatformAddReservedMemoryBaseSizeHob (
       SMM_DEFAULT_SMBASE,
       MCH_DEFAULT_SMBASE_SIZE,
       TRUE /* Cacheable */
@@ -826,12 +826,12 @@ QemuInitializeRamBelow1gb (
       SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE < BASE_512KB + BASE_128KB,
       "end of SMRAM at default SMBASE ends at, or exceeds, 640KB"
       );
-    AddMemoryRangeHob (
+    PlatformAddMemoryRangeHob (
       SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE,
       BASE_512KB + BASE_128KB
       );
   } else {
-    AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
+    PlatformAddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
   }
 }
 
@@ -889,14 +889,14 @@ QemuInitializeRam (
       UINT32  TsegSize;
 
       TsegSize = mQ35TsegMbytes * SIZE_1MB;
-      AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);
-      AddReservedMemoryBaseSizeHob (
+      PlatformAddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);
+      PlatformAddReservedMemoryBaseSizeHob (
         LowerMemorySize - TsegSize,
         TsegSize,
         TRUE
         );
     } else {
-      AddMemoryRangeHob (BASE_1MB, LowerMemorySize);
+      PlatformAddMemoryRangeHob (BASE_1MB, LowerMemorySize);
     }
 
     //
@@ -908,7 +908,7 @@ QemuInitializeRam (
     if (EFI_ERROR (Status)) {
       UpperMemorySize = GetSystemMemorySizeAbove4gb ();
       if (UpperMemorySize != 0) {
-        AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
+        PlatformAddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
       }
     }
   }
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 594891786440..62480c3c40e5 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -57,85 +57,6 @@ BOOLEAN  mS3Supported = FALSE;
 
 UINT32  mMaxCpuCount;
 
-VOID
-AddIoMemoryBaseSizeHob (
-  EFI_PHYSICAL_ADDRESS  MemoryBase,
-  UINT64                MemorySize
-  )
-{
-  BuildResourceDescriptorHob (
-    EFI_RESOURCE_MEMORY_MAPPED_IO,
-    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
-    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
-    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
-    EFI_RESOURCE_ATTRIBUTE_TESTED,
-    MemoryBase,
-    MemorySize
-    );
-}
-
-VOID
-AddReservedMemoryBaseSizeHob (
-  EFI_PHYSICAL_ADDRESS  MemoryBase,
-  UINT64                MemorySize,
-  BOOLEAN               Cacheable
-  )
-{
-  BuildResourceDescriptorHob (
-    EFI_RESOURCE_MEMORY_RESERVED,
-    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
-    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
-    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
-    (Cacheable ?
-     EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
-     EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
-     EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :
-     0
-    ) |
-    EFI_RESOURCE_ATTRIBUTE_TESTED,
-    MemoryBase,
-    MemorySize
-    );
-}
-
-VOID
-AddIoMemoryRangeHob (
-  EFI_PHYSICAL_ADDRESS  MemoryBase,
-  EFI_PHYSICAL_ADDRESS  MemoryLimit
-  )
-{
-  AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
-}
-
-VOID
-AddMemoryBaseSizeHob (
-  EFI_PHYSICAL_ADDRESS  MemoryBase,
-  UINT64                MemorySize
-  )
-{
-  BuildResourceDescriptorHob (
-    EFI_RESOURCE_SYSTEM_MEMORY,
-    EFI_RESOURCE_ATTRIBUTE_PRESENT |
-    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
-    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
-    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
-    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
-    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
-    EFI_RESOURCE_ATTRIBUTE_TESTED,
-    MemoryBase,
-    MemorySize
-    );
-}
-
-VOID
-AddMemoryRangeHob (
-  EFI_PHYSICAL_ADDRESS  MemoryBase,
-  EFI_PHYSICAL_ADDRESS  MemoryLimit
-  )
-{
-  AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
-}
-
 VOID
 MemMapInitialization (
   VOID
@@ -155,12 +76,12 @@ MemMapInitialization (
   //
   // Video memory + Legacy BIOS region
   //
-  AddIoMemoryRangeHob (0x0A0000, BASE_1MB);
+  PlatformAddIoMemoryRangeHob (0x0A0000, BASE_1MB);
 
   if (mHostBridgeDevId == 0xffff /* microvm */) {
-    AddIoMemoryBaseSizeHob (MICROVM_GED_MMIO_BASE, SIZE_4KB);
-    AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); /* ioapic #1 */
-    AddIoMemoryBaseSizeHob (0xFEC10000, SIZE_4KB); /* ioapic #2 */
+    PlatformAddIoMemoryBaseSizeHob (MICROVM_GED_MMIO_BASE, SIZE_4KB);
+    PlatformAddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); /* ioapic #1 */
+    PlatformAddIoMemoryBaseSizeHob (0xFEC10000, SIZE_4KB); /* ioapic #2 */
     return;
   }
 
@@ -194,20 +115,20 @@ MemMapInitialization (
   // 0xFEE00000    LAPIC                          1 MB
   //
   PciSize = 0xFC000000 - PciBase;
-  AddIoMemoryBaseSizeHob (PciBase, PciSize);
+  PlatformAddIoMemoryBaseSizeHob (PciBase, PciSize);
   PcdStatus = PcdSet64S (PcdPciMmio32Base, PciBase);
   ASSERT_RETURN_ERROR (PcdStatus);
   PcdStatus = PcdSet64S (PcdPciMmio32Size, PciSize);
   ASSERT_RETURN_ERROR (PcdStatus);
 
-  AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
-  AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
+  PlatformAddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
+  PlatformAddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
   if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
-    AddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);
+    PlatformAddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);
     //
     // Note: there should be an
     //
-    //   AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);
+    //   PlatformAddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);
     //
     // call below, just like the one above for RCBA. However, Linux insists
     // that the MMCONFIG area be marked in the E820 or UEFI memory map as
@@ -225,7 +146,7 @@ MemMapInitialization (
     // is most definitely not RAM; so, as an exception, cover it with
     // uncacheable reserved memory right here.
     //
-    AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);
+    PlatformAddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);
     BuildMemoryAllocationHob (
       PciExBarBase,
       SIZE_256MB,
@@ -233,7 +154,7 @@ MemMapInitialization (
       );
   }
 
-  AddIoMemoryBaseSizeHob (PcdGet32 (PcdCpuLocalApicBaseAddress), SIZE_1MB);
+  PlatformAddIoMemoryBaseSizeHob (PcdGet32 (PcdCpuLocalApicBaseAddress), SIZE_1MB);
 
   //
   // On Q35, the IO Port space is available for PCI resource allocations from
diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h
index 24e4da4e1d93..f193ff736549 100644
--- a/OvmfPkg/PlatformPei/Platform.h
+++ b/OvmfPkg/PlatformPei/Platform.h
@@ -11,37 +11,6 @@
 
 #include <IndustryStandard/E820.h>
 
-VOID
-AddIoMemoryBaseSizeHob (
-  EFI_PHYSICAL_ADDRESS  MemoryBase,
-  UINT64                MemorySize
-  );
-
-VOID
-AddIoMemoryRangeHob (
-  EFI_PHYSICAL_ADDRESS  MemoryBase,
-  EFI_PHYSICAL_ADDRESS  MemoryLimit
-  );
-
-VOID
-AddMemoryBaseSizeHob (
-  EFI_PHYSICAL_ADDRESS  MemoryBase,
-  UINT64                MemorySize
-  );
-
-VOID
-AddMemoryRangeHob (
-  EFI_PHYSICAL_ADDRESS  MemoryBase,
-  EFI_PHYSICAL_ADDRESS  MemoryLimit
-  );
-
-VOID
-AddReservedMemoryBaseSizeHob (
-  EFI_PHYSICAL_ADDRESS  MemoryBase,
-  UINT64                MemorySize,
-  BOOLEAN               Cacheable
-  );
-
 VOID
 AddressWidthInitialization (
   VOID
-- 
2.29.2.windows.2


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

* [PATCH 03/14] OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
  2022-03-08  2:36 ` [PATCH 01/14] OvmfPkg: Create initial version of PlatformInitLib Min Xu
  2022-03-08  2:36 ` [PATCH 02/14] OvmfPkg/PlatformInitLib: Add hob functions Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 04/14] OvmfPkg/PlatformPei: Refactor MiscInitialization Min Xu
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

The intention of PlatformInitLib is to extract the common function used
in OvmfPkg/PlatformPei. This lib will be used not only in PEI phase but
also in SEC phase. SEC phase cannot use global variables between
different functions. So PlatformInfoHob is created to hold the
informations shared between functions. For example, HostBridgeDevId
corespond to mHostBridgeDevId in PlatformPei.

In this patch we will first move below global variables to
PlatformInfoHob.
 - mBootMode
 - mS3Supported
 - mPhysMemAddressWidth
 - mMaxCpuCount
 - mHostBridgeDevId
 - mQ35SmramAtDefaultSmbase
 - mQemuUc32Base
 - mS3AcpiReservedMemorySize
 - mS3AcpiReservedMemoryBase

PlatformInfoHob also holds other information, for example,
PciIoBase / PciIoSize. This is because in SEC phase, PcdSetxxx
doesn't work. So we will restruct the functions which set PCDs
into two, one for PlatformInfoLib, one for PlatformPei.

So in this patch we first move global variables and PCDs to
PlatformInfoHob. All the changes are in OvmfPkg/PlatformPei.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/PlatformPei/AmdSev.c      |  10 +-
 OvmfPkg/PlatformPei/Fv.c          |   6 +-
 OvmfPkg/PlatformPei/MemDetect.c   | 210 +++++++++++++++---------------
 OvmfPkg/PlatformPei/MemTypeInfo.c |   4 +-
 OvmfPkg/PlatformPei/Platform.c    | 109 ++++++++--------
 OvmfPkg/PlatformPei/Platform.h    |  43 +++---
 6 files changed, 201 insertions(+), 181 deletions(-)

diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index fb7e21ec140f..c180383b42b0 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -24,6 +24,8 @@
 
 #include "Platform.h"
 
+extern EFI_HOB_PLATFORM_INFO  mPlatformInfoHob;
+
 STATIC
 UINT64
 GetHypervisorFeature (
@@ -228,7 +230,7 @@ AmdSevEsInitialize (
   //   Since the pages must survive across the UEFI to OS transition
   //   make them reserved.
   //
-  GhcbPageCount = mMaxCpuCount * 2;
+  GhcbPageCount = mPlatformInfoHob.PcdCpuMaxLogicalProcessorNumber * 2;
   GhcbBase      = AllocateReservedPages (GhcbPageCount);
   ASSERT (GhcbBase != NULL);
 
@@ -266,7 +268,7 @@ AmdSevEsInitialize (
   // Allocate #VC recursion backup pages. The number of backup pages needed is
   // one less than the maximum VC count.
   //
-  GhcbBackupPageCount = mMaxCpuCount * (VMGEXIT_MAXIMUM_VC_COUNT - 1);
+  GhcbBackupPageCount = mPlatformInfoHob.PcdCpuMaxLogicalProcessorNumber * (VMGEXIT_MAXIMUM_VC_COUNT - 1);
   GhcbBackupBase      = AllocatePages (GhcbBackupPageCount);
   ASSERT (GhcbBackupBase != NULL);
 
@@ -367,7 +369,7 @@ AmdSevInitialize (
   // until after re-encryption, in order to prevent an information leak to the
   // hypervisor.
   //
-  if (FeaturePcdGet (PcdSmmSmramRequire) && (mBootMode != BOOT_ON_S3_RESUME)) {
+  if (mPlatformInfoHob.SmmSmramRequire && (mPlatformInfoHob.BootMode != BOOT_ON_S3_RESUME)) {
     RETURN_STATUS  LocateMapStatus;
     UINTN          MapPagesBase;
     UINTN          MapPagesCount;
@@ -378,7 +380,7 @@ AmdSevInitialize (
                         );
     ASSERT_RETURN_ERROR (LocateMapStatus);
 
-    if (mQ35SmramAtDefaultSmbase) {
+    if (mPlatformInfoHob.Q35SmramAtDefaultSmbase) {
       //
       // The initial SMRAM Save State Map has been covered as part of a larger
       // reserved memory allocation in InitializeRamRegions().
diff --git a/OvmfPkg/PlatformPei/Fv.c b/OvmfPkg/PlatformPei/Fv.c
index 8cd8cacc5913..b9bf1a1d8b01 100644
--- a/OvmfPkg/PlatformPei/Fv.c
+++ b/OvmfPkg/PlatformPei/Fv.c
@@ -13,6 +13,8 @@
 #include <Library/PeiServicesLib.h>
 #include <Library/PcdLib.h>
 
+extern EFI_HOB_PLATFORM_INFO  mPlatformInfoHob;
+
 /**
   Publish PEI & DXE (Decompressed) Memory based FVs to let PEI
   and DXE know about them.
@@ -37,7 +39,7 @@ PeiFvInitialization (
   BuildMemoryAllocationHob (
     PcdGet32 (PcdOvmfPeiMemFvBase),
     PcdGet32 (PcdOvmfPeiMemFvSize),
-    mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+    mPlatformInfoHob.S3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
     );
 
   //
@@ -45,7 +47,7 @@ PeiFvInitialization (
   //
   BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize));
 
-  SecureS3Needed = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire);
+  SecureS3Needed = mPlatformInfoHob.S3Supported && mPlatformInfoHob.SmmSmramRequire;
 
   //
   // Create a memory allocation HOB for the DXE FV.
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index e5e105f377dd..981a9ff28685 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -37,20 +37,10 @@ Module Name:
 #include <Library/MtrrLib.h>
 #include <Library/QemuFwCfgLib.h>
 #include <Library/QemuFwCfgSimpleParserLib.h>
-#include <Library/PlatformInitLib.h>
 
 #include "Platform.h"
 
-UINT8  mPhysMemAddressWidth;
-
-STATIC UINT32  mS3AcpiReservedMemoryBase;
-STATIC UINT32  mS3AcpiReservedMemorySize;
-
-STATIC UINT16  mQ35TsegMbytes;
-
-BOOLEAN  mQ35SmramAtDefaultSmbase;
-
-UINT32  mQemuUc32Base;
+extern EFI_HOB_PLATFORM_INFO  mPlatformInfoHob;
 
 VOID
 Q35TsegMbytesInitialization (
@@ -60,7 +50,7 @@ Q35TsegMbytesInitialization (
   UINT16         ExtendedTsegMbytes;
   RETURN_STATUS  PcdStatus;
 
-  ASSERT (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID);
+  ASSERT (mPlatformInfoHob.HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID);
 
   //
   // Check if QEMU offers an extended TSEG.
@@ -81,7 +71,7 @@ Q35TsegMbytesInitialization (
   PciWrite16 (DRAMC_REGISTER_Q35 (MCH_EXT_TSEG_MB), MCH_EXT_TSEG_MB_QUERY);
   ExtendedTsegMbytes = PciRead16 (DRAMC_REGISTER_Q35 (MCH_EXT_TSEG_MB));
   if (ExtendedTsegMbytes == MCH_EXT_TSEG_MB_QUERY) {
-    mQ35TsegMbytes = PcdGet16 (PcdQ35TsegMbytes);
+    mPlatformInfoHob.Q35TsegMbytes = PcdGet16 (PcdQ35TsegMbytes);
     return;
   }
 
@@ -93,7 +83,7 @@ Q35TsegMbytesInitialization (
     ));
   PcdStatus = PcdSet16S (PcdQ35TsegMbytes, ExtendedTsegMbytes);
   ASSERT_RETURN_ERROR (PcdStatus);
-  mQ35TsegMbytes = ExtendedTsegMbytes;
+  mPlatformInfoHob.Q35TsegMbytes = ExtendedTsegMbytes;
 }
 
 VOID
@@ -103,9 +93,9 @@ Q35SmramAtDefaultSmbaseInitialization (
 {
   RETURN_STATUS  PcdStatus;
 
-  ASSERT (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID);
+  ASSERT (mPlatformInfoHob.HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID);
 
-  mQ35SmramAtDefaultSmbase = FALSE;
+  mPlatformInfoHob.Q35SmramAtDefaultSmbase = FALSE;
   if (FeaturePcdGet (PcdCsmEnable)) {
     DEBUG ((
       DEBUG_INFO,
@@ -118,37 +108,36 @@ Q35SmramAtDefaultSmbaseInitialization (
 
     CtlReg = DRAMC_REGISTER_Q35 (MCH_DEFAULT_SMBASE_CTL);
     PciWrite8 (CtlReg, MCH_DEFAULT_SMBASE_QUERY);
-    CtlRegVal                = PciRead8 (CtlReg);
-    mQ35SmramAtDefaultSmbase = (BOOLEAN)(CtlRegVal ==
-                                         MCH_DEFAULT_SMBASE_IN_RAM);
+    CtlRegVal                                = PciRead8 (CtlReg);
+    mPlatformInfoHob.Q35SmramAtDefaultSmbase = (BOOLEAN)(CtlRegVal ==
+                                                         MCH_DEFAULT_SMBASE_IN_RAM);
     DEBUG ((
       DEBUG_INFO,
       "%a: SMRAM at default SMBASE %a\n",
       __FUNCTION__,
-      mQ35SmramAtDefaultSmbase ? "found" : "not found"
+      mPlatformInfoHob.Q35SmramAtDefaultSmbase ? "found" : "not found"
       ));
   }
 
   PcdStatus = PcdSetBoolS (
                 PcdQ35SmramAtDefaultSmbase,
-                mQ35SmramAtDefaultSmbase
+                mPlatformInfoHob.Q35SmramAtDefaultSmbase
                 );
   ASSERT_RETURN_ERROR (PcdStatus);
 }
 
 VOID
 QemuUc32BaseInitialization (
-  VOID
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
   UINT32  LowerMemorySize;
-  UINT32  Uc32Size;
 
-  if (mHostBridgeDevId == 0xffff /* microvm */) {
+  if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {
     return;
   }
 
-  if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
     //
     // On q35, the 32-bit area that we'll mark as UC, through variable MTRRs,
     // starts at PcdPciExpressBaseAddress. The platform DSC is responsible for
@@ -157,40 +146,40 @@ QemuUc32BaseInitialization (
     // variable MTRRs (preferably 1 or 2).
     //
     ASSERT (FixedPcdGet64 (PcdPciExpressBaseAddress) <= MAX_UINT32);
-    mQemuUc32Base = (UINT32)FixedPcdGet64 (PcdPciExpressBaseAddress);
+    PlatformInfoHob->Uc32Base = (UINT32)FixedPcdGet64 (PcdPciExpressBaseAddress);
     return;
   }
 
-  if (mHostBridgeDevId == CLOUDHV_DEVICE_ID) {
-    Uc32Size      = CLOUDHV_MMIO_HOLE_SIZE;
-    mQemuUc32Base = CLOUDHV_MMIO_HOLE_ADDRESS;
+  if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
+    PlatformInfoHob->Uc32Size = CLOUDHV_MMIO_HOLE_SIZE;
+    PlatformInfoHob->Uc32Base = CLOUDHV_MMIO_HOLE_ADDRESS;
     return;
   }
 
-  ASSERT (mHostBridgeDevId == INTEL_82441_DEVICE_ID);
+  ASSERT (PlatformInfoHob->HostBridgeDevId == INTEL_82441_DEVICE_ID);
   //
   // On i440fx, start with the [LowerMemorySize, 4GB) range. Make sure one
   // variable MTRR suffices by truncating the size to a whole power of two,
   // while keeping the end affixed to 4GB. This will round the base up.
   //
-  LowerMemorySize = GetSystemMemorySizeBelow4gb ();
-  Uc32Size        = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - LowerMemorySize));
-  mQemuUc32Base   = (UINT32)(SIZE_4GB - Uc32Size);
+  LowerMemorySize           = GetSystemMemorySizeBelow4gb (PlatformInfoHob);
+  PlatformInfoHob->Uc32Size = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - LowerMemorySize));
+  PlatformInfoHob->Uc32Base = (UINT32)(SIZE_4GB - PlatformInfoHob->Uc32Size);
   //
   // Assuming that LowerMemorySize is at least 1 byte, Uc32Size is at most 2GB.
   // Therefore mQemuUc32Base is at least 2GB.
   //
-  ASSERT (mQemuUc32Base >= BASE_2GB);
+  ASSERT (PlatformInfoHob->Uc32Base >= BASE_2GB);
 
-  if (mQemuUc32Base != LowerMemorySize) {
+  if (PlatformInfoHob->Uc32Base != LowerMemorySize) {
     DEBUG ((
       DEBUG_VERBOSE,
       "%a: rounded UC32 base from 0x%x up to 0x%x, for "
       "an UC32 size of 0x%x\n",
       __FUNCTION__,
       LowerMemorySize,
-      mQemuUc32Base,
-      Uc32Size
+      PlatformInfoHob->Uc32Base,
+      PlatformInfoHob->Uc32Size
       ));
   }
 }
@@ -385,7 +374,7 @@ GetHighestSystemMemoryAddressFromPvhMemmap (
 
 UINT32
 GetSystemMemorySizeBelow4gb (
-  VOID
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
   EFI_STATUS  Status;
@@ -393,7 +382,7 @@ GetSystemMemorySizeBelow4gb (
   UINT8       Cmos0x34;
   UINT8       Cmos0x35;
 
-  if (mHostBridgeDevId == CLOUDHV_DEVICE_ID) {
+  if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
     // Get the information from PVH memmap
     return (UINT32)GetHighestSystemMemoryAddressFromPvhMemmap (TRUE);
   }
@@ -448,11 +437,10 @@ GetSystemMemorySizeAbove4gb (
 STATIC
 UINT64
 GetFirstNonAddress (
-  VOID
+  IN OUT  EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
   UINT64                FirstNonAddress;
-  UINT64                Pci64Base, Pci64Size;
   UINT32                FwCfgPciMmio64Mb;
   EFI_STATUS            Status;
   FIRMWARE_CONFIG_ITEM  FwCfgItem;
@@ -493,7 +481,7 @@ GetFirstNonAddress (
   // Otherwise, in order to calculate the highest address plus one, we must
   // consider the 64-bit PCI host aperture too. Fetch the default size.
   //
-  Pci64Size = PcdGet64 (PcdPciMmio64Size);
+  PlatformInfoHob->PcdPciMmio64Size = PcdGet64 (PcdPciMmio64Size);
 
   //
   // See if the user specified the number of megabytes for the 64-bit PCI host
@@ -513,7 +501,7 @@ GetFirstNonAddress (
       break;
     case EFI_SUCCESS:
       if (FwCfgPciMmio64Mb <= 0x1000000) {
-        Pci64Size = LShiftU64 (FwCfgPciMmio64Mb, 20);
+        PlatformInfoHob->PcdPciMmio64Size = LShiftU64 (FwCfgPciMmio64Mb, 20);
         break;
       }
 
@@ -529,8 +517,8 @@ GetFirstNonAddress (
       break;
   }
 
-  if (Pci64Size == 0) {
-    if (mBootMode != BOOT_ON_S3_RESUME) {
+  if (PlatformInfoHob->PcdPciMmio64Size == 0) {
+    if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
       DEBUG ((
         DEBUG_INFO,
         "%a: disabling 64-bit PCI host aperture\n",
@@ -577,8 +565,8 @@ GetFirstNonAddress (
   // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so
   // that the host can map it with 1GB hugepages. Follow suit.
   //
-  Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
-  Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);
+  PlatformInfoHob->PcdPciMmio64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
+  PlatformInfoHob->PcdPciMmio64Size = ALIGN_VALUE (PlatformInfoHob->PcdPciMmio64Size, (UINT64)SIZE_1GB);
 
   //
   // The 64-bit PCI host aperture should also be "naturally" aligned. The
@@ -586,32 +574,32 @@ GetFirstNonAddress (
   // next smaller or equal power of two. That is, align the aperture by the
   // largest BAR size that can fit into it.
   //
-  Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));
+  PlatformInfoHob->PcdPciMmio64Base = ALIGN_VALUE (PlatformInfoHob->PcdPciMmio64Base, GetPowerOfTwo64 (PlatformInfoHob->PcdPciMmio64Size));
 
-  if (mBootMode != BOOT_ON_S3_RESUME) {
+  if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
     //
     // The core PciHostBridgeDxe driver will automatically add this range to
     // the GCD memory space map through our PciHostBridgeLib instance; here we
     // only need to set the PCDs.
     //
-    PcdStatus = PcdSet64S (PcdPciMmio64Base, Pci64Base);
+    PcdStatus = PcdSet64S (PcdPciMmio64Base, PlatformInfoHob->PcdPciMmio64Base);
     ASSERT_RETURN_ERROR (PcdStatus);
-    PcdStatus = PcdSet64S (PcdPciMmio64Size, Pci64Size);
+    PcdStatus = PcdSet64S (PcdPciMmio64Size, PlatformInfoHob->PcdPciMmio64Size);
     ASSERT_RETURN_ERROR (PcdStatus);
 
     DEBUG ((
       DEBUG_INFO,
       "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",
       __FUNCTION__,
-      Pci64Base,
-      Pci64Size
+      PlatformInfoHob->PcdPciMmio64Base,
+      PlatformInfoHob->PcdPciMmio64Size
       ));
   }
 
   //
   // The useful address space ends with the 64-bit PCI host aperture.
   //
-  FirstNonAddress = Pci64Base + Pci64Size;
+  FirstNonAddress = PlatformInfoHob->PcdPciMmio64Base + PlatformInfoHob->PcdPciMmio64Size;
   return FirstNonAddress;
 }
 
@@ -620,10 +608,11 @@ GetFirstNonAddress (
 **/
 VOID
 AddressWidthInitialization (
-  VOID
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
   UINT64  FirstNonAddress;
+  UINT8   PhysMemAddressWidth;
 
   //
   // As guest-physical memory size grows, the permanent PEI RAM requirements
@@ -631,15 +620,15 @@ AddressWidthInitialization (
   // The DXL IPL keys off of the physical address bits advertized in the CPU
   // HOB. To conserve memory, we calculate the minimum address width here.
   //
-  FirstNonAddress      = GetFirstNonAddress ();
-  mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
+  FirstNonAddress     = GetFirstNonAddress (PlatformInfoHob);
+  PhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
 
   //
   // If FirstNonAddress is not an integral power of two, then we need an
   // additional bit.
   //
   if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
-    ++mPhysMemAddressWidth;
+    ++PhysMemAddressWidth;
   }
 
   //
@@ -648,11 +637,14 @@ AddressWidthInitialization (
   // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We
   // can simply assert that here, since 48 bits are good enough for 256 TB.
   //
-  if (mPhysMemAddressWidth <= 36) {
-    mPhysMemAddressWidth = 36;
+  if (PhysMemAddressWidth <= 36) {
+    PhysMemAddressWidth = 36;
   }
 
-  ASSERT (mPhysMemAddressWidth <= 48);
+  ASSERT (PhysMemAddressWidth <= 48);
+
+  PlatformInfoHob->FirstNonAddress     = FirstNonAddress;
+  PlatformInfoHob->PhysMemAddressWidth = PhysMemAddressWidth;
 }
 
 /**
@@ -698,12 +690,12 @@ GetPeiMemoryCap (
     }
   }
 
-  if (mPhysMemAddressWidth <= 39) {
+  if (mPlatformInfoHob.PhysMemAddressWidth <= 39) {
     Pml4Entries = 1;
-    PdpEntries  = 1 << (mPhysMemAddressWidth - 30);
+    PdpEntries  = 1 << (mPlatformInfoHob.PhysMemAddressWidth - 30);
     ASSERT (PdpEntries <= 0x200);
   } else {
-    Pml4Entries = 1 << (mPhysMemAddressWidth - 39);
+    Pml4Entries = 1 << (mPlatformInfoHob.PhysMemAddressWidth - 39);
     ASSERT (Pml4Entries <= 0x200);
     PdpEntries = 512;
   }
@@ -736,38 +728,46 @@ PublishPeiMemory (
   UINT64                MemorySize;
   UINT32                LowerMemorySize;
   UINT32                PeiMemoryCap;
+  UINT32                S3AcpiReservedMemoryBase;
+  UINT32                S3AcpiReservedMemorySize;
 
-  LowerMemorySize = GetSystemMemorySizeBelow4gb ();
-  if (FeaturePcdGet (PcdSmmSmramRequire)) {
+  LowerMemorySize = GetSystemMemorySizeBelow4gb (&mPlatformInfoHob);
+  if (mPlatformInfoHob.SmmSmramRequire) {
     //
     // TSEG is chipped from the end of low RAM
     //
-    LowerMemorySize -= mQ35TsegMbytes * SIZE_1MB;
+    LowerMemorySize -= mPlatformInfoHob.Q35TsegMbytes * SIZE_1MB;
   }
 
+  S3AcpiReservedMemoryBase = 0;
+  S3AcpiReservedMemorySize = 0;
+
   //
   // If S3 is supported, then the S3 permanent PEI memory is placed next,
   // downwards. Its size is primarily dictated by CpuMpPei. The formula below
   // is an approximation.
   //
-  if (mS3Supported) {
-    mS3AcpiReservedMemorySize = SIZE_512KB +
-                                mMaxCpuCount *
-                                PcdGet32 (PcdCpuApStackSize);
-    mS3AcpiReservedMemoryBase = LowerMemorySize - mS3AcpiReservedMemorySize;
-    LowerMemorySize           = mS3AcpiReservedMemoryBase;
+  if (mPlatformInfoHob.S3Supported) {
+    S3AcpiReservedMemorySize = SIZE_512KB +
+                               mPlatformInfoHob.PcdCpuMaxLogicalProcessorNumber *
+                               PcdGet32 (PcdCpuApStackSize);
+    S3AcpiReservedMemoryBase = LowerMemorySize - S3AcpiReservedMemorySize;
+    LowerMemorySize          = S3AcpiReservedMemoryBase;
   }
 
-  if (mBootMode == BOOT_ON_S3_RESUME) {
-    MemoryBase = mS3AcpiReservedMemoryBase;
-    MemorySize = mS3AcpiReservedMemorySize;
+  mPlatformInfoHob.S3AcpiReservedMemoryBase = S3AcpiReservedMemoryBase;
+  mPlatformInfoHob.S3AcpiReservedMemorySize = S3AcpiReservedMemorySize;
+
+  if (mPlatformInfoHob.BootMode == BOOT_ON_S3_RESUME) {
+    MemoryBase = S3AcpiReservedMemoryBase;
+    MemorySize = S3AcpiReservedMemorySize;
   } else {
     PeiMemoryCap = GetPeiMemoryCap ();
     DEBUG ((
       DEBUG_INFO,
       "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",
       __FUNCTION__,
-      mPhysMemAddressWidth,
+      mPlatformInfoHob.PhysMemAddressWidth,
       PeiMemoryCap >> 10
       ));
 
@@ -781,7 +781,7 @@ PublishPeiMemory (
     // allocation HOB, and other allocations served from the permanent PEI RAM
     // shouldn't overlap with that HOB.
     //
-    MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ?
+    MemoryBase = mPlatformInfoHob.S3Supported && mPlatformInfoHob.SmmSmramRequire ?
                  PcdGet32 (PcdOvmfDecompressionScratchEnd) :
                  PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize);
     MemorySize = LowerMemorySize - MemoryBase;
@@ -796,7 +796,7 @@ PublishPeiMemory (
   // normal boot permanent PEI RAM. Regarding the S3 boot path, the S3
   // permanent PEI RAM is located even higher.
   //
-  if (FeaturePcdGet (PcdSmmSmramRequire) && mQ35SmramAtDefaultSmbase) {
+  if (mPlatformInfoHob.SmmSmramRequire && mPlatformInfoHob.Q35SmramAtDefaultSmbase) {
     ASSERT (SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE <= MemoryBase);
   }
 
@@ -812,10 +812,10 @@ PublishPeiMemory (
 STATIC
 VOID
 QemuInitializeRamBelow1gb (
-  VOID
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
-  if (FeaturePcdGet (PcdSmmSmramRequire) && mQ35SmramAtDefaultSmbase) {
+  if (PlatformInfoHob->SmmSmramRequire && PlatformInfoHob->Q35SmramAtDefaultSmbase) {
     PlatformAddMemoryRangeHob (0, SMM_DEFAULT_SMBASE);
     PlatformAddReservedMemoryBaseSizeHob (
       SMM_DEFAULT_SMBASE,
@@ -842,7 +842,7 @@ QemuInitializeRamBelow1gb (
 STATIC
 VOID
 QemuInitializeRam (
-  VOID
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
   UINT64         LowerMemorySize;
@@ -855,9 +855,9 @@ QemuInitializeRam (
   //
   // Determine total memory size available
   //
-  LowerMemorySize = GetSystemMemorySizeBelow4gb ();
+  LowerMemorySize = GetSystemMemorySizeBelow4gb (PlatformInfoHob);
 
-  if (mBootMode == BOOT_ON_S3_RESUME) {
+  if (PlatformInfoHob->BootMode == BOOT_ON_S3_RESUME) {
     //
     // Create the following memory HOB as an exception on the S3 boot path.
     //
@@ -878,17 +878,17 @@ QemuInitializeRam (
     // allocation HOBs, and to honor preexistent memory allocation HOBs when
     // looking for an area to borrow.
     //
-    QemuInitializeRamBelow1gb ();
+    QemuInitializeRamBelow1gb (PlatformInfoHob);
   } else {
     //
     // Create memory HOBs
     //
-    QemuInitializeRamBelow1gb ();
+    QemuInitializeRamBelow1gb (PlatformInfoHob);
 
-    if (FeaturePcdGet (PcdSmmSmramRequire)) {
+    if (PlatformInfoHob->SmmSmramRequire) {
       UINT32  TsegSize;
 
-      TsegSize = mQ35TsegMbytes * SIZE_1MB;
+      TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB;
       PlatformAddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);
       PlatformAddReservedMemoryBaseSizeHob (
         LowerMemorySize - TsegSize,
@@ -924,7 +924,7 @@ QemuInitializeRam (
   // practically any alignment, and we may not have enough variable MTRRs to
   // cover it exactly.
   //
-  if (IsMtrrSupported () && (mHostBridgeDevId != CLOUDHV_DEVICE_ID)) {
+  if (IsMtrrSupported () && (PlatformInfoHob->HostBridgeDevId != CLOUDHV_DEVICE_ID)) {
     MtrrGetAllMtrrs (&MtrrSettings);
 
     //
@@ -957,8 +957,8 @@ QemuInitializeRam (
     // MMIO aperture on i440fx, PCIEXBAR on q35) to 4GB as uncacheable.
     //
     Status = MtrrSetMemoryAttribute (
-               mQemuUc32Base,
-               SIZE_4GB - mQemuUc32Base,
+               PlatformInfoHob->Uc32Base,
+               SIZE_4GB - PlatformInfoHob->Uc32Base,
                CacheUncacheable
                );
     ASSERT_EFI_ERROR (Status);
@@ -971,20 +971,20 @@ QemuInitializeRam (
 **/
 VOID
 InitializeRamRegions (
-  VOID
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
-  QemuInitializeRam ();
+  QemuInitializeRam (PlatformInfoHob);
 
   SevInitializeRam ();
 
-  if (mS3Supported && (mBootMode != BOOT_ON_S3_RESUME)) {
+  if (PlatformInfoHob->S3Supported && (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME)) {
     //
     // This is the memory range that will be used for PEI on S3 resume
     //
     BuildMemoryAllocationHob (
-      mS3AcpiReservedMemoryBase,
-      mS3AcpiReservedMemorySize,
+      PlatformInfoHob->S3AcpiReservedMemoryBase,
+      PlatformInfoHob->S3AcpiReservedMemorySize,
       EfiACPIMemoryNVS
       );
 
@@ -1021,7 +1021,7 @@ InitializeRamRegions (
       EfiACPIMemoryNVS
       );
 
-    if (MemEncryptSevEsIsEnabled ()) {
+    if (PlatformInfoHob->SevEsIsEnabled) {
       //
       // If SEV-ES is enabled, reserve the GHCB-related memory area. This
       // includes the extra page table used to break down the 2MB page
@@ -1051,8 +1051,8 @@ InitializeRamRegions (
  #endif
   }
 
-  if (mBootMode != BOOT_ON_S3_RESUME) {
-    if (!FeaturePcdGet (PcdSmmSmramRequire)) {
+  if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
+    if (!PlatformInfoHob->SmmSmramRequire) {
       //
       // Reserve the lock box storage area
       //
@@ -1070,20 +1070,20 @@ InitializeRamRegions (
       BuildMemoryAllocationHob (
         (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase),
         (UINT64)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageSize),
-        mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+        PlatformInfoHob->S3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
         );
     }
 
-    if (FeaturePcdGet (PcdSmmSmramRequire)) {
+    if (PlatformInfoHob->SmmSmramRequire) {
       UINT32  TsegSize;
 
       //
       // Make sure the TSEG area that we reported as a reserved memory resource
       // cannot be used for reserved memory allocations.
       //
-      TsegSize = mQ35TsegMbytes * SIZE_1MB;
+      TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB;
       BuildMemoryAllocationHob (
-        GetSystemMemorySizeBelow4gb () - TsegSize,
+        GetSystemMemorySizeBelow4gb (PlatformInfoHob) - TsegSize,
         TsegSize,
         EfiReservedMemoryType
         );
@@ -1091,7 +1091,7 @@ InitializeRamRegions (
       // Similarly, allocate away the (already reserved) SMRAM at the default
       // SMBASE, if it exists.
       //
-      if (mQ35SmramAtDefaultSmbase) {
+      if (PlatformInfoHob->Q35SmramAtDefaultSmbase) {
         BuildMemoryAllocationHob (
           SMM_DEFAULT_SMBASE,
           MCH_DEFAULT_SMBASE_SIZE,
@@ -1115,7 +1115,7 @@ InitializeRamRegions (
       BuildMemoryAllocationHob (
         (EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase),
         (UINT64)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaSize),
-        mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+        PlatformInfoHob->S3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
         );
     }
 
diff --git a/OvmfPkg/PlatformPei/MemTypeInfo.c b/OvmfPkg/PlatformPei/MemTypeInfo.c
index fc5ccfaf113d..6ee36ad1cc5c 100644
--- a/OvmfPkg/PlatformPei/MemTypeInfo.c
+++ b/OvmfPkg/PlatformPei/MemTypeInfo.c
@@ -17,6 +17,8 @@
 
 #include "Platform.h"
 
+extern EFI_HOB_PLATFORM_INFO  mPlatformInfoHob;
+
 #define MEMORY_TYPE_INFO_DEFAULT(Type) \
   { Type, FixedPcdGet32 (PcdMemoryType ## Type) }
 
@@ -208,7 +210,7 @@ MemTypeInfoInitialization (
 {
   EFI_STATUS  Status;
 
-  if (!FeaturePcdGet (PcdSmmSmramRequire)) {
+  if (!mPlatformInfoHob.SmmSmramRequire) {
     //
     // EFI_PEI_READ_ONLY_VARIABLE2_PPI will never be available; install
     // the default memory type information HOB right away.
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 62480c3c40e5..80eb4cc9adcd 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -36,11 +36,13 @@
 #include <IndustryStandard/Pci22.h>
 #include <IndustryStandard/Q35MchIch9.h>
 #include <IndustryStandard/QemuCpuHotplug.h>
-#include <Library/PlatformInitLib.h>
+#include <Library/MemEncryptSevLib.h>
 #include <OvmfPlatforms.h>
 
 #include "Platform.h"
 
+EFI_HOB_PLATFORM_INFO  mPlatformInfoHob = { 0 };
+
 EFI_PEI_PPI_DESCRIPTOR  mPpiBootMode[] = {
   {
     EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
@@ -49,17 +51,9 @@ EFI_PEI_PPI_DESCRIPTOR  mPpiBootMode[] = {
   }
 };
 
-UINT16  mHostBridgeDevId;
-
-EFI_BOOT_MODE  mBootMode = BOOT_WITH_FULL_CONFIGURATION;
-
-BOOLEAN  mS3Supported = FALSE;
-
-UINT32  mMaxCpuCount;
-
 VOID
 MemMapInitialization (
-  VOID
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
   UINT64         PciIoBase;
@@ -78,16 +72,16 @@ MemMapInitialization (
   //
   PlatformAddIoMemoryRangeHob (0x0A0000, BASE_1MB);
 
-  if (mHostBridgeDevId == 0xffff /* microvm */) {
+  if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {
     PlatformAddIoMemoryBaseSizeHob (MICROVM_GED_MMIO_BASE, SIZE_4KB);
     PlatformAddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); /* ioapic #1 */
     PlatformAddIoMemoryBaseSizeHob (0xFEC10000, SIZE_4KB); /* ioapic #2 */
     return;
   }
 
-  TopOfLowRam  = GetSystemMemorySizeBelow4gb ();
+  TopOfLowRam  = GetSystemMemorySizeBelow4gb (PlatformInfoHob);
   PciExBarBase = 0;
-  if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
     //
     // The MMCONFIG area is expected to fall between the top of low RAM and
     // the base of the 32-bit PCI host aperture.
@@ -97,8 +91,8 @@ MemMapInitialization (
     ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);
     PciBase = (UINT32)(PciExBarBase + SIZE_256MB);
   } else {
-    ASSERT (TopOfLowRam <= mQemuUc32Base);
-    PciBase = mQemuUc32Base;
+    ASSERT (TopOfLowRam <= PlatformInfoHob->Uc32Base);
+    PciBase = PlatformInfoHob->Uc32Base;
   }
 
   //
@@ -121,9 +115,12 @@ MemMapInitialization (
   PcdStatus = PcdSet64S (PcdPciMmio32Size, PciSize);
   ASSERT_RETURN_ERROR (PcdStatus);
 
+  PlatformInfoHob->PcdPciMmio32Base = PciBase;
+  PlatformInfoHob->PcdPciMmio32Size = PciSize;
+
   PlatformAddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
   PlatformAddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
-  if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
     PlatformAddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);
     //
     // Note: there should be an
@@ -160,7 +157,7 @@ MemMapInitialization (
   // On Q35, the IO Port space is available for PCI resource allocations from
   // 0x6000 up.
   //
-  if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
     PciIoBase = 0x6000;
     PciIoSize = 0xA000;
     ASSERT ((ICH9_PMBASE_VALUE & 0xF000) < PciIoBase);
@@ -180,6 +177,9 @@ MemMapInitialization (
   ASSERT_RETURN_ERROR (PcdStatus);
   PcdStatus = PcdSet64S (PcdPciIoSize, PciIoSize);
   ASSERT_RETURN_ERROR (PcdStatus);
+
+  PlatformInfoHob->PcdPciIoBase = PciIoBase;
+  PlatformInfoHob->PcdPciIoSize = PciIoSize;
 }
 
 #define UPDATE_BOOLEAN_PCD_FROM_FW_CFG(TokenName)                   \
@@ -306,7 +306,7 @@ MicrovmInitialization (
 
 VOID
 MiscInitialization (
-  VOID
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
   UINTN          PmCmd;
@@ -327,12 +327,12 @@ MiscInitialization (
   // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
   // S3 resume as well, so we build it unconditionally.)
   //
-  BuildCpuHob (mPhysMemAddressWidth, 16);
+  BuildCpuHob (PlatformInfoHob->PhysMemAddressWidth, 16);
 
   //
   // Determine platform type and save Host Bridge DID to PCD
   //
-  switch (mHostBridgeDevId) {
+  switch (PlatformInfoHob->HostBridgeDevId) {
     case INTEL_82441_DEVICE_ID:
       PmCmd      = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
       Pmba       = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
@@ -371,13 +371,13 @@ MiscInitialization (
         DEBUG_ERROR,
         "%a: Unknown Host Bridge Device ID: 0x%04x\n",
         __FUNCTION__,
-        mHostBridgeDevId
+        PlatformInfoHob->HostBridgeDevId
         ));
       ASSERT (FALSE);
       return;
   }
 
-  PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);
+  PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, PlatformInfoHob->HostBridgeDevId);
   ASSERT_RETURN_ERROR (PcdStatus);
 
   //
@@ -403,7 +403,7 @@ MiscInitialization (
     PciOr8 (AcpiCtlReg, AcpiEnBit);
   }
 
-  if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
     //
     // Set Root Complex Register Block BAR
     //
@@ -421,18 +421,18 @@ MiscInitialization (
 
 VOID
 BootModeInitialization (
-  VOID
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
   EFI_STATUS  Status;
 
   if (PlatformCmosRead8 (0xF) == 0xFE) {
-    mBootMode = BOOT_ON_S3_RESUME;
+    PlatformInfoHob->BootMode = BOOT_ON_S3_RESUME;
   }
 
   PlatformCmosWrite8 (0xF, 0x00);
 
-  Status = PeiServicesSetBootMode (mBootMode);
+  Status = PeiServicesSetBootMode (PlatformInfoHob->BootMode);
   ASSERT_EFI_ERROR (Status);
 
   Status = PeiServicesInstallPpi (mPpiBootMode);
@@ -473,7 +473,7 @@ S3Verification (
   )
 {
  #if defined (MDE_CPU_X64)
-  if (FeaturePcdGet (PcdSmmSmramRequire) && mS3Supported) {
+  if (mPlatformInfoHob.SmmSmramRequire && mPlatformInfoHob.S3Supported) {
     DEBUG ((
       DEBUG_ERROR,
       "%a: S3Resume2Pei doesn't support X64 PEI + SMM yet.\n",
@@ -501,7 +501,7 @@ Q35BoardVerification (
   VOID
   )
 {
-  if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+  if (mPlatformInfoHob.HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
     return;
   }
 
@@ -510,7 +510,7 @@ Q35BoardVerification (
     "%a: no TSEG (SMRAM) on host bridge DID=0x%04x; "
     "only DID=0x%04x (Q35) is supported\n",
     __FUNCTION__,
-    mHostBridgeDevId,
+    mPlatformInfoHob.HostBridgeDevId,
     INTEL_Q35_MCH_DEVICE_ID
     ));
   ASSERT (FALSE);
@@ -523,10 +523,11 @@ Q35BoardVerification (
 **/
 VOID
 MaxCpuCountInitialization (
-  VOID
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
   UINT16         BootCpuCount;
+  UINT32         MaxCpuCount;
   RETURN_STATUS  PcdStatus;
 
   //
@@ -542,7 +543,7 @@ MaxCpuCountInitialization (
     // first).
     //
     DEBUG ((DEBUG_WARN, "%a: boot CPU count unavailable\n", __FUNCTION__));
-    mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
+    MaxCpuCount = PlatformInfoHob->DefaultMaxCpuNumber;
   } else {
     //
     // We will expose BootCpuCount to MpInitLib. MpInitLib will count APs up to
@@ -553,7 +554,7 @@ MaxCpuCountInitialization (
     UINTN   CpuHpBase;
     UINT32  CmdData2;
 
-    CpuHpBase = ((mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) ?
+    CpuHpBase = ((PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) ?
                  ICH9_CPU_HOTPLUG_BASE : PIIX4_CPU_HOTPLUG_BASE);
 
     //
@@ -605,7 +606,7 @@ MaxCpuCountInitialization (
         "%a: modern CPU hotplug interface unavailable\n",
         __FUNCTION__
         ));
-      mMaxCpuCount = BootCpuCount;
+      MaxCpuCount = BootCpuCount;
     } else {
       //
       // Grab the possible CPU count from the modern CPU hotplug interface.
@@ -671,23 +672,26 @@ MaxCpuCountInitialization (
         BootCpuCount = (UINT16)Present;
       }
 
-      mMaxCpuCount = Possible;
+      MaxCpuCount = Possible;
     }
   }
 
   DEBUG ((
     DEBUG_INFO,
-    "%a: BootCpuCount=%d mMaxCpuCount=%u\n",
+    "%a: BootCpuCount=%d MaxCpuCount=%u\n",
     __FUNCTION__,
     BootCpuCount,
-    mMaxCpuCount
+    MaxCpuCount
     ));
-  ASSERT (BootCpuCount <= mMaxCpuCount);
+  ASSERT (BootCpuCount <= MaxCpuCount);
 
   PcdStatus = PcdSet32S (PcdCpuBootLogicalProcessorNumber, BootCpuCount);
   ASSERT_RETURN_ERROR (PcdStatus);
-  PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, mMaxCpuCount);
+  PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, MaxCpuCount);
   ASSERT_RETURN_ERROR (PcdStatus);
+
+  PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber  = MaxCpuCount;
+  PlatformInfoHob->PcdCpuBootLogicalProcessorNumber = BootCpuCount;
 }
 
 /**
@@ -710,27 +714,30 @@ InitializePlatform (
 
   DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));
 
+  mPlatformInfoHob.SmmSmramRequire = FeaturePcdGet (PcdSmmSmramRequire);
+  mPlatformInfoHob.SevEsIsEnabled  = MemEncryptSevEsIsEnabled ();
+
   PlatformDebugDumpCmos ();
 
   if (QemuFwCfgS3Enabled ()) {
     DEBUG ((DEBUG_INFO, "S3 support was detected on QEMU\n"));
-    mS3Supported = TRUE;
-    Status       = PcdSetBoolS (PcdAcpiS3Enable, TRUE);
+    mPlatformInfoHob.S3Supported = TRUE;
+    Status                       = PcdSetBoolS (PcdAcpiS3Enable, TRUE);
     ASSERT_EFI_ERROR (Status);
   }
 
   S3Verification ();
-  BootModeInitialization ();
-  AddressWidthInitialization ();
+  BootModeInitialization (&mPlatformInfoHob);
+  AddressWidthInitialization (&mPlatformInfoHob);
 
   //
   // Query Host Bridge DID
   //
-  mHostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
+  mPlatformInfoHob.HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
 
-  MaxCpuCountInitialization ();
+  MaxCpuCountInitialization (&mPlatformInfoHob);
 
-  if (FeaturePcdGet (PcdSmmSmramRequire)) {
+  if (mPlatformInfoHob.SmmSmramRequire) {
     Q35BoardVerification ();
     Q35TsegMbytesInitialization ();
     Q35SmramAtDefaultSmbaseInitialization ();
@@ -738,24 +745,24 @@ InitializePlatform (
 
   PublishPeiMemory ();
 
-  QemuUc32BaseInitialization ();
+  QemuUc32BaseInitialization (&mPlatformInfoHob);
 
-  InitializeRamRegions ();
+  InitializeRamRegions (&mPlatformInfoHob);
 
-  if (mBootMode != BOOT_ON_S3_RESUME) {
-    if (!FeaturePcdGet (PcdSmmSmramRequire)) {
+  if (mPlatformInfoHob.BootMode != BOOT_ON_S3_RESUME) {
+    if (!mPlatformInfoHob.SmmSmramRequire) {
       ReserveEmuVariableNvStore ();
     }
 
     PeiFvInitialization ();
     MemTypeInfoInitialization ();
-    MemMapInitialization ();
+    MemMapInitialization (&mPlatformInfoHob);
     NoexecDxeInitialization ();
   }
 
   InstallClearCacheCallback ();
   AmdSevInitialize ();
-  MiscInitialization ();
+  MiscInitialization (&mPlatformInfoHob);
   InstallFeatureControlCallback ();
 
   return EFI_SUCCESS;
diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h
index f193ff736549..a5fa27c3794f 100644
--- a/OvmfPkg/PlatformPei/Platform.h
+++ b/OvmfPkg/PlatformPei/Platform.h
@@ -10,10 +10,11 @@
 #define _PLATFORM_PEI_H_INCLUDED_
 
 #include <IndustryStandard/E820.h>
+#include <Library/PlatformInitLib.h>
 
 VOID
 AddressWidthInitialization (
-  VOID
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   );
 
 VOID
@@ -33,17 +34,37 @@ PublishPeiMemory (
 
 UINT32
 GetSystemMemorySizeBelow4gb (
-  VOID
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   );
 
 VOID
 QemuUc32BaseInitialization (
-  VOID
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   );
 
 VOID
 InitializeRamRegions (
-  VOID
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
+VOID
+MemMapInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
+VOID
+MiscInitialization (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
+VOID
+BootModeInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
+VOID
+MaxCpuCountInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   );
 
 EFI_STATUS
@@ -71,23 +92,9 @@ AmdSevInitialize (
   VOID
   );
 
-extern EFI_BOOT_MODE  mBootMode;
-
 VOID
 SevInitializeRam (
   VOID
   );
 
-extern BOOLEAN  mS3Supported;
-
-extern UINT8  mPhysMemAddressWidth;
-
-extern UINT32  mMaxCpuCount;
-
-extern UINT16  mHostBridgeDevId;
-
-extern BOOLEAN  mQ35SmramAtDefaultSmbase;
-
-extern UINT32  mQemuUc32Base;
-
 #endif // _PLATFORM_PEI_H_INCLUDED_
-- 
2.29.2.windows.2


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

* [PATCH 04/14] OvmfPkg/PlatformPei: Refactor MiscInitialization
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (2 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 03/14] OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 05/14] OvmfPkg/PlatformPei: Refactor MiscInitialization for CloudHV Min Xu
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

In MiscInitialization Microvm looks a little weird. Other platforms
call PcdSet16S to set the PcdOvmfHostBridgePciDevId with the value same
as PlatformInfoHob->HostBridgeDevId. But Microvm doesn't follow this
way. In switch-case 0xffff is Microvm, but set with
MICROVM_PSEUDO_DEVICE_ID. So we have to add a new function
( MiscInitializationForMicrovm ) for Microvm and delete the code in
MiscInitialization.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/PlatformPei/Platform.c | 46 ++++++++++++++++++++++++++--------
 1 file changed, 36 insertions(+), 10 deletions(-)

diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 80eb4cc9adcd..af9e72cd7a98 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -304,6 +304,36 @@ MicrovmInitialization (
   *FdtHobData = (UINTN)NewBase;
 }
 
+VOID
+MiscInitializationForMicrovm (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  RETURN_STATUS  PcdStatus;
+
+  ASSERT (PlatformInfoHob->HostBridgeDevId == 0xffff);
+
+  DEBUG ((DEBUG_INFO, "%a: microvm\n", __FUNCTION__));
+  //
+  // Disable A20 Mask
+  //
+  IoOr8 (0x92, BIT1);
+
+  //
+  // Build the CPU HOB with guest RAM size dependent address width and 16-bits
+  // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
+  // S3 resume as well, so we build it unconditionally.)
+  //
+  BuildCpuHob (PlatformInfoHob->PhysMemAddressWidth, 16);
+
+  MicrovmInitialization ();
+  PcdStatus = PcdSet16S (
+                PcdOvmfHostBridgePciDevId,
+                MICROVM_PSEUDO_DEVICE_ID
+                );
+  ASSERT_RETURN_ERROR (PcdStatus);
+}
+
 VOID
 MiscInitialization (
   IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
@@ -349,15 +379,6 @@ MiscInitialization (
       AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
       AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
       break;
-    case 0xffff: /* microvm */
-      DEBUG ((DEBUG_INFO, "%a: microvm\n", __FUNCTION__));
-      MicrovmInitialization ();
-      PcdStatus = PcdSet16S (
-                    PcdOvmfHostBridgePciDevId,
-                    MICROVM_PSEUDO_DEVICE_ID
-                    );
-      ASSERT_RETURN_ERROR (PcdStatus);
-      return;
     case CLOUDHV_DEVICE_ID:
       DEBUG ((DEBUG_INFO, "%a: Cloud Hypervisor host bridge\n", __FUNCTION__));
       PcdStatus = PcdSet16S (
@@ -762,7 +783,12 @@ InitializePlatform (
 
   InstallClearCacheCallback ();
   AmdSevInitialize ();
-  MiscInitialization (&mPlatformInfoHob);
+  if (mPlatformInfoHob.HostBridgeDevId == 0xffff) {
+    MiscInitializationForMicrovm (&mPlatformInfoHob);
+  } else {
+    MiscInitialization (&mPlatformInfoHob);
+  }
+
   InstallFeatureControlCallback ();
 
   return EFI_SUCCESS;
-- 
2.29.2.windows.2


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

* [PATCH 05/14] OvmfPkg/PlatformPei: Refactor MiscInitialization for CloudHV
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (3 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 04/14] OvmfPkg/PlatformPei: Refactor MiscInitialization Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 06/14] OvmfPkg/PlatformPei: Refactor AddressWidthInitialization Min Xu
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

Refactor MiscInitialization for CloudHV to set PCD as other platforms
do. Because in the following patch we will split the functions which
set PCDs into two, one for PlatformInitLib, one for PlatformPei.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/PlatformPei/Platform.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index af9e72cd7a98..3e0c56db57ed 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -380,13 +380,7 @@ MiscInitialization (
       AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
       break;
     case CLOUDHV_DEVICE_ID:
-      DEBUG ((DEBUG_INFO, "%a: Cloud Hypervisor host bridge\n", __FUNCTION__));
-      PcdStatus = PcdSet16S (
-                    PcdOvmfHostBridgePciDevId,
-                    CLOUDHV_DEVICE_ID
-                    );
-      ASSERT_RETURN_ERROR (PcdStatus);
-      return;
+      break;
     default:
       DEBUG ((
         DEBUG_ERROR,
@@ -401,6 +395,11 @@ MiscInitialization (
   PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, PlatformInfoHob->HostBridgeDevId);
   ASSERT_RETURN_ERROR (PcdStatus);
 
+  if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
+    DEBUG ((DEBUG_INFO, "%a: Cloud Hypervisor is done.\n", __FUNCTION__));
+    return;
+  }
+
   //
   // If the appropriate IOspace enable bit is set, assume the ACPI PMBA has
   // been configured and skip the setup here. This matches the logic in
-- 
2.29.2.windows.2


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

* [PATCH 06/14] OvmfPkg/PlatformPei: Refactor AddressWidthInitialization
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (4 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 05/14] OvmfPkg/PlatformPei: Refactor MiscInitialization for CloudHV Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 07/14] OvmfPkg/PlatformPei: Refactor MaxCpuCountInitialization Min Xu
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

>From this patch we start to restruct the functions which set PCDs into
two, one for PlatformInitLib, one for PlatformPei.

AddressWidthInitialization is the first one. It is splitted into two:
 - PlatformAddressWidthInitialization is for PlatformInitLib
 - AddressWidthInitialization is for PlatformPei. It calls
   PlatformAddressWidthInitialization then set PCDs.

Below functions are also refined for PlatformInitLib:
 - PlatformScanOrAdd64BitE820Ram
 - PlatformGetSystemMemorySizeAbove4gb
 - PlatformGetFirstNonAddress

All the SetPcd codes are removed from above functions.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/PlatformPei/MemDetect.c | 111 ++++++++++++++++++++------------
 OvmfPkg/PlatformPei/Platform.c  |   6 +-
 2 files changed, 75 insertions(+), 42 deletions(-)

diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index 981a9ff28685..56011143759c 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -191,7 +191,7 @@ QemuUc32BaseInitialization (
   Find the highest exclusive >=4GB RAM address, or produce memory resource
   descriptor HOBs for RAM entries that start at or above 4GB.
 
-  @param[out] MaxAddress  If MaxAddress is NULL, then ScanOrAdd64BitE820Ram()
+  @param[out] MaxAddress  If MaxAddress is NULL, then PlatformScanOrAdd64BitE820Ram()
                           produces memory resource descriptor HOBs for RAM
                           entries that start at or above 4GB.
 
@@ -212,7 +212,7 @@ QemuUc32BaseInitialization (
 **/
 STATIC
 EFI_STATUS
-ScanOrAdd64BitE820Ram (
+PlatformScanOrAdd64BitE820Ram (
   IN BOOLEAN  AddHighHob,
   OUT UINT64  *LowMemory OPTIONAL,
   OUT UINT64  *MaxAddress OPTIONAL
@@ -387,7 +387,7 @@ GetSystemMemorySizeBelow4gb (
     return (UINT32)GetHighestSystemMemoryAddressFromPvhMemmap (TRUE);
   }
 
-  Status = ScanOrAdd64BitE820Ram (FALSE, &LowerMemorySize, NULL);
+  Status = PlatformScanOrAdd64BitE820Ram (FALSE, &LowerMemorySize, NULL);
   if ((Status == EFI_SUCCESS) && (LowerMemorySize > 0)) {
     return (UINT32)LowerMemorySize;
   }
@@ -409,7 +409,7 @@ GetSystemMemorySizeBelow4gb (
 
 STATIC
 UINT64
-GetSystemMemorySizeAbove4gb (
+PlatformGetSystemMemorySizeAbove4gb (
   )
 {
   UINT32  Size;
@@ -436,7 +436,7 @@ GetSystemMemorySizeAbove4gb (
 **/
 STATIC
 UINT64
-GetFirstNonAddress (
+PlatformGetFirstNonAddress (
   IN OUT  EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
@@ -446,7 +446,6 @@ GetFirstNonAddress (
   FIRMWARE_CONFIG_ITEM  FwCfgItem;
   UINTN                 FwCfgSize;
   UINT64                HotPlugMemoryEnd;
-  RETURN_STATUS         PcdStatus;
 
   //
   // set FirstNonAddress to suppress incorrect compiler/analyzer warnings
@@ -460,9 +459,9 @@ GetFirstNonAddress (
   // Otherwise, get the flat size of the memory above 4GB from the CMOS (which
   // can only express a size smaller than 1TB), and add it to 4GB.
   //
-  Status = ScanOrAdd64BitE820Ram (FALSE, NULL, &FirstNonAddress);
+  Status = PlatformScanOrAdd64BitE820Ram (FALSE, NULL, &FirstNonAddress);
   if (EFI_ERROR (Status)) {
-    FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();
+    FirstNonAddress = BASE_4GB + PlatformGetSystemMemorySizeAbove4gb ();
   }
 
   //
@@ -477,12 +476,6 @@ GetFirstNonAddress (
 
  #endif
 
-  //
-  // Otherwise, in order to calculate the highest address plus one, we must
-  // consider the 64-bit PCI host aperture too. Fetch the default size.
-  //
-  PlatformInfoHob->PcdPciMmio64Size = PcdGet64 (PcdPciMmio64Size);
-
   //
   // See if the user specified the number of megabytes for the 64-bit PCI host
   // aperture. Accept an aperture size up to 16TB.
@@ -524,8 +517,6 @@ GetFirstNonAddress (
         "%a: disabling 64-bit PCI host aperture\n",
         __FUNCTION__
         ));
-      PcdStatus = PcdSet64S (PcdPciMmio64Size, 0);
-      ASSERT_RETURN_ERROR (PcdStatus);
     }
 
     //
@@ -576,26 +567,6 @@ GetFirstNonAddress (
   //
   PlatformInfoHob->PcdPciMmio64Base = ALIGN_VALUE (PlatformInfoHob->PcdPciMmio64Base, GetPowerOfTwo64 (PlatformInfoHob->PcdPciMmio64Size));
 
-  if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
-    //
-    // The core PciHostBridgeDxe driver will automatically add this range to
-    // the GCD memory space map through our PciHostBridgeLib instance; here we
-    // only need to set the PCDs.
-    //
-    PcdStatus = PcdSet64S (PcdPciMmio64Base, PlatformInfoHob->PcdPciMmio64Base);
-    ASSERT_RETURN_ERROR (PcdStatus);
-    PcdStatus = PcdSet64S (PcdPciMmio64Size, PlatformInfoHob->PcdPciMmio64Size);
-    ASSERT_RETURN_ERROR (PcdStatus);
-
-    DEBUG ((
-      DEBUG_INFO,
-      "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",
-      __FUNCTION__,
-      PlatformInfoHob->PcdPciMmio64Base,
-      PlatformInfoHob->PcdPciMmio64Size
-      ));
-  }
-
   //
   // The useful address space ends with the 64-bit PCI host aperture.
   //
@@ -607,7 +578,8 @@ GetFirstNonAddress (
   Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
 **/
 VOID
-AddressWidthInitialization (
+EFIAPI
+PlatformAddressWidthInitialization (
   IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
@@ -620,7 +592,7 @@ AddressWidthInitialization (
   // The DXL IPL keys off of the physical address bits advertized in the CPU
   // HOB. To conserve memory, we calculate the minimum address width here.
   //
-  FirstNonAddress     = GetFirstNonAddress (PlatformInfoHob);
+  FirstNonAddress     = PlatformGetFirstNonAddress (PlatformInfoHob);
   PhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
 
   //
@@ -647,6 +619,65 @@ AddressWidthInitialization (
   PlatformInfoHob->PhysMemAddressWidth = PhysMemAddressWidth;
 }
 
+/**
+  Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
+**/
+VOID
+AddressWidthInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  RETURN_STATUS  PcdStatus;
+
+  PlatformAddressWidthInitialization (PlatformInfoHob);
+
+  //
+  // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO
+  // resources to 32-bit anyway. See DegradeResource() in
+  // "PciResourceSupport.c".
+  //
+ #ifdef MDE_CPU_IA32
+  if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+    return;
+  }
+
+ #endif
+
+  if (PlatformInfoHob->PcdPciMmio64Size == 0) {
+    if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
+      DEBUG ((
+        DEBUG_INFO,
+        "%a: disabling 64-bit PCI host aperture\n",
+        __FUNCTION__
+        ));
+      PcdStatus = PcdSet64S (PcdPciMmio64Size, 0);
+      ASSERT_RETURN_ERROR (PcdStatus);
+    }
+
+    return;
+  }
+
+  if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
+    //
+    // The core PciHostBridgeDxe driver will automatically add this range to
+    // the GCD memory space map through our PciHostBridgeLib instance; here we
+    // only need to set the PCDs.
+    //
+    PcdStatus = PcdSet64S (PcdPciMmio64Base, PlatformInfoHob->PcdPciMmio64Base);
+    ASSERT_RETURN_ERROR (PcdStatus);
+    PcdStatus = PcdSet64S (PcdPciMmio64Size, PlatformInfoHob->PcdPciMmio64Size);
+    ASSERT_RETURN_ERROR (PcdStatus);
+
+    DEBUG ((
+      DEBUG_INFO,
+      "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",
+      __FUNCTION__,
+      PlatformInfoHob->PcdPciMmio64Base,
+      PlatformInfoHob->PcdPciMmio64Size
+      ));
+  }
+}
+
 /**
   Calculate the cap for the permanent PEI memory.
 **/
@@ -904,9 +935,9 @@ QemuInitializeRam (
     // entries. Otherwise, create a single memory HOB with the flat >=4GB
     // memory size read from the CMOS.
     //
-    Status = ScanOrAdd64BitE820Ram (TRUE, NULL, NULL);
+    Status = PlatformScanOrAdd64BitE820Ram (TRUE, NULL, NULL);
     if (EFI_ERROR (Status)) {
-      UpperMemorySize = GetSystemMemorySizeAbove4gb ();
+      UpperMemorySize = PlatformGetSystemMemorySizeAbove4gb ();
       if (UpperMemorySize != 0) {
         PlatformAddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
       }
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 3e0c56db57ed..7d370c9b8fa8 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -734,8 +734,10 @@ InitializePlatform (
 
   DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));
 
-  mPlatformInfoHob.SmmSmramRequire = FeaturePcdGet (PcdSmmSmramRequire);
-  mPlatformInfoHob.SevEsIsEnabled  = MemEncryptSevEsIsEnabled ();
+  mPlatformInfoHob.SmmSmramRequire     = FeaturePcdGet (PcdSmmSmramRequire);
+  mPlatformInfoHob.SevEsIsEnabled      = MemEncryptSevEsIsEnabled ();
+  mPlatformInfoHob.PcdPciMmio64Size    = PcdGet64 (PcdPciMmio64Size);
+  mPlatformInfoHob.DefaultMaxCpuNumber = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
 
   PlatformDebugDumpCmos ();
 
-- 
2.29.2.windows.2


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

* [PATCH 07/14] OvmfPkg/PlatformPei: Refactor MaxCpuCountInitialization
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (5 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 06/14] OvmfPkg/PlatformPei: Refactor AddressWidthInitialization Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 08/14] OvmfPkg/PlatformPei: Refactor QemuUc32BaseInitialization Min Xu
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

MaxCpuCountInitialization is splitted into two:
 - PlatformMaxCpuCountInitialization is for PlatformInitLib
 - MaxCpuCountInitialization is for PlatformPei. It calls
   PlatformMaxCpuCountInitialization then sets PCDs.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/PlatformPei/Platform.c | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 7d370c9b8fa8..c184fdb57ee0 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -542,13 +542,12 @@ Q35BoardVerification (
   them to UefiCpuPkg modules. Set the mMaxCpuCount variable.
 **/
 VOID
-MaxCpuCountInitialization (
+PlatformMaxCpuCountInitialization (
   IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
-  UINT16         BootCpuCount;
-  UINT32         MaxCpuCount;
-  RETURN_STATUS  PcdStatus;
+  UINT16  BootCpuCount;
+  UINT32  MaxCpuCount;
 
   //
   // Try to fetch the boot CPU count.
@@ -705,15 +704,29 @@ MaxCpuCountInitialization (
     ));
   ASSERT (BootCpuCount <= MaxCpuCount);
 
-  PcdStatus = PcdSet32S (PcdCpuBootLogicalProcessorNumber, BootCpuCount);
-  ASSERT_RETURN_ERROR (PcdStatus);
-  PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, MaxCpuCount);
-  ASSERT_RETURN_ERROR (PcdStatus);
-
   PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber  = MaxCpuCount;
   PlatformInfoHob->PcdCpuBootLogicalProcessorNumber = BootCpuCount;
 }
 
+/**
+  Fetch the boot CPU count and the possible CPU count from QEMU, and expose
+  them to UefiCpuPkg modules. Set the mMaxCpuCount variable.
+**/
+VOID
+MaxCpuCountInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  RETURN_STATUS  PcdStatus;
+
+  PlatformMaxCpuCountInitialization (PlatformInfoHob);
+
+  PcdStatus = PcdSet32S (PcdCpuBootLogicalProcessorNumber, PlatformInfoHob->PcdCpuBootLogicalProcessorNumber);
+  ASSERT_RETURN_ERROR (PcdStatus);
+  PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber);
+  ASSERT_RETURN_ERROR (PcdStatus);
+}
+
 /**
   Perform Platform PEI initialization.
 
-- 
2.29.2.windows.2


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

* [PATCH 08/14] OvmfPkg/PlatformPei: Refactor QemuUc32BaseInitialization
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (6 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 07/14] OvmfPkg/PlatformPei: Refactor MaxCpuCountInitialization Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 09/14] OvmfPkg/PlatformPei: Refactor InitializeRamRegions Min Xu
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

Rename QemuUc32BaseInitialization to PlatformQemuUc32BaseInitialization.
This function is for PlatformInitLib.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/PlatformPei/MemDetect.c | 3 ++-
 OvmfPkg/PlatformPei/Platform.c  | 2 +-
 OvmfPkg/PlatformPei/Platform.h  | 3 ++-
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index 56011143759c..33c39228e448 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -127,7 +127,8 @@ Q35SmramAtDefaultSmbaseInitialization (
 }
 
 VOID
-QemuUc32BaseInitialization (
+EFIAPI
+PlatformQemuUc32BaseInitialization (
   IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index c184fdb57ee0..0bf92e117bee 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -780,7 +780,7 @@ InitializePlatform (
 
   PublishPeiMemory ();
 
-  QemuUc32BaseInitialization (&mPlatformInfoHob);
+  PlatformQemuUc32BaseInitialization (&mPlatformInfoHob);
 
   InitializeRamRegions (&mPlatformInfoHob);
 
diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h
index a5fa27c3794f..b5e831aa68e2 100644
--- a/OvmfPkg/PlatformPei/Platform.h
+++ b/OvmfPkg/PlatformPei/Platform.h
@@ -38,7 +38,8 @@ GetSystemMemorySizeBelow4gb (
   );
 
 VOID
-QemuUc32BaseInitialization (
+EFIAPI
+PlatformQemuUc32BaseInitialization (
   IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   );
 
-- 
2.29.2.windows.2


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

* [PATCH 09/14] OvmfPkg/PlatformPei: Refactor InitializeRamRegions
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (7 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 08/14] OvmfPkg/PlatformPei: Refactor QemuUc32BaseInitialization Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 10/14] OvmfPkg/PlatformPei: Refactor MemMapInitialization Min Xu
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

InitializeRamRegions is refactored into 3 calls:
 - PlatformQemuInitializeRam
 - SevInitializeRam
 - PlatformQemuInitializeRamForS3

SevInitializeRam is not in PlatformInitLib. Because in the first stage
PlatformInitLib only support the basic platform featues.

PlatformQemuInitializeRamForS3 wraps the code which was previously in
InitializeRamRegions (many code in 2 if-checks).

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/PlatformPei/MemDetect.c | 40 ++++++++++++++++++++-------------
 OvmfPkg/PlatformPei/Platform.c  |  2 +-
 OvmfPkg/PlatformPei/Platform.h  |  3 ++-
 3 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index 33c39228e448..5709766f86f3 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -163,7 +163,7 @@ PlatformQemuUc32BaseInitialization (
   // variable MTRR suffices by truncating the size to a whole power of two,
   // while keeping the end affixed to 4GB. This will round the base up.
   //
-  LowerMemorySize           = GetSystemMemorySizeBelow4gb (PlatformInfoHob);
+  LowerMemorySize           = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
   PlatformInfoHob->Uc32Size = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - LowerMemorySize));
   PlatformInfoHob->Uc32Base = (UINT32)(SIZE_4GB - PlatformInfoHob->Uc32Size);
   //
@@ -374,7 +374,8 @@ GetHighestSystemMemoryAddressFromPvhMemmap (
 }
 
 UINT32
-GetSystemMemorySizeBelow4gb (
+EFIAPI
+PlatformGetSystemMemorySizeBelow4gb (
   IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
@@ -763,7 +764,7 @@ PublishPeiMemory (
   UINT32                S3AcpiReservedMemoryBase;
   UINT32                S3AcpiReservedMemorySize;
 
-  LowerMemorySize = GetSystemMemorySizeBelow4gb (&mPlatformInfoHob);
+  LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (&mPlatformInfoHob);
   if (mPlatformInfoHob.SmmSmramRequire) {
     //
     // TSEG is chipped from the end of low RAM
@@ -873,7 +874,7 @@ QemuInitializeRamBelow1gb (
 **/
 STATIC
 VOID
-QemuInitializeRam (
+PlatformQemuInitializeRam (
   IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
@@ -887,7 +888,7 @@ QemuInitializeRam (
   //
   // Determine total memory size available
   //
-  LowerMemorySize = GetSystemMemorySizeBelow4gb (PlatformInfoHob);
+  LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
 
   if (PlatformInfoHob->BootMode == BOOT_ON_S3_RESUME) {
     //
@@ -997,19 +998,12 @@ QemuInitializeRam (
   }
 }
 
-/**
-  Publish system RAM and reserve memory regions
-
-**/
+STATIC
 VOID
-InitializeRamRegions (
+PlatformQemuInitializeRamForS3 (
   IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
-  QemuInitializeRam (PlatformInfoHob);
-
-  SevInitializeRam ();
-
   if (PlatformInfoHob->S3Supported && (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME)) {
     //
     // This is the memory range that will be used for PEI on S3 resume
@@ -1115,7 +1109,7 @@ InitializeRamRegions (
       //
       TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB;
       BuildMemoryAllocationHob (
-        GetSystemMemorySizeBelow4gb (PlatformInfoHob) - TsegSize,
+        PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob) - TsegSize,
         TsegSize,
         EfiReservedMemoryType
         );
@@ -1154,3 +1148,19 @@ InitializeRamRegions (
  #endif
   }
 }
+
+/**
+  Publish system RAM and reserve memory regions
+
+**/
+VOID
+InitializeRamRegions (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  PlatformQemuInitializeRam (PlatformInfoHob);
+
+  SevInitializeRam ();
+
+  PlatformQemuInitializeRamForS3 (PlatformInfoHob);
+}
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 0bf92e117bee..3e02ba2c9fc4 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -79,7 +79,7 @@ MemMapInitialization (
     return;
   }
 
-  TopOfLowRam  = GetSystemMemorySizeBelow4gb (PlatformInfoHob);
+  TopOfLowRam  = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
   PciExBarBase = 0;
   if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
     //
diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h
index b5e831aa68e2..494836c3efe4 100644
--- a/OvmfPkg/PlatformPei/Platform.h
+++ b/OvmfPkg/PlatformPei/Platform.h
@@ -33,7 +33,8 @@ PublishPeiMemory (
   );
 
 UINT32
-GetSystemMemorySizeBelow4gb (
+EFIAPI
+PlatformGetSystemMemorySizeBelow4gb (
   IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   );
 
-- 
2.29.2.windows.2


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

* [PATCH 10/14] OvmfPkg/PlatformPei: Refactor MemMapInitialization
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (8 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 09/14] OvmfPkg/PlatformPei: Refactor InitializeRamRegions Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 11/14] OvmfPkg/PlatformPei: Refactor NoexecDxeInitialization Min Xu
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

MemMapInitialization is split into 2 functions:
 - PlatformMemMapInitialization is for PlatformInfoLib
 - MemMapInitialization calls PlatformMemMapInitialization and then
   sets PCDs. It is for PlatformPei.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/PlatformPei/Platform.c | 35 +++++++++++++++++++++++++---------
 1 file changed, 26 insertions(+), 9 deletions(-)

diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 3e02ba2c9fc4..01fca33e7119 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -52,7 +52,8 @@ EFI_PEI_PPI_DESCRIPTOR  mPpiBootMode[] = {
 };
 
 VOID
-MemMapInitialization (
+EFIAPI
+PlatformMemMapInitialization (
   IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
@@ -110,10 +111,6 @@ MemMapInitialization (
   //
   PciSize = 0xFC000000 - PciBase;
   PlatformAddIoMemoryBaseSizeHob (PciBase, PciSize);
-  PcdStatus = PcdSet64S (PcdPciMmio32Base, PciBase);
-  ASSERT_RETURN_ERROR (PcdStatus);
-  PcdStatus = PcdSet64S (PcdPciMmio32Size, PciSize);
-  ASSERT_RETURN_ERROR (PcdStatus);
 
   PlatformInfoHob->PcdPciMmio32Base = PciBase;
   PlatformInfoHob->PcdPciMmio32Size = PciSize;
@@ -173,15 +170,35 @@ MemMapInitialization (
     PciIoBase,
     PciIoSize
     );
-  PcdStatus = PcdSet64S (PcdPciIoBase, PciIoBase);
-  ASSERT_RETURN_ERROR (PcdStatus);
-  PcdStatus = PcdSet64S (PcdPciIoSize, PciIoSize);
-  ASSERT_RETURN_ERROR (PcdStatus);
 
   PlatformInfoHob->PcdPciIoBase = PciIoBase;
   PlatformInfoHob->PcdPciIoSize = PciIoSize;
 }
 
+VOID
+MemMapInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  RETURN_STATUS  PcdStatus;
+
+  PlatformMemMapInitialization (PlatformInfoHob);
+
+  if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {
+    return;
+  }
+
+  PcdStatus = PcdSet64S (PcdPciMmio32Base, PlatformInfoHob->PcdPciMmio32Base);
+  ASSERT_RETURN_ERROR (PcdStatus);
+  PcdStatus = PcdSet64S (PcdPciMmio32Size, PlatformInfoHob->PcdPciMmio32Size);
+  ASSERT_RETURN_ERROR (PcdStatus);
+
+  PcdStatus = PcdSet64S (PcdPciIoBase, PlatformInfoHob->PcdPciIoBase);
+  ASSERT_RETURN_ERROR (PcdStatus);
+  PcdStatus = PcdSet64S (PcdPciIoSize, PlatformInfoHob->PcdPciIoSize);
+  ASSERT_RETURN_ERROR (PcdStatus);
+}
+
 #define UPDATE_BOOLEAN_PCD_FROM_FW_CFG(TokenName)                   \
           do {                                                      \
             BOOLEAN       Setting;                                  \
-- 
2.29.2.windows.2


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

* [PATCH 11/14] OvmfPkg/PlatformPei: Refactor NoexecDxeInitialization
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (9 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 10/14] OvmfPkg/PlatformPei: Refactor MemMapInitialization Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 12/14] OvmfPkg/PlatformPei: Refactor MiscInitialization Min Xu
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

NoexecDxeInitialization is split into 2 functions:
 - PlatformNoexecDxeInitialization is for PlatformInitLib
 - NoexecDxeInitialization calls PlatformNoexecDxeInitialization and
   then sets PCD.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/PlatformPei/Platform.c | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 01fca33e7119..2d652b0dc127 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -59,7 +59,6 @@ PlatformMemMapInitialization (
 {
   UINT64         PciIoBase;
   UINT64         PciIoSize;
-  RETURN_STATUS  PcdStatus;
   UINT32         TopOfLowRam;
   UINT64         PciExBarBase;
   UINT32         PciBase;
@@ -199,24 +198,33 @@ MemMapInitialization (
   ASSERT_RETURN_ERROR (PcdStatus);
 }
 
-#define UPDATE_BOOLEAN_PCD_FROM_FW_CFG(TokenName)                   \
-          do {                                                      \
-            BOOLEAN       Setting;                                  \
-            RETURN_STATUS PcdStatus;                                \
-                                                                    \
-            if (!RETURN_ERROR (QemuFwCfgParseBool (                 \
-                              "opt/ovmf/" #TokenName, &Setting))) { \
-              PcdStatus = PcdSetBoolS (TokenName, Setting);         \
-              ASSERT_RETURN_ERROR (PcdStatus);                      \
-            }                                                       \
-          } while (0)
+/**
+ * Fetch "opt/ovmf/PcdSetNxForStack" from QEMU
+ *
+ * @param Setting     The pointer to the setting of "/opt/ovmf/PcdSetNxForStack".
+ * @return EFI_SUCCESS  Successfully fetch the settings.
+ */
+EFI_STATUS
+EFIAPI
+PlatformNoexecDxeInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  return QemuFwCfgParseBool ("opt/ovmf/PcdSetNxForStack", &PlatformInfoHob->PcdSetNxForStack);
+}
 
 VOID
 NoexecDxeInitialization (
   VOID
   )
 {
-  UPDATE_BOOLEAN_PCD_FROM_FW_CFG (PcdSetNxForStack);
+  RETURN_STATUS  Status;
+
+  Status = PlatformNoexecDxeInitialization (&mPlatformInfoHob);
+  if (!RETURN_ERROR (Status)) {
+    Status = PcdSetBoolS (PcdSetNxForStack, mPlatformInfoHob.PcdSetNxForStack);
+    ASSERT_RETURN_ERROR (Status);
+  }
 }
 
 VOID
-- 
2.29.2.windows.2


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

* [PATCH 12/14] OvmfPkg/PlatformPei: Refactor MiscInitialization
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (10 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 11/14] OvmfPkg/PlatformPei: Refactor NoexecDxeInitialization Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 13/14] OvmfPkg/PlatformInitLib: Create MemDetect.c Min Xu
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

MiscInitialization is split into 2 functions:
 - PlatformMiscInitialization is for PlatformInitLib.
 - MiscInitialization calls PlatformMiscInitialization and then sets
   PCD. It is for PlatformPei.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/PlatformPei/Platform.c | 43 ++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 17 deletions(-)

diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 2d652b0dc127..a5ed2c0bcc99 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -57,12 +57,12 @@ PlatformMemMapInitialization (
   IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
-  UINT64         PciIoBase;
-  UINT64         PciIoSize;
-  UINT32         TopOfLowRam;
-  UINT64         PciExBarBase;
-  UINT32         PciBase;
-  UINT32         PciSize;
+  UINT64  PciIoBase;
+  UINT64  PciIoSize;
+  UINT32  TopOfLowRam;
+  UINT64  PciExBarBase;
+  UINT32  PciBase;
+  UINT32  PciSize;
 
   PciIoBase = 0xC000;
   PciIoSize = 0x4000;
@@ -360,17 +360,16 @@ MiscInitializationForMicrovm (
 }
 
 VOID
-MiscInitialization (
+PlatformMiscInitialization (
   IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   )
 {
-  UINTN          PmCmd;
-  UINTN          Pmba;
-  UINT32         PmbaAndVal;
-  UINT32         PmbaOrVal;
-  UINTN          AcpiCtlReg;
-  UINT8          AcpiEnBit;
-  RETURN_STATUS  PcdStatus;
+  UINTN   PmCmd;
+  UINTN   Pmba;
+  UINT32  PmbaAndVal;
+  UINT32  PmbaOrVal;
+  UINTN   AcpiCtlReg;
+  UINT8   AcpiEnBit;
 
   //
   // Disable A20 Mask
@@ -417,9 +416,6 @@ MiscInitialization (
       return;
   }
 
-  PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, PlatformInfoHob->HostBridgeDevId);
-  ASSERT_RETURN_ERROR (PcdStatus);
-
   if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
     DEBUG ((DEBUG_INFO, "%a: Cloud Hypervisor is done.\n", __FUNCTION__));
     return;
@@ -464,6 +460,19 @@ MiscInitialization (
   }
 }
 
+VOID
+MiscInitialization (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  RETURN_STATUS  PcdStatus;
+
+  PlatformMiscInitialization (PlatformInfoHob);
+
+  PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, PlatformInfoHob->HostBridgeDevId);
+  ASSERT_RETURN_ERROR (PcdStatus);
+}
+
 VOID
 BootModeInitialization (
   IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-- 
2.29.2.windows.2


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

* [PATCH 13/14] OvmfPkg/PlatformInitLib: Create MemDetect.c
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (11 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 12/14] OvmfPkg/PlatformPei: Refactor MiscInitialization Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  2:36 ` [PATCH 14/14] OvmfPkg/PlatformInitLib: Move functions to Platform.c Min Xu
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

Move functions in PlatformPei\MemDetect.c to PlatformInitLib\MemDetect.c.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Include/Library/PlatformInitLib.h     |  37 +
 OvmfPkg/Library/PlatformInitLib/MemDetect.c   | 842 ++++++++++++++++++
 .../PlatformInitLib/PlatformInitLib.inf       |  49 +
 OvmfPkg/PlatformPei/MemDetect.c               | 804 +----------------
 OvmfPkg/PlatformPei/Platform.h                |  12 -
 5 files changed, 929 insertions(+), 815 deletions(-)
 create mode 100644 OvmfPkg/Library/PlatformInitLib/MemDetect.c

diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h
index 9b99d4c1f514..2e4bb8140368 100644
--- a/OvmfPkg/Include/Library/PlatformInitLib.h
+++ b/OvmfPkg/Include/Library/PlatformInitLib.h
@@ -132,4 +132,41 @@ PlatformAddReservedMemoryBaseSizeHob (
   IN BOOLEAN               Cacheable
   );
 
+VOID
+EFIAPI
+PlatformQemuUc32BaseInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
+UINT32
+EFIAPI
+PlatformGetSystemMemorySizeBelow4gb (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
+/**
+  Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
+**/
+VOID
+EFIAPI
+PlatformAddressWidthInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
+/**
+  Peform Memory Detection for QEMU / KVM
+
+**/
+VOID
+EFIAPI
+PlatformQemuInitializeRam (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
+VOID
+EFIAPI
+PlatformQemuInitializeRamForS3 (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
 #endif // PLATFORM_INIT_LIB_H_
diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
new file mode 100644
index 000000000000..fbd3073bd3d1
--- /dev/null
+++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
@@ -0,0 +1,842 @@
+/**@file
+  Memory Detection for Virtual Machines.
+
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+  MemDetect.c
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <IndustryStandard/E820.h>
+#include <IndustryStandard/I440FxPiix4.h>
+#include <IndustryStandard/Q35MchIch9.h>
+#include <IndustryStandard/CloudHv.h>
+#include <IndustryStandard/Xen/arch-x86/hvm/start_info.h>
+#include <PiPei.h>
+#include <Register/Intel/SmramSaveStateMap.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Library/QemuFwCfgSimpleParserLib.h>
+#include <Library/PlatformInitLib.h>
+
+VOID
+EFIAPI
+PlatformQemuUc32BaseInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  UINT32  LowerMemorySize;
+
+  if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {
+    return;
+  }
+
+  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+    //
+    // On q35, the 32-bit area that we'll mark as UC, through variable MTRRs,
+    // starts at PcdPciExpressBaseAddress. The platform DSC is responsible for
+    // setting PcdPciExpressBaseAddress such that describing the
+    // [PcdPciExpressBaseAddress, 4GB) range require a very small number of
+    // variable MTRRs (preferably 1 or 2).
+    //
+    ASSERT (FixedPcdGet64 (PcdPciExpressBaseAddress) <= MAX_UINT32);
+    PlatformInfoHob->Uc32Base = (UINT32)FixedPcdGet64 (PcdPciExpressBaseAddress);
+    return;
+  }
+
+  if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
+    PlatformInfoHob->Uc32Size = CLOUDHV_MMIO_HOLE_SIZE;
+    PlatformInfoHob->Uc32Base = CLOUDHV_MMIO_HOLE_ADDRESS;
+    return;
+  }
+
+  ASSERT (PlatformInfoHob->HostBridgeDevId == INTEL_82441_DEVICE_ID);
+  //
+  // On i440fx, start with the [LowerMemorySize, 4GB) range. Make sure one
+  // variable MTRR suffices by truncating the size to a whole power of two,
+  // while keeping the end affixed to 4GB. This will round the base up.
+  //
+  LowerMemorySize           = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
+  PlatformInfoHob->Uc32Size = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - LowerMemorySize));
+  PlatformInfoHob->Uc32Base = (UINT32)(SIZE_4GB - PlatformInfoHob->Uc32Size);
+  //
+  // Assuming that LowerMemorySize is at least 1 byte, Uc32Size is at most 2GB.
+  // Therefore mQemuUc32Base is at least 2GB.
+  //
+  ASSERT (PlatformInfoHob->Uc32Base >= BASE_2GB);
+
+  if (PlatformInfoHob->Uc32Base != LowerMemorySize) {
+    DEBUG ((
+      DEBUG_VERBOSE,
+      "%a: rounded UC32 base from 0x%x up to 0x%x, for "
+      "an UC32 size of 0x%x\n",
+      __FUNCTION__,
+      LowerMemorySize,
+      PlatformInfoHob->Uc32Base,
+      PlatformInfoHob->Uc32Size
+      ));
+  }
+}
+
+/**
+  Iterate over the RAM entries in QEMU's fw_cfg E820 RAM map that start outside
+  of the 32-bit address range.
+
+  Find the highest exclusive >=4GB RAM address, or produce memory resource
+  descriptor HOBs for RAM entries that start at or above 4GB.
+
+  @param[out] MaxAddress  If MaxAddress is NULL, then PlatformScanOrAdd64BitE820Ram()
+                          produces memory resource descriptor HOBs for RAM
+                          entries that start at or above 4GB.
+
+                          Otherwise, MaxAddress holds the highest exclusive
+                          >=4GB RAM address on output. If QEMU's fw_cfg E820
+                          RAM map contains no RAM entry that starts outside of
+                          the 32-bit address range, then MaxAddress is exactly
+                          4GB on output.
+
+  @retval EFI_SUCCESS         The fw_cfg E820 RAM map was found and processed.
+
+  @retval EFI_PROTOCOL_ERROR  The RAM map was found, but its size wasn't a
+                              whole multiple of sizeof(EFI_E820_ENTRY64). No
+                              RAM entry was processed.
+
+  @return                     Error codes from QemuFwCfgFindFile(). No RAM
+                              entry was processed.
+**/
+STATIC
+EFI_STATUS
+PlatformScanOrAdd64BitE820Ram (
+  IN BOOLEAN  AddHighHob,
+  OUT UINT64  *LowMemory OPTIONAL,
+  OUT UINT64  *MaxAddress OPTIONAL
+  )
+{
+  EFI_STATUS            Status;
+  FIRMWARE_CONFIG_ITEM  FwCfgItem;
+  UINTN                 FwCfgSize;
+  EFI_E820_ENTRY64      E820Entry;
+  UINTN                 Processed;
+
+  Status = QemuFwCfgFindFile ("etc/e820", &FwCfgItem, &FwCfgSize);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (FwCfgSize % sizeof E820Entry != 0) {
+    return EFI_PROTOCOL_ERROR;
+  }
+
+  if (LowMemory != NULL) {
+    *LowMemory = 0;
+  }
+
+  if (MaxAddress != NULL) {
+    *MaxAddress = BASE_4GB;
+  }
+
+  QemuFwCfgSelectItem (FwCfgItem);
+  for (Processed = 0; Processed < FwCfgSize; Processed += sizeof E820Entry) {
+    QemuFwCfgReadBytes (sizeof E820Entry, &E820Entry);
+    DEBUG ((
+      DEBUG_VERBOSE,
+      "%a: Base=0x%Lx Length=0x%Lx Type=%u\n",
+      __FUNCTION__,
+      E820Entry.BaseAddr,
+      E820Entry.Length,
+      E820Entry.Type
+      ));
+    if (E820Entry.Type == EfiAcpiAddressRangeMemory) {
+      if (AddHighHob && (E820Entry.BaseAddr >= BASE_4GB)) {
+        UINT64  Base;
+        UINT64  End;
+
+        //
+        // Round up the start address, and round down the end address.
+        //
+        Base = ALIGN_VALUE (E820Entry.BaseAddr, (UINT64)EFI_PAGE_SIZE);
+        End  = (E820Entry.BaseAddr + E820Entry.Length) &
+               ~(UINT64)EFI_PAGE_MASK;
+        if (Base < End) {
+          PlatformAddMemoryRangeHob (Base, End);
+          DEBUG ((
+            DEBUG_VERBOSE,
+            "%a: PlatformAddMemoryRangeHob [0x%Lx, 0x%Lx)\n",
+            __FUNCTION__,
+            Base,
+            End
+            ));
+        }
+      }
+
+      if (MaxAddress || LowMemory) {
+        UINT64  Candidate;
+
+        Candidate = E820Entry.BaseAddr + E820Entry.Length;
+        if (MaxAddress && (Candidate > *MaxAddress)) {
+          *MaxAddress = Candidate;
+          DEBUG ((
+            DEBUG_VERBOSE,
+            "%a: MaxAddress=0x%Lx\n",
+            __FUNCTION__,
+            *MaxAddress
+            ));
+        }
+
+        if (LowMemory && (Candidate > *LowMemory) && (Candidate < BASE_4GB)) {
+          *LowMemory = Candidate;
+          DEBUG ((
+            DEBUG_VERBOSE,
+            "%a: LowMemory=0x%Lx\n",
+            __FUNCTION__,
+            *LowMemory
+            ));
+        }
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Returns PVH memmap
+
+  @param Entries      Pointer to PVH memmap
+  @param Count        Number of entries
+
+  @return EFI_STATUS
+**/
+EFI_STATUS
+GetPvhMemmapEntries (
+  struct hvm_memmap_table_entry  **Entries,
+  UINT32                         *Count
+  )
+{
+  UINT32                 *PVHResetVectorData;
+  struct hvm_start_info  *pvh_start_info;
+
+  PVHResetVectorData = (VOID *)(UINTN)PcdGet32 (PcdXenPvhStartOfDayStructPtr);
+  if (PVHResetVectorData == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  pvh_start_info = (struct hvm_start_info *)(UINTN)PVHResetVectorData[0];
+
+  *Entries = (struct hvm_memmap_table_entry *)(UINTN)pvh_start_info->memmap_paddr;
+  *Count   = pvh_start_info->memmap_entries;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+UINT64
+GetHighestSystemMemoryAddressFromPvhMemmap (
+  BOOLEAN  Below4gb
+  )
+{
+  struct hvm_memmap_table_entry  *Memmap;
+  UINT32                         MemmapEntriesCount;
+  struct hvm_memmap_table_entry  *Entry;
+  EFI_STATUS                     Status;
+  UINT32                         Loop;
+  UINT64                         HighestAddress;
+  UINT64                         EntryEnd;
+
+  HighestAddress = 0;
+
+  Status = GetPvhMemmapEntries (&Memmap, &MemmapEntriesCount);
+  ASSERT_EFI_ERROR (Status);
+
+  for (Loop = 0; Loop < MemmapEntriesCount; Loop++) {
+    Entry    = Memmap + Loop;
+    EntryEnd = Entry->addr + Entry->size;
+
+    if ((Entry->type == XEN_HVM_MEMMAP_TYPE_RAM) &&
+        (EntryEnd > HighestAddress))
+    {
+      if (Below4gb && (EntryEnd <= BASE_4GB)) {
+        HighestAddress = EntryEnd;
+      } else if (!Below4gb && (EntryEnd >= BASE_4GB)) {
+        HighestAddress = EntryEnd;
+      }
+    }
+  }
+
+  return HighestAddress;
+}
+
+UINT32
+EFIAPI
+PlatformGetSystemMemorySizeBelow4gb (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  EFI_STATUS  Status;
+  UINT64      LowerMemorySize = 0;
+  UINT8       Cmos0x34;
+  UINT8       Cmos0x35;
+
+  if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
+    // Get the information from PVH memmap
+    return (UINT32)GetHighestSystemMemoryAddressFromPvhMemmap (TRUE);
+  }
+
+  Status = PlatformScanOrAdd64BitE820Ram (FALSE, &LowerMemorySize, NULL);
+  if ((Status == EFI_SUCCESS) && (LowerMemorySize > 0)) {
+    return (UINT32)LowerMemorySize;
+  }
+
+  //
+  // CMOS 0x34/0x35 specifies the system memory above 16 MB.
+  // * CMOS(0x35) is the high byte
+  // * CMOS(0x34) is the low byte
+  // * The size is specified in 64kb chunks
+  // * Since this is memory above 16MB, the 16MB must be added
+  //   into the calculation to get the total memory size.
+  //
+
+  Cmos0x34 = (UINT8)PlatformCmosRead8 (0x34);
+  Cmos0x35 = (UINT8)PlatformCmosRead8 (0x35);
+
+  return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
+}
+
+STATIC
+UINT64
+PlatformGetSystemMemorySizeAbove4gb (
+  )
+{
+  UINT32  Size;
+  UINTN   CmosIndex;
+
+  //
+  // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
+  // * CMOS(0x5d) is the most significant size byte
+  // * CMOS(0x5c) is the middle size byte
+  // * CMOS(0x5b) is the least significant size byte
+  // * The size is specified in 64kb chunks
+  //
+
+  Size = 0;
+  for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
+    Size = (UINT32)(Size << 8) + (UINT32)PlatformCmosRead8 (CmosIndex);
+  }
+
+  return LShiftU64 (Size, 16);
+}
+
+/**
+  Return the highest address that DXE could possibly use, plus one.
+**/
+STATIC
+UINT64
+PlatformGetFirstNonAddress (
+  IN OUT  EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  UINT64                FirstNonAddress;
+  UINT32                FwCfgPciMmio64Mb;
+  EFI_STATUS            Status;
+  FIRMWARE_CONFIG_ITEM  FwCfgItem;
+  UINTN                 FwCfgSize;
+  UINT64                HotPlugMemoryEnd;
+
+  //
+  // set FirstNonAddress to suppress incorrect compiler/analyzer warnings
+  //
+  FirstNonAddress = 0;
+
+  //
+  // If QEMU presents an E820 map, then get the highest exclusive >=4GB RAM
+  // address from it. This can express an address >= 4GB+1TB.
+  //
+  // Otherwise, get the flat size of the memory above 4GB from the CMOS (which
+  // can only express a size smaller than 1TB), and add it to 4GB.
+  //
+  Status = PlatformScanOrAdd64BitE820Ram (FALSE, NULL, &FirstNonAddress);
+  if (EFI_ERROR (Status)) {
+    FirstNonAddress = BASE_4GB + PlatformGetSystemMemorySizeAbove4gb ();
+  }
+
+  //
+  // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO
+  // resources to 32-bit anyway. See DegradeResource() in
+  // "PciResourceSupport.c".
+  //
+ #ifdef MDE_CPU_IA32
+  if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+    return FirstNonAddress;
+  }
+
+ #endif
+
+  //
+  // See if the user specified the number of megabytes for the 64-bit PCI host
+  // aperture. Accept an aperture size up to 16TB.
+  //
+  // As signaled by the "X-" prefix, this knob is experimental, and might go
+  // away at any time.
+  //
+  Status = QemuFwCfgParseUint32 (
+             "opt/ovmf/X-PciMmio64Mb",
+             FALSE,
+             &FwCfgPciMmio64Mb
+             );
+  switch (Status) {
+    case EFI_UNSUPPORTED:
+    case EFI_NOT_FOUND:
+      break;
+    case EFI_SUCCESS:
+      if (FwCfgPciMmio64Mb <= 0x1000000) {
+        PlatformInfoHob->PcdPciMmio64Size = LShiftU64 (FwCfgPciMmio64Mb, 20);
+        break;
+      }
+
+    //
+    // fall through
+    //
+    default:
+      DEBUG ((
+        DEBUG_WARN,
+        "%a: ignoring malformed 64-bit PCI host aperture size from fw_cfg\n",
+        __FUNCTION__
+        ));
+      break;
+  }
+
+  if (PlatformInfoHob->PcdPciMmio64Size == 0) {
+    if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
+      DEBUG ((
+        DEBUG_INFO,
+        "%a: disabling 64-bit PCI host aperture\n",
+        __FUNCTION__
+        ));
+    }
+
+    //
+    // There's nothing more to do; the amount of memory above 4GB fully
+    // determines the highest address plus one. The memory hotplug area (see
+    // below) plays no role for the firmware in this case.
+    //
+    return FirstNonAddress;
+  }
+
+  //
+  // The "etc/reserved-memory-end" fw_cfg file, when present, contains an
+  // absolute, exclusive end address for the memory hotplug area. This area
+  // starts right at the end of the memory above 4GB. The 64-bit PCI host
+  // aperture must be placed above it.
+  //
+  Status = QemuFwCfgFindFile (
+             "etc/reserved-memory-end",
+             &FwCfgItem,
+             &FwCfgSize
+             );
+  if (!EFI_ERROR (Status) && (FwCfgSize == sizeof HotPlugMemoryEnd)) {
+    QemuFwCfgSelectItem (FwCfgItem);
+    QemuFwCfgReadBytes (FwCfgSize, &HotPlugMemoryEnd);
+    DEBUG ((
+      DEBUG_VERBOSE,
+      "%a: HotPlugMemoryEnd=0x%Lx\n",
+      __FUNCTION__,
+      HotPlugMemoryEnd
+      ));
+
+    ASSERT (HotPlugMemoryEnd >= FirstNonAddress);
+    FirstNonAddress = HotPlugMemoryEnd;
+  }
+
+  //
+  // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so
+  // that the host can map it with 1GB hugepages. Follow suit.
+  //
+  PlatformInfoHob->PcdPciMmio64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
+  PlatformInfoHob->PcdPciMmio64Size = ALIGN_VALUE (PlatformInfoHob->PcdPciMmio64Size, (UINT64)SIZE_1GB);
+
+  //
+  // The 64-bit PCI host aperture should also be "naturally" aligned. The
+  // alignment is determined by rounding the size of the aperture down to the
+  // next smaller or equal power of two. That is, align the aperture by the
+  // largest BAR size that can fit into it.
+  //
+  PlatformInfoHob->PcdPciMmio64Base = ALIGN_VALUE (PlatformInfoHob->PcdPciMmio64Base, GetPowerOfTwo64 (PlatformInfoHob->PcdPciMmio64Size));
+
+  //
+  // The useful address space ends with the 64-bit PCI host aperture.
+  //
+  FirstNonAddress = PlatformInfoHob->PcdPciMmio64Base + PlatformInfoHob->PcdPciMmio64Size;
+  return FirstNonAddress;
+}
+
+/**
+  Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
+**/
+VOID
+EFIAPI
+PlatformAddressWidthInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  UINT64  FirstNonAddress;
+  UINT8   PhysMemAddressWidth;
+
+  //
+  // As guest-physical memory size grows, the permanent PEI RAM requirements
+  // are dominated by the identity-mapping page tables built by the DXE IPL.
+  // The DXL IPL keys off of the physical address bits advertized in the CPU
+  // HOB. To conserve memory, we calculate the minimum address width here.
+  //
+  FirstNonAddress     = PlatformGetFirstNonAddress (PlatformInfoHob);
+  PhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
+
+  //
+  // If FirstNonAddress is not an integral power of two, then we need an
+  // additional bit.
+  //
+  if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
+    ++PhysMemAddressWidth;
+  }
+
+  //
+  // The minimum address width is 36 (covers up to and excluding 64 GB, which
+  // is the maximum for Ia32 + PAE). The theoretical architecture maximum for
+  // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We
+  // can simply assert that here, since 48 bits are good enough for 256 TB.
+  //
+  if (PhysMemAddressWidth <= 36) {
+    PhysMemAddressWidth = 36;
+  }
+
+  ASSERT (PhysMemAddressWidth <= 48);
+
+  PlatformInfoHob->FirstNonAddress     = FirstNonAddress;
+  PlatformInfoHob->PhysMemAddressWidth = PhysMemAddressWidth;
+}
+
+STATIC
+VOID
+QemuInitializeRamBelow1gb (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  if (PlatformInfoHob->SmmSmramRequire && PlatformInfoHob->Q35SmramAtDefaultSmbase) {
+    PlatformAddMemoryRangeHob (0, SMM_DEFAULT_SMBASE);
+    PlatformAddReservedMemoryBaseSizeHob (
+      SMM_DEFAULT_SMBASE,
+      MCH_DEFAULT_SMBASE_SIZE,
+      TRUE /* Cacheable */
+      );
+    STATIC_ASSERT (
+      SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE < BASE_512KB + BASE_128KB,
+      "end of SMRAM at default SMBASE ends at, or exceeds, 640KB"
+      );
+    PlatformAddMemoryRangeHob (
+      SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE,
+      BASE_512KB + BASE_128KB
+      );
+  } else {
+    PlatformAddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
+  }
+}
+
+/**
+  Peform Memory Detection for QEMU / KVM
+
+**/
+VOID
+EFIAPI
+PlatformQemuInitializeRam (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  UINT64         LowerMemorySize;
+  UINT64         UpperMemorySize;
+  MTRR_SETTINGS  MtrrSettings;
+  EFI_STATUS     Status;
+
+  DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__));
+
+  //
+  // Determine total memory size available
+  //
+  LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
+
+  if (PlatformInfoHob->BootMode == BOOT_ON_S3_RESUME) {
+    //
+    // Create the following memory HOB as an exception on the S3 boot path.
+    //
+    // Normally we'd create memory HOBs only on the normal boot path. However,
+    // CpuMpPei specifically needs such a low-memory HOB on the S3 path as
+    // well, for "borrowing" a subset of it temporarily, for the AP startup
+    // vector.
+    //
+    // CpuMpPei saves the original contents of the borrowed area in permanent
+    // PEI RAM, in a backup buffer allocated with the normal PEI services.
+    // CpuMpPei restores the original contents ("returns" the borrowed area) at
+    // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before
+    // transferring control to the OS's wakeup vector in the FACS.
+    //
+    // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to
+    // restore the original contents. Furthermore, we expect all such PEIMs
+    // (CpuMpPei included) to claim the borrowed areas by producing memory
+    // allocation HOBs, and to honor preexistent memory allocation HOBs when
+    // looking for an area to borrow.
+    //
+    QemuInitializeRamBelow1gb (PlatformInfoHob);
+  } else {
+    //
+    // Create memory HOBs
+    //
+    QemuInitializeRamBelow1gb (PlatformInfoHob);
+
+    if (PlatformInfoHob->SmmSmramRequire) {
+      UINT32  TsegSize;
+
+      TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB;
+      PlatformAddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);
+      PlatformAddReservedMemoryBaseSizeHob (
+        LowerMemorySize - TsegSize,
+        TsegSize,
+        TRUE
+        );
+    } else {
+      PlatformAddMemoryRangeHob (BASE_1MB, LowerMemorySize);
+    }
+
+    //
+    // If QEMU presents an E820 map, then create memory HOBs for the >=4GB RAM
+    // entries. Otherwise, create a single memory HOB with the flat >=4GB
+    // memory size read from the CMOS.
+    //
+    Status = PlatformScanOrAdd64BitE820Ram (TRUE, NULL, NULL);
+    if (EFI_ERROR (Status)) {
+      UpperMemorySize = PlatformGetSystemMemorySizeAbove4gb ();
+      if (UpperMemorySize != 0) {
+        PlatformAddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
+      }
+    }
+  }
+
+  //
+  // We'd like to keep the following ranges uncached:
+  // - [640 KB, 1 MB)
+  // - [LowerMemorySize, 4 GB)
+  //
+  // Everything else should be WB. Unfortunately, programming the inverse (ie.
+  // keeping the default UC, and configuring the complement set of the above as
+  // WB) is not reliable in general, because the end of the upper RAM can have
+  // practically any alignment, and we may not have enough variable MTRRs to
+  // cover it exactly.
+  //
+  if (IsMtrrSupported () && (PlatformInfoHob->HostBridgeDevId != CLOUDHV_DEVICE_ID)) {
+    MtrrGetAllMtrrs (&MtrrSettings);
+
+    //
+    // MTRRs disabled, fixed MTRRs disabled, default type is uncached
+    //
+    ASSERT ((MtrrSettings.MtrrDefType & BIT11) == 0);
+    ASSERT ((MtrrSettings.MtrrDefType & BIT10) == 0);
+    ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == 0);
+
+    //
+    // flip default type to writeback
+    //
+    SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, 0x06);
+    ZeroMem (&MtrrSettings.Variables, sizeof MtrrSettings.Variables);
+    MtrrSettings.MtrrDefType |= BIT11 | BIT10 | 6;
+    MtrrSetAllMtrrs (&MtrrSettings);
+
+    //
+    // Set memory range from 640KB to 1MB to uncacheable
+    //
+    Status = MtrrSetMemoryAttribute (
+               BASE_512KB + BASE_128KB,
+               BASE_1MB - (BASE_512KB + BASE_128KB),
+               CacheUncacheable
+               );
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Set the memory range from the start of the 32-bit MMIO area (32-bit PCI
+    // MMIO aperture on i440fx, PCIEXBAR on q35) to 4GB as uncacheable.
+    //
+    Status = MtrrSetMemoryAttribute (
+               PlatformInfoHob->Uc32Base,
+               SIZE_4GB - PlatformInfoHob->Uc32Base,
+               CacheUncacheable
+               );
+    ASSERT_EFI_ERROR (Status);
+  }
+}
+
+VOID
+EFIAPI
+PlatformQemuInitializeRamForS3 (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  if (PlatformInfoHob->S3Supported && (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME)) {
+    //
+    // This is the memory range that will be used for PEI on S3 resume
+    //
+    BuildMemoryAllocationHob (
+      PlatformInfoHob->S3AcpiReservedMemoryBase,
+      PlatformInfoHob->S3AcpiReservedMemorySize,
+      EfiACPIMemoryNVS
+      );
+
+    //
+    // Cover the initial RAM area used as stack and temporary PEI heap.
+    //
+    // This is reserved as ACPI NVS so it can be used on S3 resume.
+    //
+    BuildMemoryAllocationHob (
+      PcdGet32 (PcdOvmfSecPeiTempRamBase),
+      PcdGet32 (PcdOvmfSecPeiTempRamSize),
+      EfiACPIMemoryNVS
+      );
+
+    //
+    // SEC stores its table of GUIDed section handlers here.
+    //
+    BuildMemoryAllocationHob (
+      PcdGet64 (PcdGuidedExtractHandlerTableAddress),
+      PcdGet32 (PcdGuidedExtractHandlerTableSize),
+      EfiACPIMemoryNVS
+      );
+
+ #ifdef MDE_CPU_X64
+    //
+    // Reserve the initial page tables built by the reset vector code.
+    //
+    // Since this memory range will be used by the Reset Vector on S3
+    // resume, it must be reserved as ACPI NVS.
+    //
+    BuildMemoryAllocationHob (
+      (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase),
+      (UINT64)(UINTN)PcdGet32 (PcdOvmfSecPageTablesSize),
+      EfiACPIMemoryNVS
+      );
+
+    if (PlatformInfoHob->SevEsIsEnabled) {
+      //
+      // If SEV-ES is enabled, reserve the GHCB-related memory area. This
+      // includes the extra page table used to break down the 2MB page
+      // mapping into 4KB page entries where the GHCB resides and the
+      // GHCB area itself.
+      //
+      // Since this memory range will be used by the Reset Vector on S3
+      // resume, it must be reserved as ACPI NVS.
+      //
+      BuildMemoryAllocationHob (
+        (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbPageTableBase),
+        (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbPageTableSize),
+        EfiACPIMemoryNVS
+        );
+      BuildMemoryAllocationHob (
+        (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbBase),
+        (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbSize),
+        EfiACPIMemoryNVS
+        );
+      BuildMemoryAllocationHob (
+        (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupBase),
+        (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupSize),
+        EfiACPIMemoryNVS
+        );
+    }
+
+ #endif
+  }
+
+  if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
+    if (!PlatformInfoHob->SmmSmramRequire) {
+      //
+      // Reserve the lock box storage area
+      //
+      // Since this memory range will be used on S3 resume, it must be
+      // reserved as ACPI NVS.
+      //
+      // If S3 is unsupported, then various drivers might still write to the
+      // LockBox area. We ought to prevent DXE from serving allocation requests
+      // such that they would overlap the LockBox storage.
+      //
+      ZeroMem (
+        (VOID *)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase),
+        (UINTN)PcdGet32 (PcdOvmfLockBoxStorageSize)
+        );
+      BuildMemoryAllocationHob (
+        (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase),
+        (UINT64)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageSize),
+        PlatformInfoHob->S3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+        );
+    }
+
+    if (PlatformInfoHob->SmmSmramRequire) {
+      UINT32  TsegSize;
+
+      //
+      // Make sure the TSEG area that we reported as a reserved memory resource
+      // cannot be used for reserved memory allocations.
+      //
+      TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB;
+      BuildMemoryAllocationHob (
+        PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob) - TsegSize,
+        TsegSize,
+        EfiReservedMemoryType
+        );
+      //
+      // Similarly, allocate away the (already reserved) SMRAM at the default
+      // SMBASE, if it exists.
+      //
+      if (PlatformInfoHob->Q35SmramAtDefaultSmbase) {
+        BuildMemoryAllocationHob (
+          SMM_DEFAULT_SMBASE,
+          MCH_DEFAULT_SMBASE_SIZE,
+          EfiReservedMemoryType
+          );
+      }
+    }
+
+ #ifdef MDE_CPU_X64
+    if (FixedPcdGet32 (PcdOvmfWorkAreaSize) != 0) {
+      //
+      // Reserve the work area.
+      //
+      // Since this memory range will be used by the Reset Vector on S3
+      // resume, it must be reserved as ACPI NVS.
+      //
+      // If S3 is unsupported, then various drivers might still write to the
+      // work area. We ought to prevent DXE from serving allocation requests
+      // such that they would overlap the work area.
+      //
+      BuildMemoryAllocationHob (
+        (EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase),
+        (UINT64)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaSize),
+        PlatformInfoHob->S3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+        );
+    }
+
+ #endif
+  }
+}
diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
index 21813458cb59..19a88d363819 100644
--- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
+++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
@@ -24,15 +24,64 @@
 
 [Sources]
   Cmos.c
+  MemDetect.c
   Platform.c
 
 [Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
   OvmfPkg/OvmfPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
 
 [LibraryClasses]
   BaseLib
   DebugLib
   IoLib
   HobLib
+  QemuFwCfgLib
+  QemuFwCfgSimpleParserLib
+  MtrrLib
+  PcdLib
+  PciLib
+
+[FixedPcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
+
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfCpuidSize
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBackupSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSnpSecretsSize
+
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbPageTableSize
+
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecGhcbSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
+  gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtr
+  gUefiOvmfPkgTokenSpaceGuid.PcdXenPvhStartOfDayStructPtrSize
+  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+  gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+
+[FeaturePcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index 5709766f86f3..3907de1545de 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -34,7 +34,7 @@ Module Name:
 #include <Library/PciLib.h>
 #include <Library/PeimEntryPoint.h>
 #include <Library/ResourcePublicationLib.h>
-#include <Library/MtrrLib.h>
+
 #include <Library/QemuFwCfgLib.h>
 #include <Library/QemuFwCfgSimpleParserLib.h>
 
@@ -126,501 +126,6 @@ Q35SmramAtDefaultSmbaseInitialization (
   ASSERT_RETURN_ERROR (PcdStatus);
 }
 
-VOID
-EFIAPI
-PlatformQemuUc32BaseInitialization (
-  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  UINT32  LowerMemorySize;
-
-  if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {
-    return;
-  }
-
-  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
-    //
-    // On q35, the 32-bit area that we'll mark as UC, through variable MTRRs,
-    // starts at PcdPciExpressBaseAddress. The platform DSC is responsible for
-    // setting PcdPciExpressBaseAddress such that describing the
-    // [PcdPciExpressBaseAddress, 4GB) range require a very small number of
-    // variable MTRRs (preferably 1 or 2).
-    //
-    ASSERT (FixedPcdGet64 (PcdPciExpressBaseAddress) <= MAX_UINT32);
-    PlatformInfoHob->Uc32Base = (UINT32)FixedPcdGet64 (PcdPciExpressBaseAddress);
-    return;
-  }
-
-  if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
-    PlatformInfoHob->Uc32Size = CLOUDHV_MMIO_HOLE_SIZE;
-    PlatformInfoHob->Uc32Base = CLOUDHV_MMIO_HOLE_ADDRESS;
-    return;
-  }
-
-  ASSERT (PlatformInfoHob->HostBridgeDevId == INTEL_82441_DEVICE_ID);
-  //
-  // On i440fx, start with the [LowerMemorySize, 4GB) range. Make sure one
-  // variable MTRR suffices by truncating the size to a whole power of two,
-  // while keeping the end affixed to 4GB. This will round the base up.
-  //
-  LowerMemorySize           = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
-  PlatformInfoHob->Uc32Size = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - LowerMemorySize));
-  PlatformInfoHob->Uc32Base = (UINT32)(SIZE_4GB - PlatformInfoHob->Uc32Size);
-  //
-  // Assuming that LowerMemorySize is at least 1 byte, Uc32Size is at most 2GB.
-  // Therefore mQemuUc32Base is at least 2GB.
-  //
-  ASSERT (PlatformInfoHob->Uc32Base >= BASE_2GB);
-
-  if (PlatformInfoHob->Uc32Base != LowerMemorySize) {
-    DEBUG ((
-      DEBUG_VERBOSE,
-      "%a: rounded UC32 base from 0x%x up to 0x%x, for "
-      "an UC32 size of 0x%x\n",
-      __FUNCTION__,
-      LowerMemorySize,
-      PlatformInfoHob->Uc32Base,
-      PlatformInfoHob->Uc32Size
-      ));
-  }
-}
-
-/**
-  Iterate over the RAM entries in QEMU's fw_cfg E820 RAM map that start outside
-  of the 32-bit address range.
-
-  Find the highest exclusive >=4GB RAM address, or produce memory resource
-  descriptor HOBs for RAM entries that start at or above 4GB.
-
-  @param[out] MaxAddress  If MaxAddress is NULL, then PlatformScanOrAdd64BitE820Ram()
-                          produces memory resource descriptor HOBs for RAM
-                          entries that start at or above 4GB.
-
-                          Otherwise, MaxAddress holds the highest exclusive
-                          >=4GB RAM address on output. If QEMU's fw_cfg E820
-                          RAM map contains no RAM entry that starts outside of
-                          the 32-bit address range, then MaxAddress is exactly
-                          4GB on output.
-
-  @retval EFI_SUCCESS         The fw_cfg E820 RAM map was found and processed.
-
-  @retval EFI_PROTOCOL_ERROR  The RAM map was found, but its size wasn't a
-                              whole multiple of sizeof(EFI_E820_ENTRY64). No
-                              RAM entry was processed.
-
-  @return                     Error codes from QemuFwCfgFindFile(). No RAM
-                              entry was processed.
-**/
-STATIC
-EFI_STATUS
-PlatformScanOrAdd64BitE820Ram (
-  IN BOOLEAN  AddHighHob,
-  OUT UINT64  *LowMemory OPTIONAL,
-  OUT UINT64  *MaxAddress OPTIONAL
-  )
-{
-  EFI_STATUS            Status;
-  FIRMWARE_CONFIG_ITEM  FwCfgItem;
-  UINTN                 FwCfgSize;
-  EFI_E820_ENTRY64      E820Entry;
-  UINTN                 Processed;
-
-  Status = QemuFwCfgFindFile ("etc/e820", &FwCfgItem, &FwCfgSize);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  if (FwCfgSize % sizeof E820Entry != 0) {
-    return EFI_PROTOCOL_ERROR;
-  }
-
-  if (LowMemory != NULL) {
-    *LowMemory = 0;
-  }
-
-  if (MaxAddress != NULL) {
-    *MaxAddress = BASE_4GB;
-  }
-
-  QemuFwCfgSelectItem (FwCfgItem);
-  for (Processed = 0; Processed < FwCfgSize; Processed += sizeof E820Entry) {
-    QemuFwCfgReadBytes (sizeof E820Entry, &E820Entry);
-    DEBUG ((
-      DEBUG_VERBOSE,
-      "%a: Base=0x%Lx Length=0x%Lx Type=%u\n",
-      __FUNCTION__,
-      E820Entry.BaseAddr,
-      E820Entry.Length,
-      E820Entry.Type
-      ));
-    if (E820Entry.Type == EfiAcpiAddressRangeMemory) {
-      if (AddHighHob && (E820Entry.BaseAddr >= BASE_4GB)) {
-        UINT64  Base;
-        UINT64  End;
-
-        //
-        // Round up the start address, and round down the end address.
-        //
-        Base = ALIGN_VALUE (E820Entry.BaseAddr, (UINT64)EFI_PAGE_SIZE);
-        End  = (E820Entry.BaseAddr + E820Entry.Length) &
-               ~(UINT64)EFI_PAGE_MASK;
-        if (Base < End) {
-          PlatformAddMemoryRangeHob (Base, End);
-          DEBUG ((
-            DEBUG_VERBOSE,
-            "%a: PlatformAddMemoryRangeHob [0x%Lx, 0x%Lx)\n",
-            __FUNCTION__,
-            Base,
-            End
-            ));
-        }
-      }
-
-      if (MaxAddress || LowMemory) {
-        UINT64  Candidate;
-
-        Candidate = E820Entry.BaseAddr + E820Entry.Length;
-        if (MaxAddress && (Candidate > *MaxAddress)) {
-          *MaxAddress = Candidate;
-          DEBUG ((
-            DEBUG_VERBOSE,
-            "%a: MaxAddress=0x%Lx\n",
-            __FUNCTION__,
-            *MaxAddress
-            ));
-        }
-
-        if (LowMemory && (Candidate > *LowMemory) && (Candidate < BASE_4GB)) {
-          *LowMemory = Candidate;
-          DEBUG ((
-            DEBUG_VERBOSE,
-            "%a: LowMemory=0x%Lx\n",
-            __FUNCTION__,
-            *LowMemory
-            ));
-        }
-      }
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Returns PVH memmap
-
-  @param Entries      Pointer to PVH memmap
-  @param Count        Number of entries
-
-  @return EFI_STATUS
-**/
-EFI_STATUS
-GetPvhMemmapEntries (
-  struct hvm_memmap_table_entry  **Entries,
-  UINT32                         *Count
-  )
-{
-  UINT32                 *PVHResetVectorData;
-  struct hvm_start_info  *pvh_start_info;
-
-  PVHResetVectorData = (VOID *)(UINTN)PcdGet32 (PcdXenPvhStartOfDayStructPtr);
-  if (PVHResetVectorData == 0) {
-    return EFI_NOT_FOUND;
-  }
-
-  pvh_start_info = (struct hvm_start_info *)(UINTN)PVHResetVectorData[0];
-
-  *Entries = (struct hvm_memmap_table_entry *)(UINTN)pvh_start_info->memmap_paddr;
-  *Count   = pvh_start_info->memmap_entries;
-
-  return EFI_SUCCESS;
-}
-
-STATIC
-UINT64
-GetHighestSystemMemoryAddressFromPvhMemmap (
-  BOOLEAN  Below4gb
-  )
-{
-  struct hvm_memmap_table_entry  *Memmap;
-  UINT32                         MemmapEntriesCount;
-  struct hvm_memmap_table_entry  *Entry;
-  EFI_STATUS                     Status;
-  UINT32                         Loop;
-  UINT64                         HighestAddress;
-  UINT64                         EntryEnd;
-
-  HighestAddress = 0;
-
-  Status = GetPvhMemmapEntries (&Memmap, &MemmapEntriesCount);
-  ASSERT_EFI_ERROR (Status);
-
-  for (Loop = 0; Loop < MemmapEntriesCount; Loop++) {
-    Entry    = Memmap + Loop;
-    EntryEnd = Entry->addr + Entry->size;
-
-    if ((Entry->type == XEN_HVM_MEMMAP_TYPE_RAM) &&
-        (EntryEnd > HighestAddress))
-    {
-      if (Below4gb && (EntryEnd <= BASE_4GB)) {
-        HighestAddress = EntryEnd;
-      } else if (!Below4gb && (EntryEnd >= BASE_4GB)) {
-        HighestAddress = EntryEnd;
-      }
-    }
-  }
-
-  return HighestAddress;
-}
-
-UINT32
-EFIAPI
-PlatformGetSystemMemorySizeBelow4gb (
-  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  EFI_STATUS  Status;
-  UINT64      LowerMemorySize = 0;
-  UINT8       Cmos0x34;
-  UINT8       Cmos0x35;
-
-  if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
-    // Get the information from PVH memmap
-    return (UINT32)GetHighestSystemMemoryAddressFromPvhMemmap (TRUE);
-  }
-
-  Status = PlatformScanOrAdd64BitE820Ram (FALSE, &LowerMemorySize, NULL);
-  if ((Status == EFI_SUCCESS) && (LowerMemorySize > 0)) {
-    return (UINT32)LowerMemorySize;
-  }
-
-  //
-  // CMOS 0x34/0x35 specifies the system memory above 16 MB.
-  // * CMOS(0x35) is the high byte
-  // * CMOS(0x34) is the low byte
-  // * The size is specified in 64kb chunks
-  // * Since this is memory above 16MB, the 16MB must be added
-  //   into the calculation to get the total memory size.
-  //
-
-  Cmos0x34 = (UINT8)PlatformCmosRead8 (0x34);
-  Cmos0x35 = (UINT8)PlatformCmosRead8 (0x35);
-
-  return (UINT32)(((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
-}
-
-STATIC
-UINT64
-PlatformGetSystemMemorySizeAbove4gb (
-  )
-{
-  UINT32  Size;
-  UINTN   CmosIndex;
-
-  //
-  // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
-  // * CMOS(0x5d) is the most significant size byte
-  // * CMOS(0x5c) is the middle size byte
-  // * CMOS(0x5b) is the least significant size byte
-  // * The size is specified in 64kb chunks
-  //
-
-  Size = 0;
-  for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
-    Size = (UINT32)(Size << 8) + (UINT32)PlatformCmosRead8 (CmosIndex);
-  }
-
-  return LShiftU64 (Size, 16);
-}
-
-/**
-  Return the highest address that DXE could possibly use, plus one.
-**/
-STATIC
-UINT64
-PlatformGetFirstNonAddress (
-  IN OUT  EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  UINT64                FirstNonAddress;
-  UINT32                FwCfgPciMmio64Mb;
-  EFI_STATUS            Status;
-  FIRMWARE_CONFIG_ITEM  FwCfgItem;
-  UINTN                 FwCfgSize;
-  UINT64                HotPlugMemoryEnd;
-
-  //
-  // set FirstNonAddress to suppress incorrect compiler/analyzer warnings
-  //
-  FirstNonAddress = 0;
-
-  //
-  // If QEMU presents an E820 map, then get the highest exclusive >=4GB RAM
-  // address from it. This can express an address >= 4GB+1TB.
-  //
-  // Otherwise, get the flat size of the memory above 4GB from the CMOS (which
-  // can only express a size smaller than 1TB), and add it to 4GB.
-  //
-  Status = PlatformScanOrAdd64BitE820Ram (FALSE, NULL, &FirstNonAddress);
-  if (EFI_ERROR (Status)) {
-    FirstNonAddress = BASE_4GB + PlatformGetSystemMemorySizeAbove4gb ();
-  }
-
-  //
-  // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO
-  // resources to 32-bit anyway. See DegradeResource() in
-  // "PciResourceSupport.c".
-  //
- #ifdef MDE_CPU_IA32
-  if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
-    return FirstNonAddress;
-  }
-
- #endif
-
-  //
-  // See if the user specified the number of megabytes for the 64-bit PCI host
-  // aperture. Accept an aperture size up to 16TB.
-  //
-  // As signaled by the "X-" prefix, this knob is experimental, and might go
-  // away at any time.
-  //
-  Status = QemuFwCfgParseUint32 (
-             "opt/ovmf/X-PciMmio64Mb",
-             FALSE,
-             &FwCfgPciMmio64Mb
-             );
-  switch (Status) {
-    case EFI_UNSUPPORTED:
-    case EFI_NOT_FOUND:
-      break;
-    case EFI_SUCCESS:
-      if (FwCfgPciMmio64Mb <= 0x1000000) {
-        PlatformInfoHob->PcdPciMmio64Size = LShiftU64 (FwCfgPciMmio64Mb, 20);
-        break;
-      }
-
-    //
-    // fall through
-    //
-    default:
-      DEBUG ((
-        DEBUG_WARN,
-        "%a: ignoring malformed 64-bit PCI host aperture size from fw_cfg\n",
-        __FUNCTION__
-        ));
-      break;
-  }
-
-  if (PlatformInfoHob->PcdPciMmio64Size == 0) {
-    if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
-      DEBUG ((
-        DEBUG_INFO,
-        "%a: disabling 64-bit PCI host aperture\n",
-        __FUNCTION__
-        ));
-    }
-
-    //
-    // There's nothing more to do; the amount of memory above 4GB fully
-    // determines the highest address plus one. The memory hotplug area (see
-    // below) plays no role for the firmware in this case.
-    //
-    return FirstNonAddress;
-  }
-
-  //
-  // The "etc/reserved-memory-end" fw_cfg file, when present, contains an
-  // absolute, exclusive end address for the memory hotplug area. This area
-  // starts right at the end of the memory above 4GB. The 64-bit PCI host
-  // aperture must be placed above it.
-  //
-  Status = QemuFwCfgFindFile (
-             "etc/reserved-memory-end",
-             &FwCfgItem,
-             &FwCfgSize
-             );
-  if (!EFI_ERROR (Status) && (FwCfgSize == sizeof HotPlugMemoryEnd)) {
-    QemuFwCfgSelectItem (FwCfgItem);
-    QemuFwCfgReadBytes (FwCfgSize, &HotPlugMemoryEnd);
-    DEBUG ((
-      DEBUG_VERBOSE,
-      "%a: HotPlugMemoryEnd=0x%Lx\n",
-      __FUNCTION__,
-      HotPlugMemoryEnd
-      ));
-
-    ASSERT (HotPlugMemoryEnd >= FirstNonAddress);
-    FirstNonAddress = HotPlugMemoryEnd;
-  }
-
-  //
-  // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so
-  // that the host can map it with 1GB hugepages. Follow suit.
-  //
-  PlatformInfoHob->PcdPciMmio64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
-  PlatformInfoHob->PcdPciMmio64Size = ALIGN_VALUE (PlatformInfoHob->PcdPciMmio64Size, (UINT64)SIZE_1GB);
-
-  //
-  // The 64-bit PCI host aperture should also be "naturally" aligned. The
-  // alignment is determined by rounding the size of the aperture down to the
-  // next smaller or equal power of two. That is, align the aperture by the
-  // largest BAR size that can fit into it.
-  //
-  PlatformInfoHob->PcdPciMmio64Base = ALIGN_VALUE (PlatformInfoHob->PcdPciMmio64Base, GetPowerOfTwo64 (PlatformInfoHob->PcdPciMmio64Size));
-
-  //
-  // The useful address space ends with the 64-bit PCI host aperture.
-  //
-  FirstNonAddress = PlatformInfoHob->PcdPciMmio64Base + PlatformInfoHob->PcdPciMmio64Size;
-  return FirstNonAddress;
-}
-
-/**
-  Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
-**/
-VOID
-EFIAPI
-PlatformAddressWidthInitialization (
-  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  UINT64  FirstNonAddress;
-  UINT8   PhysMemAddressWidth;
-
-  //
-  // As guest-physical memory size grows, the permanent PEI RAM requirements
-  // are dominated by the identity-mapping page tables built by the DXE IPL.
-  // The DXL IPL keys off of the physical address bits advertized in the CPU
-  // HOB. To conserve memory, we calculate the minimum address width here.
-  //
-  FirstNonAddress     = PlatformGetFirstNonAddress (PlatformInfoHob);
-  PhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
-
-  //
-  // If FirstNonAddress is not an integral power of two, then we need an
-  // additional bit.
-  //
-  if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
-    ++PhysMemAddressWidth;
-  }
-
-  //
-  // The minimum address width is 36 (covers up to and excluding 64 GB, which
-  // is the maximum for Ia32 + PAE). The theoretical architecture maximum for
-  // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We
-  // can simply assert that here, since 48 bits are good enough for 256 TB.
-  //
-  if (PhysMemAddressWidth <= 36) {
-    PhysMemAddressWidth = 36;
-  }
-
-  ASSERT (PhysMemAddressWidth <= 48);
-
-  PlatformInfoHob->FirstNonAddress     = FirstNonAddress;
-  PlatformInfoHob->PhysMemAddressWidth = PhysMemAddressWidth;
-}
-
 /**
   Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
 **/
@@ -842,313 +347,6 @@ PublishPeiMemory (
   return Status;
 }
 
-STATIC
-VOID
-QemuInitializeRamBelow1gb (
-  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  if (PlatformInfoHob->SmmSmramRequire && PlatformInfoHob->Q35SmramAtDefaultSmbase) {
-    PlatformAddMemoryRangeHob (0, SMM_DEFAULT_SMBASE);
-    PlatformAddReservedMemoryBaseSizeHob (
-      SMM_DEFAULT_SMBASE,
-      MCH_DEFAULT_SMBASE_SIZE,
-      TRUE /* Cacheable */
-      );
-    STATIC_ASSERT (
-      SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE < BASE_512KB + BASE_128KB,
-      "end of SMRAM at default SMBASE ends at, or exceeds, 640KB"
-      );
-    PlatformAddMemoryRangeHob (
-      SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE,
-      BASE_512KB + BASE_128KB
-      );
-  } else {
-    PlatformAddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
-  }
-}
-
-/**
-  Peform Memory Detection for QEMU / KVM
-
-**/
-STATIC
-VOID
-PlatformQemuInitializeRam (
-  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  UINT64         LowerMemorySize;
-  UINT64         UpperMemorySize;
-  MTRR_SETTINGS  MtrrSettings;
-  EFI_STATUS     Status;
-
-  DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__));
-
-  //
-  // Determine total memory size available
-  //
-  LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
-
-  if (PlatformInfoHob->BootMode == BOOT_ON_S3_RESUME) {
-    //
-    // Create the following memory HOB as an exception on the S3 boot path.
-    //
-    // Normally we'd create memory HOBs only on the normal boot path. However,
-    // CpuMpPei specifically needs such a low-memory HOB on the S3 path as
-    // well, for "borrowing" a subset of it temporarily, for the AP startup
-    // vector.
-    //
-    // CpuMpPei saves the original contents of the borrowed area in permanent
-    // PEI RAM, in a backup buffer allocated with the normal PEI services.
-    // CpuMpPei restores the original contents ("returns" the borrowed area) at
-    // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before
-    // transferring control to the OS's wakeup vector in the FACS.
-    //
-    // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to
-    // restore the original contents. Furthermore, we expect all such PEIMs
-    // (CpuMpPei included) to claim the borrowed areas by producing memory
-    // allocation HOBs, and to honor preexistent memory allocation HOBs when
-    // looking for an area to borrow.
-    //
-    QemuInitializeRamBelow1gb (PlatformInfoHob);
-  } else {
-    //
-    // Create memory HOBs
-    //
-    QemuInitializeRamBelow1gb (PlatformInfoHob);
-
-    if (PlatformInfoHob->SmmSmramRequire) {
-      UINT32  TsegSize;
-
-      TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB;
-      PlatformAddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);
-      PlatformAddReservedMemoryBaseSizeHob (
-        LowerMemorySize - TsegSize,
-        TsegSize,
-        TRUE
-        );
-    } else {
-      PlatformAddMemoryRangeHob (BASE_1MB, LowerMemorySize);
-    }
-
-    //
-    // If QEMU presents an E820 map, then create memory HOBs for the >=4GB RAM
-    // entries. Otherwise, create a single memory HOB with the flat >=4GB
-    // memory size read from the CMOS.
-    //
-    Status = PlatformScanOrAdd64BitE820Ram (TRUE, NULL, NULL);
-    if (EFI_ERROR (Status)) {
-      UpperMemorySize = PlatformGetSystemMemorySizeAbove4gb ();
-      if (UpperMemorySize != 0) {
-        PlatformAddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
-      }
-    }
-  }
-
-  //
-  // We'd like to keep the following ranges uncached:
-  // - [640 KB, 1 MB)
-  // - [LowerMemorySize, 4 GB)
-  //
-  // Everything else should be WB. Unfortunately, programming the inverse (ie.
-  // keeping the default UC, and configuring the complement set of the above as
-  // WB) is not reliable in general, because the end of the upper RAM can have
-  // practically any alignment, and we may not have enough variable MTRRs to
-  // cover it exactly.
-  //
-  if (IsMtrrSupported () && (PlatformInfoHob->HostBridgeDevId != CLOUDHV_DEVICE_ID)) {
-    MtrrGetAllMtrrs (&MtrrSettings);
-
-    //
-    // MTRRs disabled, fixed MTRRs disabled, default type is uncached
-    //
-    ASSERT ((MtrrSettings.MtrrDefType & BIT11) == 0);
-    ASSERT ((MtrrSettings.MtrrDefType & BIT10) == 0);
-    ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == 0);
-
-    //
-    // flip default type to writeback
-    //
-    SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, 0x06);
-    ZeroMem (&MtrrSettings.Variables, sizeof MtrrSettings.Variables);
-    MtrrSettings.MtrrDefType |= BIT11 | BIT10 | 6;
-    MtrrSetAllMtrrs (&MtrrSettings);
-
-    //
-    // Set memory range from 640KB to 1MB to uncacheable
-    //
-    Status = MtrrSetMemoryAttribute (
-               BASE_512KB + BASE_128KB,
-               BASE_1MB - (BASE_512KB + BASE_128KB),
-               CacheUncacheable
-               );
-    ASSERT_EFI_ERROR (Status);
-
-    //
-    // Set the memory range from the start of the 32-bit MMIO area (32-bit PCI
-    // MMIO aperture on i440fx, PCIEXBAR on q35) to 4GB as uncacheable.
-    //
-    Status = MtrrSetMemoryAttribute (
-               PlatformInfoHob->Uc32Base,
-               SIZE_4GB - PlatformInfoHob->Uc32Base,
-               CacheUncacheable
-               );
-    ASSERT_EFI_ERROR (Status);
-  }
-}
-
-STATIC
-VOID
-PlatformQemuInitializeRamForS3 (
-  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  if (PlatformInfoHob->S3Supported && (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME)) {
-    //
-    // This is the memory range that will be used for PEI on S3 resume
-    //
-    BuildMemoryAllocationHob (
-      PlatformInfoHob->S3AcpiReservedMemoryBase,
-      PlatformInfoHob->S3AcpiReservedMemorySize,
-      EfiACPIMemoryNVS
-      );
-
-    //
-    // Cover the initial RAM area used as stack and temporary PEI heap.
-    //
-    // This is reserved as ACPI NVS so it can be used on S3 resume.
-    //
-    BuildMemoryAllocationHob (
-      PcdGet32 (PcdOvmfSecPeiTempRamBase),
-      PcdGet32 (PcdOvmfSecPeiTempRamSize),
-      EfiACPIMemoryNVS
-      );
-
-    //
-    // SEC stores its table of GUIDed section handlers here.
-    //
-    BuildMemoryAllocationHob (
-      PcdGet64 (PcdGuidedExtractHandlerTableAddress),
-      PcdGet32 (PcdGuidedExtractHandlerTableSize),
-      EfiACPIMemoryNVS
-      );
-
- #ifdef MDE_CPU_X64
-    //
-    // Reserve the initial page tables built by the reset vector code.
-    //
-    // Since this memory range will be used by the Reset Vector on S3
-    // resume, it must be reserved as ACPI NVS.
-    //
-    BuildMemoryAllocationHob (
-      (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase),
-      (UINT64)(UINTN)PcdGet32 (PcdOvmfSecPageTablesSize),
-      EfiACPIMemoryNVS
-      );
-
-    if (PlatformInfoHob->SevEsIsEnabled) {
-      //
-      // If SEV-ES is enabled, reserve the GHCB-related memory area. This
-      // includes the extra page table used to break down the 2MB page
-      // mapping into 4KB page entries where the GHCB resides and the
-      // GHCB area itself.
-      //
-      // Since this memory range will be used by the Reset Vector on S3
-      // resume, it must be reserved as ACPI NVS.
-      //
-      BuildMemoryAllocationHob (
-        (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbPageTableBase),
-        (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbPageTableSize),
-        EfiACPIMemoryNVS
-        );
-      BuildMemoryAllocationHob (
-        (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbBase),
-        (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbSize),
-        EfiACPIMemoryNVS
-        );
-      BuildMemoryAllocationHob (
-        (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupBase),
-        (UINT64)(UINTN)PcdGet32 (PcdOvmfSecGhcbBackupSize),
-        EfiACPIMemoryNVS
-        );
-    }
-
- #endif
-  }
-
-  if (PlatformInfoHob->BootMode != BOOT_ON_S3_RESUME) {
-    if (!PlatformInfoHob->SmmSmramRequire) {
-      //
-      // Reserve the lock box storage area
-      //
-      // Since this memory range will be used on S3 resume, it must be
-      // reserved as ACPI NVS.
-      //
-      // If S3 is unsupported, then various drivers might still write to the
-      // LockBox area. We ought to prevent DXE from serving allocation requests
-      // such that they would overlap the LockBox storage.
-      //
-      ZeroMem (
-        (VOID *)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase),
-        (UINTN)PcdGet32 (PcdOvmfLockBoxStorageSize)
-        );
-      BuildMemoryAllocationHob (
-        (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageBase),
-        (UINT64)(UINTN)PcdGet32 (PcdOvmfLockBoxStorageSize),
-        PlatformInfoHob->S3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
-        );
-    }
-
-    if (PlatformInfoHob->SmmSmramRequire) {
-      UINT32  TsegSize;
-
-      //
-      // Make sure the TSEG area that we reported as a reserved memory resource
-      // cannot be used for reserved memory allocations.
-      //
-      TsegSize = PlatformInfoHob->Q35TsegMbytes * SIZE_1MB;
-      BuildMemoryAllocationHob (
-        PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob) - TsegSize,
-        TsegSize,
-        EfiReservedMemoryType
-        );
-      //
-      // Similarly, allocate away the (already reserved) SMRAM at the default
-      // SMBASE, if it exists.
-      //
-      if (PlatformInfoHob->Q35SmramAtDefaultSmbase) {
-        BuildMemoryAllocationHob (
-          SMM_DEFAULT_SMBASE,
-          MCH_DEFAULT_SMBASE_SIZE,
-          EfiReservedMemoryType
-          );
-      }
-    }
-
- #ifdef MDE_CPU_X64
-    if (FixedPcdGet32 (PcdOvmfWorkAreaSize) != 0) {
-      //
-      // Reserve the work area.
-      //
-      // Since this memory range will be used by the Reset Vector on S3
-      // resume, it must be reserved as ACPI NVS.
-      //
-      // If S3 is unsupported, then various drivers might still write to the
-      // work area. We ought to prevent DXE from serving allocation requests
-      // such that they would overlap the work area.
-      //
-      BuildMemoryAllocationHob (
-        (EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase),
-        (UINT64)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaSize),
-        PlatformInfoHob->S3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
-        );
-    }
-
- #endif
-  }
-}
-
 /**
   Publish system RAM and reserve memory regions
 
diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h
index 494836c3efe4..31670747d8b0 100644
--- a/OvmfPkg/PlatformPei/Platform.h
+++ b/OvmfPkg/PlatformPei/Platform.h
@@ -32,18 +32,6 @@ PublishPeiMemory (
   VOID
   );
 
-UINT32
-EFIAPI
-PlatformGetSystemMemorySizeBelow4gb (
-  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  );
-
-VOID
-EFIAPI
-PlatformQemuUc32BaseInitialization (
-  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  );
-
 VOID
 InitializeRamRegions (
   IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-- 
2.29.2.windows.2


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

* [PATCH 14/14] OvmfPkg/PlatformInitLib: Move functions to Platform.c
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (12 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 13/14] OvmfPkg/PlatformInitLib: Create MemDetect.c Min Xu
@ 2022-03-08  2:36 ` Min Xu
  2022-03-08  9:50 ` [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Boeuf, Sebastien
  2022-03-09 12:24 ` Gerd Hoffmann
  15 siblings, 0 replies; 17+ messages in thread
From: Min Xu @ 2022-03-08  2:36 UTC (permalink / raw)
  To: devel
  Cc: Min Xu, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Gerd Hoffmann,
	Sebastien Boeuf

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

Move functions in PlatformPei/Platform.c to PlatformInitLib/Platform.c.

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/Include/Library/PlatformInitLib.h  |  34 ++
 OvmfPkg/Library/PlatformInitLib/Platform.c | 465 +++++++++++++++++++++
 OvmfPkg/PlatformPei/Platform.c             | 451 --------------------
 3 files changed, 499 insertions(+), 451 deletions(-)

diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h
index 2e4bb8140368..21fc385e35eb 100644
--- a/OvmfPkg/Include/Library/PlatformInitLib.h
+++ b/OvmfPkg/Include/Library/PlatformInitLib.h
@@ -169,4 +169,38 @@ PlatformQemuInitializeRamForS3 (
   IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
   );
 
+VOID
+EFIAPI
+PlatformMemMapInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
+/**
+ * Fetch "opt/ovmf/PcdSetNxForStack" from QEMU
+ *
+ * @param Setting     The pointer to the setting of "/opt/ovmf/PcdSetNxForStack".
+ * @return EFI_SUCCESS  Successfully fetch the settings.
+ */
+EFI_STATUS
+EFIAPI
+PlatformNoexecDxeInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
+VOID
+EFIAPI
+PlatformMiscInitialization (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
+/**
+  Fetch the boot CPU count and the possible CPU count from QEMU, and expose
+  them to UefiCpuPkg modules. Set the mMaxCpuCount variable.
+**/
+VOID
+EFIAPI
+PlatformMaxCpuCountInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  );
+
 #endif // PLATFORM_INIT_LIB_H_
diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c b/OvmfPkg/Library/PlatformInitLib/Platform.c
index e41f230ff563..96bc41b1098c 100644
--- a/OvmfPkg/Library/PlatformInitLib/Platform.c
+++ b/OvmfPkg/Library/PlatformInitLib/Platform.c
@@ -19,6 +19,18 @@
 #include <Library/BaseLib.h>
 #include <Library/DebugLib.h>
 #include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <IndustryStandard/I440FxPiix4.h>
+#include <IndustryStandard/Microvm.h>
+#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/Q35MchIch9.h>
+#include <IndustryStandard/QemuCpuHotplug.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Library/QemuFwCfgS3Lib.h>
+#include <Library/QemuFwCfgSimpleParserLib.h>
+#include <Library/PciLib.h>
+#include <OvmfPlatforms.h>
+
 #include <Library/PlatformInitLib.h>
 
 VOID
@@ -104,3 +116,456 @@ PlatformAddMemoryRangeHob (
 {
   PlatformAddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
 }
+
+VOID
+EFIAPI
+PlatformMemMapInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  UINT64  PciIoBase;
+  UINT64  PciIoSize;
+  UINT32  TopOfLowRam;
+  UINT64  PciExBarBase;
+  UINT32  PciBase;
+  UINT32  PciSize;
+
+  PciIoBase = 0xC000;
+  PciIoSize = 0x4000;
+
+  //
+  // Video memory + Legacy BIOS region
+  //
+  PlatformAddIoMemoryRangeHob (0x0A0000, BASE_1MB);
+
+  if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {
+    PlatformAddIoMemoryBaseSizeHob (MICROVM_GED_MMIO_BASE, SIZE_4KB);
+    PlatformAddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); /* ioapic #1 */
+    PlatformAddIoMemoryBaseSizeHob (0xFEC10000, SIZE_4KB); /* ioapic #2 */
+    return;
+  }
+
+  TopOfLowRam  = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
+  PciExBarBase = 0;
+  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+    //
+    // The MMCONFIG area is expected to fall between the top of low RAM and
+    // the base of the 32-bit PCI host aperture.
+    //
+    PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress);
+    ASSERT (TopOfLowRam <= PciExBarBase);
+    ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);
+    PciBase = (UINT32)(PciExBarBase + SIZE_256MB);
+  } else {
+    ASSERT (TopOfLowRam <= PlatformInfoHob->Uc32Base);
+    PciBase = PlatformInfoHob->Uc32Base;
+  }
+
+  //
+  // address       purpose   size
+  // ------------  --------  -------------------------
+  // max(top, 2g)  PCI MMIO  0xFC000000 - max(top, 2g)
+  // 0xFC000000    gap                           44 MB
+  // 0xFEC00000    IO-APIC                        4 KB
+  // 0xFEC01000    gap                         1020 KB
+  // 0xFED00000    HPET                           1 KB
+  // 0xFED00400    gap                          111 KB
+  // 0xFED1C000    gap (PIIX4) / RCRB (ICH9)     16 KB
+  // 0xFED20000    gap                          896 KB
+  // 0xFEE00000    LAPIC                          1 MB
+  //
+  PciSize = 0xFC000000 - PciBase;
+  PlatformAddIoMemoryBaseSizeHob (PciBase, PciSize);
+
+  PlatformInfoHob->PcdPciMmio32Base = PciBase;
+  PlatformInfoHob->PcdPciMmio32Size = PciSize;
+
+  PlatformAddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
+  PlatformAddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
+  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+    PlatformAddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);
+    //
+    // Note: there should be an
+    //
+    //   PlatformAddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);
+    //
+    // call below, just like the one above for RCBA. However, Linux insists
+    // that the MMCONFIG area be marked in the E820 or UEFI memory map as
+    // "reserved memory" -- Linux does not content itself with a simple gap
+    // in the memory map wherever the MCFG ACPI table points to.
+    //
+    // This appears to be a safety measure. The PCI Firmware Specification
+    // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can
+    // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory
+    // [...]". (Emphasis added here.)
+    //
+    // Normally we add memory resource descriptor HOBs in
+    // QemuInitializeRam(), and pre-allocate from those with memory
+    // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area
+    // is most definitely not RAM; so, as an exception, cover it with
+    // uncacheable reserved memory right here.
+    //
+    PlatformAddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);
+    BuildMemoryAllocationHob (
+      PciExBarBase,
+      SIZE_256MB,
+      EfiReservedMemoryType
+      );
+  }
+
+  PlatformAddIoMemoryBaseSizeHob (PcdGet32 (PcdCpuLocalApicBaseAddress), SIZE_1MB);
+
+  //
+  // On Q35, the IO Port space is available for PCI resource allocations from
+  // 0x6000 up.
+  //
+  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+    PciIoBase = 0x6000;
+    PciIoSize = 0xA000;
+    ASSERT ((ICH9_PMBASE_VALUE & 0xF000) < PciIoBase);
+  }
+
+  //
+  // Add PCI IO Port space available for PCI resource allocations.
+  //
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_IO,
+    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
+    PciIoBase,
+    PciIoSize
+    );
+
+  PlatformInfoHob->PcdPciIoBase = PciIoBase;
+  PlatformInfoHob->PcdPciIoSize = PciIoSize;
+}
+
+/**
+ * Fetch "opt/ovmf/PcdSetNxForStack" from QEMU
+ *
+ * @param Setting     The pointer to the setting of "/opt/ovmf/PcdSetNxForStack".
+ * @return EFI_SUCCESS  Successfully fetch the settings.
+ */
+EFI_STATUS
+EFIAPI
+PlatformNoexecDxeInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  return QemuFwCfgParseBool ("opt/ovmf/PcdSetNxForStack", &PlatformInfoHob->PcdSetNxForStack);
+}
+
+VOID
+PciExBarInitialization (
+  VOID
+  )
+{
+  union {
+    UINT64    Uint64;
+    UINT32    Uint32[2];
+  } PciExBarBase;
+
+  //
+  // We only support the 256MB size for the MMCONFIG area:
+  // 256 buses * 32 devices * 8 functions * 4096 bytes config space.
+  //
+  // The masks used below enforce the Q35 requirements that the MMCONFIG area
+  // be (a) correctly aligned -- here at 256 MB --, (b) located under 64 GB.
+  //
+  // Note that (b) also ensures that the minimum address width we have
+  // determined in AddressWidthInitialization(), i.e., 36 bits, will suffice
+  // for DXE's page tables to cover the MMCONFIG area.
+  //
+  PciExBarBase.Uint64 = FixedPcdGet64 (PcdPciExpressBaseAddress);
+  ASSERT ((PciExBarBase.Uint32[1] & MCH_PCIEXBAR_HIGHMASK) == 0);
+  ASSERT ((PciExBarBase.Uint32[0] & MCH_PCIEXBAR_LOWMASK) == 0);
+
+  //
+  // Clear the PCIEXBAREN bit first, before programming the high register.
+  //
+  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0);
+
+  //
+  // Program the high register. Then program the low register, setting the
+  // MMCONFIG area size and enabling decoding at once.
+  //
+  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[1]);
+  PciWrite32 (
+    DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW),
+    PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN
+    );
+}
+
+VOID
+EFIAPI
+PlatformMiscInitialization (
+  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  UINTN   PmCmd;
+  UINTN   Pmba;
+  UINT32  PmbaAndVal;
+  UINT32  PmbaOrVal;
+  UINTN   AcpiCtlReg;
+  UINT8   AcpiEnBit;
+
+  //
+  // Disable A20 Mask
+  //
+  IoOr8 (0x92, BIT1);
+
+  //
+  // Build the CPU HOB with guest RAM size dependent address width and 16-bits
+  // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
+  // S3 resume as well, so we build it unconditionally.)
+  //
+  BuildCpuHob (PlatformInfoHob->PhysMemAddressWidth, 16);
+
+  //
+  // Determine platform type and save Host Bridge DID to PCD
+  //
+  switch (PlatformInfoHob->HostBridgeDevId) {
+    case INTEL_82441_DEVICE_ID:
+      PmCmd      = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
+      Pmba       = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
+      PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;
+      PmbaOrVal  = PIIX4_PMBA_VALUE;
+      AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
+      AcpiEnBit  = PIIX4_PMREGMISC_PMIOSE;
+      break;
+    case INTEL_Q35_MCH_DEVICE_ID:
+      PmCmd      = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET);
+      Pmba       = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
+      PmbaAndVal = ~(UINT32)ICH9_PMBASE_MASK;
+      PmbaOrVal  = ICH9_PMBASE_VALUE;
+      AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
+      AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
+      break;
+    case CLOUDHV_DEVICE_ID:
+      break;
+    default:
+      DEBUG ((
+        DEBUG_ERROR,
+        "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+        __FUNCTION__,
+        PlatformInfoHob->HostBridgeDevId
+        ));
+      ASSERT (FALSE);
+      return;
+  }
+
+  if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
+    DEBUG ((DEBUG_INFO, "%a: Cloud Hypervisor is done.\n", __FUNCTION__));
+    return;
+  }
+
+  //
+  // If the appropriate IOspace enable bit is set, assume the ACPI PMBA has
+  // been configured and skip the setup here. This matches the logic in
+  // AcpiTimerLibConstructor ().
+  //
+  if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {
+    //
+    // The PEI phase should be exited with fully accessibe ACPI PM IO space:
+    // 1. set PMBA
+    //
+    PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);
+
+    //
+    // 2. set PCICMD/IOSE
+    //
+    PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);
+
+    //
+    // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN)
+    //
+    PciOr8 (AcpiCtlReg, AcpiEnBit);
+  }
+
+  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+    //
+    // Set Root Complex Register Block BAR
+    //
+    PciWrite32 (
+      POWER_MGMT_REGISTER_Q35 (ICH9_RCBA),
+      ICH9_ROOT_COMPLEX_BASE | ICH9_RCBA_EN
+      );
+
+    //
+    // Set PCI Express Register Range Base Address
+    //
+    PciExBarInitialization ();
+  }
+}
+
+/**
+  Fetch the boot CPU count and the possible CPU count from QEMU, and expose
+  them to UefiCpuPkg modules. Set the mMaxCpuCount variable.
+**/
+VOID
+EFIAPI
+PlatformMaxCpuCountInitialization (
+  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
+  )
+{
+  UINT16  BootCpuCount;
+  UINT32  MaxCpuCount;
+
+  //
+  // Try to fetch the boot CPU count.
+  //
+  QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount);
+  BootCpuCount = QemuFwCfgRead16 ();
+  if (BootCpuCount == 0) {
+    //
+    // QEMU doesn't report the boot CPU count. (BootCpuCount == 0) will let
+    // MpInitLib count APs up to (PcdCpuMaxLogicalProcessorNumber - 1), or
+    // until PcdCpuApInitTimeOutInMicroSeconds elapses (whichever is reached
+    // first).
+    //
+    DEBUG ((DEBUG_WARN, "%a: boot CPU count unavailable\n", __FUNCTION__));
+    MaxCpuCount = PlatformInfoHob->DefaultMaxCpuNumber;
+  } else {
+    //
+    // We will expose BootCpuCount to MpInitLib. MpInitLib will count APs up to
+    // (BootCpuCount - 1) precisely, regardless of timeout.
+    //
+    // Now try to fetch the possible CPU count.
+    //
+    UINTN   CpuHpBase;
+    UINT32  CmdData2;
+
+    CpuHpBase = ((PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) ?
+                 ICH9_CPU_HOTPLUG_BASE : PIIX4_CPU_HOTPLUG_BASE);
+
+    //
+    // If only legacy mode is available in the CPU hotplug register block, or
+    // the register block is completely missing, then the writes below are
+    // no-ops.
+    //
+    // 1. Switch the hotplug register block to modern mode.
+    //
+    IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, 0);
+    //
+    // 2. Select a valid CPU for deterministic reading of
+    //    QEMU_CPUHP_R_CMD_DATA2.
+    //
+    //    CPU#0 is always valid; it is the always present and non-removable
+    //    BSP.
+    //
+    IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, 0);
+    //
+    // 3. Send a command after which QEMU_CPUHP_R_CMD_DATA2 is specified to
+    //    read as zero, and which does not invalidate the selector. (The
+    //    selector may change, but it must not become invalid.)
+    //
+    //    Send QEMU_CPUHP_CMD_GET_PENDING, as it will prove useful later.
+    //
+    IoWrite8 (CpuHpBase + QEMU_CPUHP_W_CMD, QEMU_CPUHP_CMD_GET_PENDING);
+    //
+    // 4. Read QEMU_CPUHP_R_CMD_DATA2.
+    //
+    //    If the register block is entirely missing, then this is an unassigned
+    //    IO read, returning all-bits-one.
+    //
+    //    If only legacy mode is available, then bit#0 stands for CPU#0 in the
+    //    "CPU present bitmap". CPU#0 is always present.
+    //
+    //    Otherwise, QEMU_CPUHP_R_CMD_DATA2 is either still reserved (returning
+    //    all-bits-zero), or it is specified to read as zero after the above
+    //    steps. Both cases confirm modern mode.
+    //
+    CmdData2 = IoRead32 (CpuHpBase + QEMU_CPUHP_R_CMD_DATA2);
+    DEBUG ((DEBUG_VERBOSE, "%a: CmdData2=0x%x\n", __FUNCTION__, CmdData2));
+    if (CmdData2 != 0) {
+      //
+      // QEMU doesn't support the modern CPU hotplug interface. Assume that the
+      // possible CPU count equals the boot CPU count (precluding hotplug).
+      //
+      DEBUG ((
+        DEBUG_WARN,
+        "%a: modern CPU hotplug interface unavailable\n",
+        __FUNCTION__
+        ));
+      MaxCpuCount = BootCpuCount;
+    } else {
+      //
+      // Grab the possible CPU count from the modern CPU hotplug interface.
+      //
+      UINT32  Present, Possible, Selected;
+
+      Present  = 0;
+      Possible = 0;
+
+      //
+      // We've sent QEMU_CPUHP_CMD_GET_PENDING last; this ensures
+      // QEMU_CPUHP_RW_CMD_DATA can now be read usefully. However,
+      // QEMU_CPUHP_CMD_GET_PENDING may have selected a CPU with actual pending
+      // hotplug events; therefore, select CPU#0 forcibly.
+      //
+      IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, Possible);
+
+      do {
+        UINT8  CpuStatus;
+
+        //
+        // Read the status of the currently selected CPU. This will help with a
+        // sanity check against "BootCpuCount".
+        //
+        CpuStatus = IoRead8 (CpuHpBase + QEMU_CPUHP_R_CPU_STAT);
+        if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) != 0) {
+          ++Present;
+        }
+
+        //
+        // Attempt to select the next CPU.
+        //
+        ++Possible;
+        IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, Possible);
+        //
+        // If the selection is successful, then the following read will return
+        // the selector (which we know is positive at this point). Otherwise,
+        // the read will return 0.
+        //
+        Selected = IoRead32 (CpuHpBase + QEMU_CPUHP_RW_CMD_DATA);
+        ASSERT (Selected == Possible || Selected == 0);
+      } while (Selected > 0);
+
+      //
+      // Sanity check: fw_cfg and the modern CPU hotplug interface should
+      // return the same boot CPU count.
+      //
+      if (BootCpuCount != Present) {
+        DEBUG ((
+          DEBUG_WARN,
+          "%a: QEMU v2.7 reset bug: BootCpuCount=%d "
+          "Present=%u\n",
+          __FUNCTION__,
+          BootCpuCount,
+          Present
+          ));
+        //
+        // The handling of QemuFwCfgItemSmpCpuCount, across CPU hotplug plus
+        // platform reset (including S3), was corrected in QEMU commit
+        // e3cadac073a9 ("pc: fix FW_CFG_NB_CPUS to account for -device added
+        // CPUs", 2016-11-16), part of release v2.8.0.
+        //
+        BootCpuCount = (UINT16)Present;
+      }
+
+      MaxCpuCount = Possible;
+    }
+  }
+
+  DEBUG ((
+    DEBUG_INFO,
+    "%a: BootCpuCount=%d MaxCpuCount=%u\n",
+    __FUNCTION__,
+    BootCpuCount,
+    MaxCpuCount
+    ));
+  ASSERT (BootCpuCount <= MaxCpuCount);
+
+  PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber  = MaxCpuCount;
+  PlatformInfoHob->PcdCpuBootLogicalProcessorNumber = BootCpuCount;
+}
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index a5ed2c0bcc99..0f81c6193e12 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -51,129 +51,6 @@ EFI_PEI_PPI_DESCRIPTOR  mPpiBootMode[] = {
   }
 };
 
-VOID
-EFIAPI
-PlatformMemMapInitialization (
-  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  UINT64  PciIoBase;
-  UINT64  PciIoSize;
-  UINT32  TopOfLowRam;
-  UINT64  PciExBarBase;
-  UINT32  PciBase;
-  UINT32  PciSize;
-
-  PciIoBase = 0xC000;
-  PciIoSize = 0x4000;
-
-  //
-  // Video memory + Legacy BIOS region
-  //
-  PlatformAddIoMemoryRangeHob (0x0A0000, BASE_1MB);
-
-  if (PlatformInfoHob->HostBridgeDevId == 0xffff /* microvm */) {
-    PlatformAddIoMemoryBaseSizeHob (MICROVM_GED_MMIO_BASE, SIZE_4KB);
-    PlatformAddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); /* ioapic #1 */
-    PlatformAddIoMemoryBaseSizeHob (0xFEC10000, SIZE_4KB); /* ioapic #2 */
-    return;
-  }
-
-  TopOfLowRam  = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
-  PciExBarBase = 0;
-  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
-    //
-    // The MMCONFIG area is expected to fall between the top of low RAM and
-    // the base of the 32-bit PCI host aperture.
-    //
-    PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress);
-    ASSERT (TopOfLowRam <= PciExBarBase);
-    ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);
-    PciBase = (UINT32)(PciExBarBase + SIZE_256MB);
-  } else {
-    ASSERT (TopOfLowRam <= PlatformInfoHob->Uc32Base);
-    PciBase = PlatformInfoHob->Uc32Base;
-  }
-
-  //
-  // address       purpose   size
-  // ------------  --------  -------------------------
-  // max(top, 2g)  PCI MMIO  0xFC000000 - max(top, 2g)
-  // 0xFC000000    gap                           44 MB
-  // 0xFEC00000    IO-APIC                        4 KB
-  // 0xFEC01000    gap                         1020 KB
-  // 0xFED00000    HPET                           1 KB
-  // 0xFED00400    gap                          111 KB
-  // 0xFED1C000    gap (PIIX4) / RCRB (ICH9)     16 KB
-  // 0xFED20000    gap                          896 KB
-  // 0xFEE00000    LAPIC                          1 MB
-  //
-  PciSize = 0xFC000000 - PciBase;
-  PlatformAddIoMemoryBaseSizeHob (PciBase, PciSize);
-
-  PlatformInfoHob->PcdPciMmio32Base = PciBase;
-  PlatformInfoHob->PcdPciMmio32Size = PciSize;
-
-  PlatformAddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
-  PlatformAddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
-  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
-    PlatformAddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);
-    //
-    // Note: there should be an
-    //
-    //   PlatformAddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);
-    //
-    // call below, just like the one above for RCBA. However, Linux insists
-    // that the MMCONFIG area be marked in the E820 or UEFI memory map as
-    // "reserved memory" -- Linux does not content itself with a simple gap
-    // in the memory map wherever the MCFG ACPI table points to.
-    //
-    // This appears to be a safety measure. The PCI Firmware Specification
-    // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can
-    // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory
-    // [...]". (Emphasis added here.)
-    //
-    // Normally we add memory resource descriptor HOBs in
-    // QemuInitializeRam(), and pre-allocate from those with memory
-    // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area
-    // is most definitely not RAM; so, as an exception, cover it with
-    // uncacheable reserved memory right here.
-    //
-    PlatformAddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);
-    BuildMemoryAllocationHob (
-      PciExBarBase,
-      SIZE_256MB,
-      EfiReservedMemoryType
-      );
-  }
-
-  PlatformAddIoMemoryBaseSizeHob (PcdGet32 (PcdCpuLocalApicBaseAddress), SIZE_1MB);
-
-  //
-  // On Q35, the IO Port space is available for PCI resource allocations from
-  // 0x6000 up.
-  //
-  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
-    PciIoBase = 0x6000;
-    PciIoSize = 0xA000;
-    ASSERT ((ICH9_PMBASE_VALUE & 0xF000) < PciIoBase);
-  }
-
-  //
-  // Add PCI IO Port space available for PCI resource allocations.
-  //
-  BuildResourceDescriptorHob (
-    EFI_RESOURCE_IO,
-    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
-    EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
-    PciIoBase,
-    PciIoSize
-    );
-
-  PlatformInfoHob->PcdPciIoBase = PciIoBase;
-  PlatformInfoHob->PcdPciIoSize = PciIoSize;
-}
-
 VOID
 MemMapInitialization (
   IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
@@ -198,21 +75,6 @@ MemMapInitialization (
   ASSERT_RETURN_ERROR (PcdStatus);
 }
 
-/**
- * Fetch "opt/ovmf/PcdSetNxForStack" from QEMU
- *
- * @param Setting     The pointer to the setting of "/opt/ovmf/PcdSetNxForStack".
- * @return EFI_SUCCESS  Successfully fetch the settings.
- */
-EFI_STATUS
-EFIAPI
-PlatformNoexecDxeInitialization (
-  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  return QemuFwCfgParseBool ("opt/ovmf/PcdSetNxForStack", &PlatformInfoHob->PcdSetNxForStack);
-}
-
 VOID
 NoexecDxeInitialization (
   VOID
@@ -227,47 +89,6 @@ NoexecDxeInitialization (
   }
 }
 
-VOID
-PciExBarInitialization (
-  VOID
-  )
-{
-  union {
-    UINT64    Uint64;
-    UINT32    Uint32[2];
-  } PciExBarBase;
-
-  //
-  // We only support the 256MB size for the MMCONFIG area:
-  // 256 buses * 32 devices * 8 functions * 4096 bytes config space.
-  //
-  // The masks used below enforce the Q35 requirements that the MMCONFIG area
-  // be (a) correctly aligned -- here at 256 MB --, (b) located under 64 GB.
-  //
-  // Note that (b) also ensures that the minimum address width we have
-  // determined in AddressWidthInitialization(), i.e., 36 bits, will suffice
-  // for DXE's page tables to cover the MMCONFIG area.
-  //
-  PciExBarBase.Uint64 = FixedPcdGet64 (PcdPciExpressBaseAddress);
-  ASSERT ((PciExBarBase.Uint32[1] & MCH_PCIEXBAR_HIGHMASK) == 0);
-  ASSERT ((PciExBarBase.Uint32[0] & MCH_PCIEXBAR_LOWMASK) == 0);
-
-  //
-  // Clear the PCIEXBAREN bit first, before programming the high register.
-  //
-  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0);
-
-  //
-  // Program the high register. Then program the low register, setting the
-  // MMCONFIG area size and enabling decoding at once.
-  //
-  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[1]);
-  PciWrite32 (
-    DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW),
-    PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN
-    );
-}
-
 static const UINT8  EmptyFdt[] = {
   0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x00, 0x48,
   0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x48,
@@ -359,107 +180,6 @@ MiscInitializationForMicrovm (
   ASSERT_RETURN_ERROR (PcdStatus);
 }
 
-VOID
-PlatformMiscInitialization (
-  IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  UINTN   PmCmd;
-  UINTN   Pmba;
-  UINT32  PmbaAndVal;
-  UINT32  PmbaOrVal;
-  UINTN   AcpiCtlReg;
-  UINT8   AcpiEnBit;
-
-  //
-  // Disable A20 Mask
-  //
-  IoOr8 (0x92, BIT1);
-
-  //
-  // Build the CPU HOB with guest RAM size dependent address width and 16-bits
-  // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
-  // S3 resume as well, so we build it unconditionally.)
-  //
-  BuildCpuHob (PlatformInfoHob->PhysMemAddressWidth, 16);
-
-  //
-  // Determine platform type and save Host Bridge DID to PCD
-  //
-  switch (PlatformInfoHob->HostBridgeDevId) {
-    case INTEL_82441_DEVICE_ID:
-      PmCmd      = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
-      Pmba       = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
-      PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;
-      PmbaOrVal  = PIIX4_PMBA_VALUE;
-      AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
-      AcpiEnBit  = PIIX4_PMREGMISC_PMIOSE;
-      break;
-    case INTEL_Q35_MCH_DEVICE_ID:
-      PmCmd      = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET);
-      Pmba       = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
-      PmbaAndVal = ~(UINT32)ICH9_PMBASE_MASK;
-      PmbaOrVal  = ICH9_PMBASE_VALUE;
-      AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
-      AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
-      break;
-    case CLOUDHV_DEVICE_ID:
-      break;
-    default:
-      DEBUG ((
-        DEBUG_ERROR,
-        "%a: Unknown Host Bridge Device ID: 0x%04x\n",
-        __FUNCTION__,
-        PlatformInfoHob->HostBridgeDevId
-        ));
-      ASSERT (FALSE);
-      return;
-  }
-
-  if (PlatformInfoHob->HostBridgeDevId == CLOUDHV_DEVICE_ID) {
-    DEBUG ((DEBUG_INFO, "%a: Cloud Hypervisor is done.\n", __FUNCTION__));
-    return;
-  }
-
-  //
-  // If the appropriate IOspace enable bit is set, assume the ACPI PMBA has
-  // been configured and skip the setup here. This matches the logic in
-  // AcpiTimerLibConstructor ().
-  //
-  if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {
-    //
-    // The PEI phase should be exited with fully accessibe ACPI PM IO space:
-    // 1. set PMBA
-    //
-    PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);
-
-    //
-    // 2. set PCICMD/IOSE
-    //
-    PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);
-
-    //
-    // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN)
-    //
-    PciOr8 (AcpiCtlReg, AcpiEnBit);
-  }
-
-  if (PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
-    //
-    // Set Root Complex Register Block BAR
-    //
-    PciWrite32 (
-      POWER_MGMT_REGISTER_Q35 (ICH9_RCBA),
-      ICH9_ROOT_COMPLEX_BASE | ICH9_RCBA_EN
-      );
-
-    //
-    // Set PCI Express Register Range Base Address
-    //
-    PciExBarInitialization ();
-  }
-}
-
 VOID
 MiscInitialization (
   IN EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
@@ -571,177 +291,6 @@ Q35BoardVerification (
   CpuDeadLoop ();
 }
 
-/**
-  Fetch the boot CPU count and the possible CPU count from QEMU, and expose
-  them to UefiCpuPkg modules. Set the mMaxCpuCount variable.
-**/
-VOID
-PlatformMaxCpuCountInitialization (
-  IN OUT EFI_HOB_PLATFORM_INFO  *PlatformInfoHob
-  )
-{
-  UINT16  BootCpuCount;
-  UINT32  MaxCpuCount;
-
-  //
-  // Try to fetch the boot CPU count.
-  //
-  QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount);
-  BootCpuCount = QemuFwCfgRead16 ();
-  if (BootCpuCount == 0) {
-    //
-    // QEMU doesn't report the boot CPU count. (BootCpuCount == 0) will let
-    // MpInitLib count APs up to (PcdCpuMaxLogicalProcessorNumber - 1), or
-    // until PcdCpuApInitTimeOutInMicroSeconds elapses (whichever is reached
-    // first).
-    //
-    DEBUG ((DEBUG_WARN, "%a: boot CPU count unavailable\n", __FUNCTION__));
-    MaxCpuCount = PlatformInfoHob->DefaultMaxCpuNumber;
-  } else {
-    //
-    // We will expose BootCpuCount to MpInitLib. MpInitLib will count APs up to
-    // (BootCpuCount - 1) precisely, regardless of timeout.
-    //
-    // Now try to fetch the possible CPU count.
-    //
-    UINTN   CpuHpBase;
-    UINT32  CmdData2;
-
-    CpuHpBase = ((PlatformInfoHob->HostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) ?
-                 ICH9_CPU_HOTPLUG_BASE : PIIX4_CPU_HOTPLUG_BASE);
-
-    //
-    // If only legacy mode is available in the CPU hotplug register block, or
-    // the register block is completely missing, then the writes below are
-    // no-ops.
-    //
-    // 1. Switch the hotplug register block to modern mode.
-    //
-    IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, 0);
-    //
-    // 2. Select a valid CPU for deterministic reading of
-    //    QEMU_CPUHP_R_CMD_DATA2.
-    //
-    //    CPU#0 is always valid; it is the always present and non-removable
-    //    BSP.
-    //
-    IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, 0);
-    //
-    // 3. Send a command after which QEMU_CPUHP_R_CMD_DATA2 is specified to
-    //    read as zero, and which does not invalidate the selector. (The
-    //    selector may change, but it must not become invalid.)
-    //
-    //    Send QEMU_CPUHP_CMD_GET_PENDING, as it will prove useful later.
-    //
-    IoWrite8 (CpuHpBase + QEMU_CPUHP_W_CMD, QEMU_CPUHP_CMD_GET_PENDING);
-    //
-    // 4. Read QEMU_CPUHP_R_CMD_DATA2.
-    //
-    //    If the register block is entirely missing, then this is an unassigned
-    //    IO read, returning all-bits-one.
-    //
-    //    If only legacy mode is available, then bit#0 stands for CPU#0 in the
-    //    "CPU present bitmap". CPU#0 is always present.
-    //
-    //    Otherwise, QEMU_CPUHP_R_CMD_DATA2 is either still reserved (returning
-    //    all-bits-zero), or it is specified to read as zero after the above
-    //    steps. Both cases confirm modern mode.
-    //
-    CmdData2 = IoRead32 (CpuHpBase + QEMU_CPUHP_R_CMD_DATA2);
-    DEBUG ((DEBUG_VERBOSE, "%a: CmdData2=0x%x\n", __FUNCTION__, CmdData2));
-    if (CmdData2 != 0) {
-      //
-      // QEMU doesn't support the modern CPU hotplug interface. Assume that the
-      // possible CPU count equals the boot CPU count (precluding hotplug).
-      //
-      DEBUG ((
-        DEBUG_WARN,
-        "%a: modern CPU hotplug interface unavailable\n",
-        __FUNCTION__
-        ));
-      MaxCpuCount = BootCpuCount;
-    } else {
-      //
-      // Grab the possible CPU count from the modern CPU hotplug interface.
-      //
-      UINT32  Present, Possible, Selected;
-
-      Present  = 0;
-      Possible = 0;
-
-      //
-      // We've sent QEMU_CPUHP_CMD_GET_PENDING last; this ensures
-      // QEMU_CPUHP_RW_CMD_DATA can now be read usefully. However,
-      // QEMU_CPUHP_CMD_GET_PENDING may have selected a CPU with actual pending
-      // hotplug events; therefore, select CPU#0 forcibly.
-      //
-      IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, Possible);
-
-      do {
-        UINT8  CpuStatus;
-
-        //
-        // Read the status of the currently selected CPU. This will help with a
-        // sanity check against "BootCpuCount".
-        //
-        CpuStatus = IoRead8 (CpuHpBase + QEMU_CPUHP_R_CPU_STAT);
-        if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) != 0) {
-          ++Present;
-        }
-
-        //
-        // Attempt to select the next CPU.
-        //
-        ++Possible;
-        IoWrite32 (CpuHpBase + QEMU_CPUHP_W_CPU_SEL, Possible);
-        //
-        // If the selection is successful, then the following read will return
-        // the selector (which we know is positive at this point). Otherwise,
-        // the read will return 0.
-        //
-        Selected = IoRead32 (CpuHpBase + QEMU_CPUHP_RW_CMD_DATA);
-        ASSERT (Selected == Possible || Selected == 0);
-      } while (Selected > 0);
-
-      //
-      // Sanity check: fw_cfg and the modern CPU hotplug interface should
-      // return the same boot CPU count.
-      //
-      if (BootCpuCount != Present) {
-        DEBUG ((
-          DEBUG_WARN,
-          "%a: QEMU v2.7 reset bug: BootCpuCount=%d "
-          "Present=%u\n",
-          __FUNCTION__,
-          BootCpuCount,
-          Present
-          ));
-        //
-        // The handling of QemuFwCfgItemSmpCpuCount, across CPU hotplug plus
-        // platform reset (including S3), was corrected in QEMU commit
-        // e3cadac073a9 ("pc: fix FW_CFG_NB_CPUS to account for -device added
-        // CPUs", 2016-11-16), part of release v2.8.0.
-        //
-        BootCpuCount = (UINT16)Present;
-      }
-
-      MaxCpuCount = Possible;
-    }
-  }
-
-  DEBUG ((
-    DEBUG_INFO,
-    "%a: BootCpuCount=%d MaxCpuCount=%u\n",
-    __FUNCTION__,
-    BootCpuCount,
-    MaxCpuCount
-    ));
-  ASSERT (BootCpuCount <= MaxCpuCount);
-
-  PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber  = MaxCpuCount;
-  PlatformInfoHob->PcdCpuBootLogicalProcessorNumber = BootCpuCount;
-}
-
 /**
   Fetch the boot CPU count and the possible CPU count from QEMU, and expose
   them to UefiCpuPkg modules. Set the mMaxCpuCount variable.
-- 
2.29.2.windows.2


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

* Re: [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (13 preceding siblings ...)
  2022-03-08  2:36 ` [PATCH 14/14] OvmfPkg/PlatformInitLib: Move functions to Platform.c Min Xu
@ 2022-03-08  9:50 ` Boeuf, Sebastien
  2022-03-09 12:24 ` Gerd Hoffmann
  15 siblings, 0 replies; 17+ messages in thread
From: Boeuf, Sebastien @ 2022-03-08  9:50 UTC (permalink / raw)
  To: devel@edk2.groups.io, Xu, Min M
  Cc: jejb@linux.ibm.com, kraxel@redhat.com, Yao, Jiewen,
	Justen, Jordan L, thomas.lendacky@amd.com, Aktas, Erdem,
	brijesh.singh@amd.com, ardb+tianocore@kernel.org

The series looks good to me, and I've tested your branch by building
CLOUDHV.fd and running it with Cloud Hypervisor, nothing's broken :)

Acked-by: Sebastien Boeuf <sebastien.boeuf@intel.com>

On Tue, 2022-03-08 at 10:36 +0800, Min Xu wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863
> 
> There are 3 variants of PlatformPei in OvmfPkg:
>  - OvmfPkg/PlatformPei
>  - OvmfPkg/Bhyve/PlatformPei
>  - OvmfPkg/XenPlatformPei
> 
> A lot of common code can be shared in above PlatformPeis. Further more,
> with the upstreaming of TDVF (Pei-less boot mode), a library which
> wraps the common functions is needed. PlatformInitLib is designed
> to meet this requirement.
> 
> PlatformInitLib is designed to run in both PEI and SEC. So global
> variables and dynamic PCDs are avoided.
> 
> As the first stage, OvmfPkg/PlatformPei will be refactored with
> PlatformInitLib. In the future we will refactor other PlatformPeis
> with this lib as well.
> 
> Patch 1 - 2: 
> Create initial version of PlatformInitLib and move Cmos / Hob functions
> to the lib.
> 
> Patch 3:
> Move global variables in PlatformPei to PlatformInfoHob. Changes are
> all in OvmfPkg/PlatformPei.
> 
> Patch 4 - 12:
> These patches restruct the functions which set PCDs into two, one for
> PlatformInitLib, one for PlatformPei.
> 
> Patch 13 - 14:
> Pure move from PlatformPei to PlatformInitLib.
> 
> Code at: https://github.com/mxu9/edk2/tree/platform-init-lib-v1
> 
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Brijesh Singh <brijesh.singh@amd.com>
> Cc: Erdem Aktas <erdemaktas@google.com>
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
> Signed-off-by: Min Xu <min.m.xu@intel.com>
> 
> Min Xu (14):
>   OvmfPkg: Create initial version of PlatformInitLib
>   OvmfPkg/PlatformInitLib: Add hob functions
>   OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob
>   OvmfPkg/PlatformPei: Refactor MiscInitialization
>   OvmfPkg/PlatformPei: Refactor MiscInitialization for CloudHV
>   OvmfPkg/PlatformPei: Refactor AddressWidthInitialization
>   OvmfPkg/PlatformPei: Refactor MaxCpuCountInitialization
>   OvmfPkg/PlatformPei: Refactor QemuUc32BaseInitialization
>   OvmfPkg/PlatformPei: Refactor InitializeRamRegions
>   OvmfPkg/PlatformPei: Refactor MemMapInitialization
>   OvmfPkg/PlatformPei: Refactor NoexecDxeInitialization
>   OvmfPkg/PlatformPei: Refactor MiscInitialization
>   OvmfPkg/PlatformInitLib: Create MemDetect.c
>   OvmfPkg/PlatformInitLib: Move functions to Platform.c
> 
>  OvmfPkg/AmdSev/AmdSevX64.dsc                  |   1 +
>  OvmfPkg/CloudHv/CloudHvX64.dsc                |   1 +
>  OvmfPkg/Include/Library/PlatformInitLib.h     | 206 +++++
>  .../PlatformInitLib}/Cmos.c                   |  32 +-
>  OvmfPkg/Library/PlatformInitLib/MemDetect.c   | 842 +++++++++++++++++
>  OvmfPkg/Library/PlatformInitLib/Platform.c    | 571 ++++++++++++
>  .../PlatformInitLib/PlatformInitLib.inf       |  87 ++
>  OvmfPkg/Microvm/MicrovmX64.dsc                |   1 +
>  OvmfPkg/OvmfPkg.dec                           |   4 +
>  OvmfPkg/OvmfPkgIa32.dsc                       |   1 +
>  OvmfPkg/OvmfPkgIa32X64.dsc                    |   1 +
>  OvmfPkg/OvmfPkgX64.dsc                        |   1 +
>  OvmfPkg/PlatformPei/AmdSev.c                  |  10 +-
>  OvmfPkg/PlatformPei/Cmos.h                    |  48 -
>  OvmfPkg/PlatformPei/Fv.c                      |   6 +-
>  OvmfPkg/PlatformPei/MemDetect.c               | 874 ++----------------
>  OvmfPkg/PlatformPei/MemTypeInfo.c             |   4 +-
>  OvmfPkg/PlatformPei/Platform.c                | 616 ++----------
>  OvmfPkg/PlatformPei/Platform.h                |  80 +-
>  OvmfPkg/PlatformPei/PlatformPei.inf           |   3 +-
>  20 files changed, 1912 insertions(+), 1477 deletions(-)
>  create mode 100644 OvmfPkg/Include/Library/PlatformInitLib.h
>  rename OvmfPkg/{PlatformPei => Library/PlatformInitLib}/Cmos.c (61%)
>  create mode 100644 OvmfPkg/Library/PlatformInitLib/MemDetect.c
>  create mode 100644 OvmfPkg/Library/PlatformInitLib/Platform.c
>  create mode 100644 OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
>  delete mode 100644 OvmfPkg/PlatformPei/Cmos.h
> 

---------------------------------------------------------------------
Intel Corporation SAS (French simplified joint stock company)
Registered headquarters: "Les Montalets"- 2, rue de Paris, 
92196 Meudon Cedex, France
Registration Number:  302 456 199 R.C.S. NANTERRE
Capital: 4,572,000 Euros

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.

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

* Re: [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg
  2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
                   ` (14 preceding siblings ...)
  2022-03-08  9:50 ` [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Boeuf, Sebastien
@ 2022-03-09 12:24 ` Gerd Hoffmann
  15 siblings, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2022-03-09 12:24 UTC (permalink / raw)
  To: Min Xu
  Cc: devel, Ard Biesheuvel, Jordan Justen, Brijesh Singh, Erdem Aktas,
	James Bottomley, Jiewen Yao, Tom Lendacky, Sebastien Boeuf

On Tue, Mar 08, 2022 at 10:36:01AM +0800, Min Xu wrote:
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863
> 
> There are 3 variants of PlatformPei in OvmfPkg:
>  - OvmfPkg/PlatformPei
>  - OvmfPkg/Bhyve/PlatformPei
>  - OvmfPkg/XenPlatformPei
> 
> A lot of common code can be shared in above PlatformPeis. Further more,
> with the upstreaming of TDVF (Pei-less boot mode), a library which
> wraps the common functions is needed. PlatformInitLib is designed
> to meet this requirement.
> 
> PlatformInitLib is designed to run in both PEI and SEC. So global
> variables and dynamic PCDs are avoided.
> 
> As the first stage, OvmfPkg/PlatformPei will be refactored with
> PlatformInitLib. In the future we will refactor other PlatformPeis
> with this lib as well.
> 
> Patch 1 - 2: 
> Create initial version of PlatformInitLib and move Cmos / Hob functions
> to the lib.
> 
> Patch 3:
> Move global variables in PlatformPei to PlatformInfoHob. Changes are
> all in OvmfPkg/PlatformPei.
> 
> Patch 4 - 12:
> These patches restruct the functions which set PCDs into two, one for
> PlatformInitLib, one for PlatformPei.
> 
> Patch 13 - 14:
> Pure move from PlatformPei to PlatformInitLib.
> 
> Code at: https://github.com/mxu9/edk2/tree/platform-init-lib-v1

Looks all sane to me, also survived a smoke test with pc + q35 +
microvm.

Acked-by: Gerd Hoffmann <kraxel@redhat.com>

take care,
  Gerd


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

end of thread, other threads:[~2022-03-09 12:25 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-08  2:36 [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Min Xu
2022-03-08  2:36 ` [PATCH 01/14] OvmfPkg: Create initial version of PlatformInitLib Min Xu
2022-03-08  2:36 ` [PATCH 02/14] OvmfPkg/PlatformInitLib: Add hob functions Min Xu
2022-03-08  2:36 ` [PATCH 03/14] OvmfPkg/PlatformPei: Move global variables to PlatformInfoHob Min Xu
2022-03-08  2:36 ` [PATCH 04/14] OvmfPkg/PlatformPei: Refactor MiscInitialization Min Xu
2022-03-08  2:36 ` [PATCH 05/14] OvmfPkg/PlatformPei: Refactor MiscInitialization for CloudHV Min Xu
2022-03-08  2:36 ` [PATCH 06/14] OvmfPkg/PlatformPei: Refactor AddressWidthInitialization Min Xu
2022-03-08  2:36 ` [PATCH 07/14] OvmfPkg/PlatformPei: Refactor MaxCpuCountInitialization Min Xu
2022-03-08  2:36 ` [PATCH 08/14] OvmfPkg/PlatformPei: Refactor QemuUc32BaseInitialization Min Xu
2022-03-08  2:36 ` [PATCH 09/14] OvmfPkg/PlatformPei: Refactor InitializeRamRegions Min Xu
2022-03-08  2:36 ` [PATCH 10/14] OvmfPkg/PlatformPei: Refactor MemMapInitialization Min Xu
2022-03-08  2:36 ` [PATCH 11/14] OvmfPkg/PlatformPei: Refactor NoexecDxeInitialization Min Xu
2022-03-08  2:36 ` [PATCH 12/14] OvmfPkg/PlatformPei: Refactor MiscInitialization Min Xu
2022-03-08  2:36 ` [PATCH 13/14] OvmfPkg/PlatformInitLib: Create MemDetect.c Min Xu
2022-03-08  2:36 ` [PATCH 14/14] OvmfPkg/PlatformInitLib: Move functions to Platform.c Min Xu
2022-03-08  9:50 ` [PATCH 00/14] Introduce PlatformInitLib in OvmfPkg Boeuf, Sebastien
2022-03-09 12:24 ` Gerd Hoffmann

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