If timeout expires before AP returns from Procedure, the AP should be terminated, we introduce ResetApStackLess() to send init IPI to let AP exit Procedurce and re-available.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com> --- UefiCpuPkg/CpuDxe/ApStartup.c | 19 ++++++++++++++++++- UefiCpuPkg/CpuDxe/CpuMp.c | 36 +++++++++++++++++++++++++++++++----- UefiCpuPkg/CpuDxe/CpuMp.h | 15 +++++++++++++++ 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/UefiCpuPkg/CpuDxe/ApStartup.c b/UefiCpuPkg/CpuDxe/ApStartup.c index f985a5c..860b7c3 100644 --- a/UefiCpuPkg/CpuDxe/ApStartup.c +++ b/UefiCpuPkg/CpuDxe/ApStartup.c @@ -203,7 +203,7 @@ FreeApStartupCode ( ) { if (StartupCode != NULL) { - gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(VOID *) StartupCode, + gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)(VOID*) StartupCode, EFI_SIZE_TO_PAGES (sizeof (*StartupCode))); } } @@ -233,3 +233,20 @@ StartApsStackless ( return EFI_SUCCESS; } +/** + Resets the Application Processor and directs it to jump to the + specified routine. + + The processor jumps to this code in flat mode, but the processor's + stack is not initialized. + + @param ProcessorId the AP of ProcessorId was reset +**/ +VOID +ResetApStackless ( + IN UINT32 ProcessorId + ) +{ + SendInitSipiSipi (ProcessorId, + (UINT32)(UINTN)(VOID*) StartupCode); +} diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c index 428ea9e..96513e8 100644 --- a/UefiCpuPkg/CpuDxe/CpuMp.c +++ b/UefiCpuPkg/CpuDxe/CpuMp.c @@ -25,6 +25,7 @@ VOID *mCommonStack = 0; VOID *mTopOfApCommonStack = 0; VOID *mApStackStart = 0; +BOOLEAN mAPsAlreadyInitFinished = FALSE; volatile BOOLEAN mStopCheckAllAPsStatus = TRUE; EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = { @@ -1112,6 +1113,7 @@ ResetProcessorToIdleState ( IN CPU_DATA_BLOCK *CpuData ) { + ResetApStackless(CpuData->Info.ProcessorId); } /** @@ -1138,6 +1140,14 @@ ProcessorToIdleState ( AsmApDoneWithCommonStack (); + // + // Avoid forcibly reset AP caused the AP State is not updated. + // + GetMpSpinLock (CpuData); + CpuData->State = CpuStateIdle; + CpuData->Procedure = NULL; + ReleaseMpSpinLock (CpuData); + while (TRUE) { GetMpSpinLock (CpuData); ProcedureArgument = CpuData->Parameter; @@ -1319,13 +1329,27 @@ ApEntryPointInC ( VOID ) { - VOID* TopOfApStack; + VOID* TopOfApStack; + UINTN ProcessorNumber; - FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors); - TopOfApStack = (UINT8*)mApStackStart + gApStackSize; - mApStackStart = TopOfApStack; + if (!mAPsAlreadyInitFinished) { + FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors); + TopOfApStack = (UINT8*)mApStackStart + gApStackSize; + mApStackStart = TopOfApStack; - mMpSystemData.NumberOfProcessors++; + // + // Store the Stack address, when reset the AP, We can found the original address. + // + mMpSystemData.CpuDatas[mMpSystemData.NumberOfProcessors].TopOfStack = TopOfApStack; + mMpSystemData.NumberOfProcessors++; + mMpSystemData.NumberOfEnabledProcessors++; + } else { + WhoAmI (&mMpServicesTemplate, &ProcessorNumber); + // + // Get the original stack address. + // + TopOfApStack = mMpSystemData.CpuDatas[ProcessorNumber].TopOfStack; + } SwitchStack ( (SWITCH_STACK_ENTRY_POINT)(UINTN)ProcessorToIdleState, @@ -1462,6 +1486,8 @@ InitializeMpSupport ( return; } + mAPsAlreadyInitFinished = TRUE; + if (mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) { FreePages (mApStackStart, EFI_SIZE_TO_PAGES ( (gMaxLogicalProcessorNumber - mMpSystemData.NumberOfProcessors) * diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h index 40fda72..2533f4e 100644 --- a/UefiCpuPkg/CpuDxe/CpuMp.h +++ b/UefiCpuPkg/CpuDxe/CpuMp.h @@ -99,6 +99,7 @@ typedef struct { EFI_EVENT WaitEvent; BOOLEAN TimeoutActive; EFI_EVENT CheckThisAPEvent; + VOID *TopOfStack; } CPU_DATA_BLOCK; /** @@ -622,5 +623,19 @@ FreeApStartupCode ( VOID ); +/** + Resets the Application Processor and directs it to jump to the + specified routine. + + The processor jumps to this code in flat mode, but the processor's + stack is not initialized. + + @param ProcessorId the AP of ProcessorId was reset +**/ +VOID +ResetApStackless ( + IN UINT32 ProcessorId + ); + #endif // _CPU_MP_H_ -- 1.9.3 ------------------------------------------------------------------------------ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel