From ac9dbb3b03313c7426c5bb15663b20b57ca771ce Mon Sep 17 00:00:00 2001 From: Chen Fan Date: Thu, 13 Nov 2014 18:29:13 +0000 Subject: UefiCpuPkg/CpuDxe: introduce ResetApStackless() 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 Reviewed-by: Jeff Fan git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16366 6f19259b-4bc3-4df7-8a09-765794883524 --- UefiCpuPkg/CpuDxe/ApStartup.c | 17 +++++++++++++++++ UefiCpuPkg/CpuDxe/CpuMp.c | 36 +++++++++++++++++++++++++++++++----- UefiCpuPkg/CpuDxe/CpuMp.h | 15 +++++++++++++++ 3 files changed, 63 insertions(+), 5 deletions(-) (limited to 'UefiCpuPkg') diff --git a/UefiCpuPkg/CpuDxe/ApStartup.c b/UefiCpuPkg/CpuDxe/ApStartup.c index 801f7f8611..7613b47942 100644 --- a/UefiCpuPkg/CpuDxe/ApStartup.c +++ b/UefiCpuPkg/CpuDxe/ApStartup.c @@ -328,3 +328,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 029e8d4331..13fcda5859 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 ((UINT32)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 2b1717d410..4254419a93 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_ -- cgit v1.2.3