Since the CpuDxe has a fixed maximum number of APs that are controlled with PcdCpuMaxLogicalProcessorNumber, if the maximum number of APs are awake, then the BSP should be able to continue.
Since the APs may be updating the mMpSystemData.NumberOfProcessors during this early init phase, we use SynchronizationLib to update this variable on the AP and to read it on the BSP. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jordan Justen <jordan.l.jus...@intel.com> Cc: Jeff Fan <jeff....@intel.com> Cc: Laszlo Ersek <ler...@redhat.com> --- UefiCpuPkg/CpuDxe/CpuMp.c | 15 ++++++++++++--- UefiCpuPkg/CpuDxe/CpuMp.h | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c index 6a22b9d..1094292 100644 --- a/UefiCpuPkg/CpuDxe/CpuMp.c +++ b/UefiCpuPkg/CpuDxe/CpuMp.c @@ -1474,7 +1474,7 @@ ApEntryPointInC ( // Store the Stack address, when reset the AP, We can found the original address. // mMpSystemData.CpuDatas[mMpSystemData.NumberOfProcessors].TopOfStack = TopOfApStack; - mMpSystemData.NumberOfProcessors++; + InterlockedIncrement (&mMpSystemData.NumberOfProcessors); mMpSystemData.NumberOfEnabledProcessors++; } else { Status = WhoAmI (&mMpServicesTemplate, &ProcessorNumber); @@ -1749,9 +1749,18 @@ InitializeMpSupport ( StartApsStackless (); // - // Wait for APs to arrive at the ApEntryPoint routine + // Wait for all APs to start // - MicroSecondDelay (PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds)); + Timeout = 0; + do { + if (InterlockedCompareExchange32 ( + &mMpSystemData.NumberOfProcessors, 0, 0) >= + gMaxLogicalProcessorNumber) { + break; + } + MicroSecondDelay (gPollInterval); + Timeout += gPollInterval; + } while (Timeout <= PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds)); } DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", mMpSystemData.NumberOfProcessors)); diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h index 503f3ae..ab7a7f5 100644 --- a/UefiCpuPkg/CpuDxe/CpuMp.h +++ b/UefiCpuPkg/CpuDxe/CpuMp.h @@ -114,7 +114,7 @@ typedef struct { **/ typedef struct { CPU_DATA_BLOCK *CpuDatas; - UINTN NumberOfProcessors; + UINT32 NumberOfProcessors; UINTN NumberOfEnabledProcessors; EFI_AP_PROCEDURE Procedure; -- 2.5.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel