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 <[email protected]>
---
 UefiCpuPkg/CpuDxe/ApStartup.c | 19 ++++++++++++++++++-
 UefiCpuPkg/CpuDxe/CpuMp.c     | 34 +++++++++++++++++++++++++++++-----
 UefiCpuPkg/CpuDxe/CpuMp.h     | 15 +++++++++++++++
 3 files changed, 62 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 3d67cc3..802f587 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -25,6 +25,8 @@ VOID *mCommonStack = 0;
 VOID *mTopOfApCommonStack = 0;
 VOID *mApStackStart = 0;
 
+BOOLEAN mAPsAlreadyInitFinished = FALSE;
+
 EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
   GetNumberOfProcessors,
   GetProcessorInfo,
@@ -1085,6 +1087,7 @@ ResetProcessorToIdleState (
   IN CPU_DATA_BLOCK  *CpuData
   )
 {
+  ResetApStackless(CpuData->Info.ProcessorId);
 }
 
 /**
@@ -1108,6 +1111,12 @@ ProcessorToIdleState (
 
   AsmApDoneWithCommonStack ();
 
+  //
+  // Avoid forcibly reset AP caused the AP State is not updated.
+  //
+  SetApState (CpuData, CpuStateIdle);
+  SetApProcedure (CpuData, NULL, NULL);
+
   while (TRUE) {
     while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) {
       CpuPause ();
@@ -1255,13 +1264,27 @@ ApEntryPointInC (
   VOID
   )
 {
-  VOID* TopOfApStack;
+  VOID*           TopOfApStack;
+  UINTN           ProcessorNumber;
 
-  FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors);
-  TopOfApStack  = mApStackStart + gApStackSize;
-  mApStackStart = TopOfApStack;
+  if (!mAPsAlreadyInitFinished) {
+    FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors);
+    TopOfApStack  = 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,
@@ -1400,6 +1423,7 @@ InitializeMpSupport (
     return;
   }
 
+  mAPsAlreadyInitFinished = TRUE;
 
   if (mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) {
     FreePages (mApStackStart, EFI_SIZE_TO_PAGES (
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index 0337327..d812561 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -98,6 +98,7 @@ typedef struct {
   EFI_EVENT                      WaitEvent;
   BOOLEAN                        TimeoutActive;
   EFI_EVENT                      CheckThisAPEvent;
+  VOID                           *TopOfStack;
 } CPU_DATA_BLOCK;
 
 /**
@@ -621,5 +622,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


------------------------------------------------------------------------------
Comprehensive Server Monitoring with Site24x7.
Monitor 10 servers for $9/Month.
Get alerted through email, SMS, voice calls or mobile push notifications.
Take corrective actions from your mobile device.
http://p.sf.net/sfu/Zoho
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to