If ApLoopMode is ApInHltLoop, BSP will send INIT-SIPI-SIPI to wake up APs.
If ApLoopMode is ApInMwaitLoop or ApInRunLoop, BSP will write one semaphore to
wake up APs.

Contributed-under: TianoCore Contribution Agreement 1.0
Cc: Feng Tian <feng.t...@intel.com>
Cc: Michael Kinney <michael.d.kin...@intel.com>
Cc: Jordan Justen <jordan.l.jus...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff....@intel.com>
Tested-by: Michael Kinney <michael.d.kin...@intel.com>
---
 UefiCpuPkg/CpuMpPei/CpuMpPei.c      | 43 +++++++++++++++++++++++++++++++------
 UefiCpuPkg/CpuMpPei/CpuMpPei.h      |  4 ++--
 UefiCpuPkg/CpuMpPei/CpuMpPei.inf    |  1 +
 UefiCpuPkg/CpuMpPei/PeiMpServices.c |  6 +++---
 4 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
index ba82ba4..950d61c 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
@@ -399,7 +399,7 @@ ApCFunction (
   @param PeiCpuMpData       Pointer to PEI CPU MP Data
   @param Broadcast          TRUE:  Send broadcast IPI to all APs
                             FALSE: Send IPI to AP by ApicId
-  @param ApicId             Apic ID for the processor to be waked
+  @param ProcessorNumber    The handle number of specified processor
   @param Procedure          The function to be invoked by AP
   @param ProcedureArgument  The argument to be passed into AP function
 **/
@@ -407,12 +407,13 @@ VOID
 WakeUpAP (
   IN PEI_CPU_MP_DATA           *PeiCpuMpData,
   IN BOOLEAN                   Broadcast,
-  IN UINT32                    ApicId,
+  IN UINTN                     ProcessorNumber,
   IN EFI_AP_PROCEDURE          Procedure,              OPTIONAL
   IN VOID                      *ProcedureArgument      OPTIONAL
   )
 {
   volatile MP_CPU_EXCHANGE_INFO    *ExchangeInfo;
+  UINTN                            Index;
 
   PeiCpuMpData->ApFunction         = (UINTN) Procedure;
   PeiCpuMpData->ApFunctionArgument = (UINTN) ProcedureArgument;
@@ -436,12 +437,40 @@ WakeUpAP (
   CopyMem ((VOID *)&ExchangeInfo->GdtrProfile, &mGdt, sizeof(mGdt));
   AsmReadIdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->IdtrProfile);
 
-  if (Broadcast) {
-    SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart);
-  } else {
-    SendInitSipiSipi (ApicId, (UINT32) ExchangeInfo->BufferStart);
+  if (PeiCpuMpData->ApLoopMode == ApInMwaitLoop) {
+    //
+    // Get AP target C-state each time when waking up AP,
+    // for it maybe updated by platform again
+    //
+    PeiCpuMpData->ApTargetCState = PcdGet8 (PcdCpuApTargetCstate);
   }
 
+  //
+  // Wakeup APs per AP loop state
+  //
+  if (PeiCpuMpData->ApLoopMode == ApInHltLoop || PeiCpuMpData->InitFlag) {
+    if (Broadcast) {
+      SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart);
+    } else {
+      SendInitSipiSipi (
+        PeiCpuMpData->CpuData[ProcessorNumber].ApicId,
+        (UINT32) ExchangeInfo->BufferStart
+        );
+    }
+  } else if ((PeiCpuMpData->ApLoopMode == ApInMwaitLoop) ||
+             (PeiCpuMpData->ApLoopMode == ApInRunLoop)) {
+    if (Broadcast) {
+      for (Index = 0; Index < PeiCpuMpData->CpuCount; Index++) {
+        if (Index != PeiCpuMpData->BspNumber) {
+          *(PeiCpuMpData->CpuData[Index].StartupApSignal) = WAKEUP_AP_SIGNAL;
+        }
+      }
+    } else {
+      *(PeiCpuMpData->CpuData[ProcessorNumber].StartupApSignal) = 
WAKEUP_AP_SIGNAL;
+    }
+  } else {
+    ASSERT (FALSE);
+  }
   return ;
 }
 
@@ -600,7 +629,7 @@ CountProcessorNumber (
     if (PeiCpuMpData->X2ApicEnable) {
       DEBUG ((EFI_D_INFO, "Force x2APIC mode!\n"));
       //
-      // Send 2nd broadcast IPI to all APs to enable x2APIC mode
+      // Wakeup all APs to enable x2APIC mode
       //
       WakeUpAP (PeiCpuMpData, TRUE, 0, ApFuncEnableX2Apic, NULL);
       //
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
index bbd35ff..65d8d48 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -253,7 +253,7 @@ CpuMpEndOfPeiCallback (
   @param PeiCpuMpData       Pointer to PEI CPU MP Data
   @param Broadcast          TRUE:  Send broadcast IPI to all APs
                             FALSE: Send IPI to AP by ApicId
-  @param ApicId             Apic ID for the processor to be waked
+  @param ProcessorNumber    The handle number of specified processor
   @param Procedure          The function to be invoked by AP
   @param ProcedureArgument  The argument to be passed into AP function
 **/
@@ -261,7 +261,7 @@ VOID
 WakeUpAP (
   IN PEI_CPU_MP_DATA           *PeiCpuMpData,
   IN BOOLEAN                   Broadcast,
-  IN UINT32                    ApicId,
+  IN UINTN                     ProcessorNumber,
   IN EFI_AP_PROCEDURE          Procedure,              OPTIONAL
   IN VOID                      *ProcedureArgument      OPTIONAL
   );
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
index ec353ae..70b272e 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
@@ -83,6 +83,7 @@
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress            ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize         ## CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode                       ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate                   ## 
SOMETIMES_CONSUMES
 
 [Depex]
   gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/UefiCpuPkg/CpuMpPei/PeiMpServices.c 
b/UefiCpuPkg/CpuMpPei/PeiMpServices.c
index 5dd2c15..e784377 100644
--- a/UefiCpuPkg/CpuMpPei/PeiMpServices.c
+++ b/UefiCpuPkg/CpuMpPei/PeiMpServices.c
@@ -520,7 +520,7 @@ PeiStartupAllAPs (
       if (Index == CallerNumber) {
         continue;
       }
-      WakeUpAP (PeiCpuMpData, FALSE, PeiCpuMpData->CpuData[Index].ApicId, 
Procedure, ProcedureArgument);
+      WakeUpAP (PeiCpuMpData, FALSE, Index, Procedure, ProcedureArgument);
       //
       // Wait to finish
       //
@@ -655,7 +655,7 @@ PeiStartupThisAP (
   WaitCountIndex = 0;
   FinishedCount = &PeiCpuMpData->FinishedCount;
 
-  WakeUpAP (PeiCpuMpData, FALSE, 
PeiCpuMpData->CpuData[ProcessorNumber].ApicId, Procedure, ProcedureArgument);
+  WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, Procedure, 
ProcedureArgument);
 
   //
   // Wait to finish
@@ -791,7 +791,7 @@ PeiSwitchBSP (
   //
   // Need to wakeUp AP (future BSP).
   //
-  WakeUpAP (PeiCpuMpData, FALSE, 
PeiCpuMpData->CpuData[ProcessorNumber].ApicId, FutureBSPProc, PeiCpuMpData);
+  WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, FutureBSPProc, PeiCpuMpData);
 
   AsmExchangeRole (&PeiCpuMpData->BSPInfo, &PeiCpuMpData->APInfo);
 
-- 
1.9.5.msysgit.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to