OvmfPkg/PlatformPei: take VCPU count from QEMU and configure MpInitLib

These settings will allow CpuMpPei and CpuDxe to wait for the initial AP
check-ins exactly as long as necessary.

It is safe to set PcdCpuMaxLogicalProcessorNumber and
PcdCpuApInitTimeOutInMicroSeconds in OvmfPkg/PlatformPei.
OvmfPkg/PlatformPei installs the permanent PEI RAM, producing
gEfiPeiMemoryDiscoveredPpiGuid, and UefiCpuPkg/CpuMpPei has a depex on
gEfiPeiMemoryDiscoveredPpiGuid.

It is safe to read the fw_cfg item QemuFwCfgItemSmpCpuCount (0x0005). It
was added to QEMU in 2008 as key FW_CFG_NB_CPUS, in commit 905fdcb5264c
("Add common keys to firmware configuration"). Even if the key is
unavailable (or if fw_cfg is entirely unavailable, for example on Xen),
QemuFwCfgRead16() will return 0, and then we stick with the current
behavior.

Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Laszlo Ersek 2016-11-24 15:18:44 +01:00
parent 6e1987f19a
commit 45a70db3c3
7 changed files with 59 additions and 1 deletions

View File

@ -488,6 +488,10 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable|FALSE
# UefiCpuPkg PCDs related to initial AP bringup and general AP management.
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.

View File

@ -496,6 +496,10 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable|FALSE
# UefiCpuPkg PCDs related to initial AP bringup and general AP management.
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.

View File

@ -495,6 +495,10 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable|FALSE
# UefiCpuPkg PCDs related to initial AP bringup and general AP management.
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform.

View File

@ -358,7 +358,7 @@ PublishPeiMemory (
//
if (mS3Supported) {
mS3AcpiReservedMemorySize = SIZE_512KB +
PcdGet32 (PcdCpuMaxLogicalProcessorNumber) *
mMaxCpuCount *
PcdGet32 (PcdCpuApStackSize);
mS3AcpiReservedMemoryBase = LowerMemorySize - mS3AcpiReservedMemorySize;
LowerMemorySize = mS3AcpiReservedMemoryBase;

View File

@ -68,6 +68,7 @@ EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
BOOLEAN mS3Supported = FALSE;
UINT32 mMaxCpuCount;
VOID
AddIoMemoryBaseSizeHob (
@ -567,6 +568,47 @@ S3Verification (
}
/**
Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg modules.
Set the mMaxCpuCount variable.
**/
VOID
MaxCpuCountInitialization (
VOID
)
{
UINT16 ProcessorCount;
RETURN_STATUS PcdStatus;
QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount);
ProcessorCount = QemuFwCfgRead16 ();
//
// If the fw_cfg key or fw_cfg entirely is unavailable, load mMaxCpuCount
// from the PCD default. No change to PCDs.
//
if (ProcessorCount == 0) {
mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
return;
}
//
// Otherwise, set mMaxCpuCount to the value reported by QEMU.
//
mMaxCpuCount = ProcessorCount;
//
// Additionally, tell UefiCpuPkg modules (a) the exact number of VCPUs, (b)
// to wait, in the initial AP bringup, exactly as long as it takes for all of
// the APs to report in. For this, we set the longest representable timeout
// (approx. 71 minutes).
//
PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, ProcessorCount);
ASSERT_RETURN_ERROR (PcdStatus);
PcdStatus = PcdSet32S (PcdCpuApInitTimeOutInMicroSeconds, MAX_UINT32);
ASSERT_RETURN_ERROR (PcdStatus);
DEBUG ((DEBUG_INFO, "%a: QEMU reports %d processor(s)\n", __FUNCTION__,
ProcessorCount));
}
/**
Perform Platform PEI initialization.
@ -601,6 +643,7 @@ InitializePlatform (
S3Verification ();
BootModeInitialization ();
AddressWidthInitialization ();
MaxCpuCountInitialization ();
PublishPeiMemory ();

View File

@ -101,4 +101,6 @@ extern BOOLEAN mS3Supported;
extern UINT8 mPhysMemAddressWidth;
extern UINT32 mMaxCpuCount;
#endif // _PLATFORM_PEI_H_INCLUDED_

View File

@ -95,6 +95,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable
gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
[FixedPcd]