* [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