summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/PlatformPei/Platform.c
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2016-11-24 15:18:44 +0100
committerLaszlo Ersek <lersek@redhat.com>2016-11-29 10:05:54 +0100
commit45a70db3c3a59b64e0f517870415963fbfacf507 (patch)
tree4ae301a45d01c74e558c21958dfffcde8f14c820 /OvmfPkg/PlatformPei/Platform.c
parent6e1987f19af720aa9991f3f9994370383f43222d (diff)
downloadedk2-45a70db3c3a59b64e0f517870415963fbfacf507.tar.gz
edk2-45a70db3c3a59b64e0f517870415963fbfacf507.tar.bz2
edk2-45a70db3c3a59b64e0f517870415963fbfacf507.zip
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>
Diffstat (limited to 'OvmfPkg/PlatformPei/Platform.c')
-rw-r--r--OvmfPkg/PlatformPei/Platform.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index c6e1106c9e..0be86722e5 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -68,6 +68,7 @@ EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
BOOLEAN mS3Supported = FALSE;
+UINT32 mMaxCpuCount;
VOID
AddIoMemoryBaseSizeHob (
@@ -568,6 +569,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.
@param FileHandle Handle of the file being invoked.
@@ -601,6 +643,7 @@ InitializePlatform (
S3Verification ();
BootModeInitialization ();
AddressWidthInitialization ();
+ MaxCpuCountInitialization ();
PublishPeiMemory ();