gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE\r
gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable|FALSE\r
\r
+ # UefiCpuPkg PCDs related to initial AP bringup and general AP management.\r
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64\r
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000\r
+\r
################################################################################\r
#\r
# Components Section - list of all EDK II Modules needed by this Platform.\r
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE\r
gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable|FALSE\r
\r
+ # UefiCpuPkg PCDs related to initial AP bringup and general AP management.\r
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64\r
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000\r
+\r
################################################################################\r
#\r
# Components Section - list of all EDK II Modules needed by this Platform.\r
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE\r
gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable|FALSE\r
\r
+ # UefiCpuPkg PCDs related to initial AP bringup and general AP management.\r
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64\r
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000\r
+\r
################################################################################\r
#\r
# Components Section - list of all EDK II Modules needed by this Platform.\r
\r
BOOLEAN mS3Supported = FALSE;\r
\r
+UINT32 mMaxCpuCount;\r
\r
VOID\r
AddIoMemoryBaseSizeHob (\r
}\r
\r
\r
+/**\r
+ Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg modules.\r
+ Set the mMaxCpuCount variable.\r
+**/\r
+VOID\r
+MaxCpuCountInitialization (\r
+ VOID\r
+ )\r
+{\r
+ UINT16 ProcessorCount;\r
+ RETURN_STATUS PcdStatus;\r
+\r
+ QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount);\r
+ ProcessorCount = QemuFwCfgRead16 ();\r
+ //\r
+ // If the fw_cfg key or fw_cfg entirely is unavailable, load mMaxCpuCount\r
+ // from the PCD default. No change to PCDs.\r
+ //\r
+ if (ProcessorCount == 0) {\r
+ mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);\r
+ return;\r
+ }\r
+ //\r
+ // Otherwise, set mMaxCpuCount to the value reported by QEMU.\r
+ //\r
+ mMaxCpuCount = ProcessorCount;\r
+ //\r
+ // Additionally, tell UefiCpuPkg modules (a) the exact number of VCPUs, (b)\r
+ // to wait, in the initial AP bringup, exactly as long as it takes for all of\r
+ // the APs to report in. For this, we set the longest representable timeout\r
+ // (approx. 71 minutes).\r
+ //\r
+ PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, ProcessorCount);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
+ PcdStatus = PcdSet32S (PcdCpuApInitTimeOutInMicroSeconds, MAX_UINT32);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
+ DEBUG ((DEBUG_INFO, "%a: QEMU reports %d processor(s)\n", __FUNCTION__,\r
+ ProcessorCount));\r
+}\r
+\r
+\r
/**\r
Perform Platform PEI initialization.\r
\r
S3Verification ();\r
BootModeInitialization ();\r
AddressWidthInitialization ();\r
+ MaxCpuCountInitialization ();\r
\r
PublishPeiMemory ();\r
\r