]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/MpInitLib: Enhance waiting for AP initialization logic.
authorEric Dong <eric.dong@intel.com>
Mon, 23 Oct 2017 07:02:36 +0000 (15:02 +0800)
committerEric Dong <eric.dong@intel.com>
Tue, 24 Oct 2017 08:05:37 +0000 (16:05 +0800)
Current logic always waiting for a specific value to collect all APs
count. This logic may caused some platforms cost too much time to
wait for time out.
This patch add new logic to collect APs count. It adds new variable
NumApsExecuting to detect whether all APs have finished initialization.
Each AP let NumApsExecuting++ when begin to initialize itself and let
NumApsExecuting-- when it finish the initialization. BSP base on whether
NumApsExecuting == 0  to finished the collect AP process.

Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Jeff Fan <vanjeff_919@hotmail.com>
UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
UefiCpuPkg/Library/MpInitLib/MpLib.c
UefiCpuPkg/Library/MpInitLib/MpLib.h
UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm

index 976af1f78e1b9d5f84a5768aed8d3be68cffff0a..bdfe0d33cc9ec40befb37efe70a78070ede4813b 100644 (file)
@@ -40,4 +40,5 @@ EnableExecuteDisableLocation  equ        LockLocation + 30h
 Cr3Location                   equ        LockLocation + 34h\r
 InitFlagLocation              equ        LockLocation + 38h\r
 CpuInfoLocation               equ        LockLocation + 3Ch\r
+NumApsExecutingLocation       equ        LockLocation + 40h\r
 \r
index 1b9c6a62f8fe9320b545b826af94f0eef45cf0b0..2b6c27d4ec675f6389436ce3862b01b22284a5b1 100644 (file)
@@ -86,6 +86,12 @@ Flat32Start:                                   ; protected mode entry point
 \r
     mov        esi, ebx\r
 \r
+    ; Increment the number of APs executing here as early as possible\r
+    ; This is decremented in C code when AP is finished executing\r
+    mov        edi, esi\r
+    add        edi, NumApsExecutingLocation\r
+    lock inc   dword [edi]\r
+\r
     mov         edi, esi\r
     add         edi, EnableExecuteDisableLocation\r
     cmp         byte [edi], 0\r
index db923c9917d7be561c96da23a6161c013d2cce7f..48f930b701473de77cabd58d4f929fc4c6091ea1 100644 (file)
@@ -662,6 +662,7 @@ ApWakeupFunction (
     // AP finished executing C code\r
     //\r
     InterlockedIncrement ((UINT32 *) &CpuMpData->FinishedCount);\r
+    InterlockedDecrement ((UINT32 *) &CpuMpData->MpCpuExchangeInfo->NumApsExecuting);\r
 \r
     //\r
     // Place AP is specified loop mode\r
@@ -765,6 +766,7 @@ FillExchangeInfoData (
 \r
   ExchangeInfo->CFunction       = (UINTN) ApWakeupFunction;\r
   ExchangeInfo->ApIndex         = 0;\r
+  ExchangeInfo->NumApsExecuting = 0;\r
   ExchangeInfo->InitFlag        = (UINTN) CpuMpData->InitFlag;\r
   ExchangeInfo->CpuInfo         = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;\r
   ExchangeInfo->CpuMpData       = CpuMpData;\r
@@ -934,13 +936,19 @@ WakeUpAP (
     }\r
     if (CpuMpData->InitFlag == ApInitConfig) {\r
       //\r
-      // Wait for all potential APs waken up in one specified period\r
+      // Wait for one potential AP waken up in one specified period\r
       //\r
-      TimedWaitForApFinish (\r
-        CpuMpData,\r
-        PcdGet32 (PcdCpuMaxLogicalProcessorNumber) - 1,\r
-        PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds)\r
-        );\r
+      if (CpuMpData->CpuCount == 0) {\r
+        TimedWaitForApFinish (\r
+          CpuMpData,\r
+          PcdGet32 (PcdCpuMaxLogicalProcessorNumber) - 1,\r
+          PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds)\r
+          );\r
+      }\r
+\r
+      while (CpuMpData->MpCpuExchangeInfo->NumApsExecuting != 0) {\r
+        CpuPause();\r
+      }\r
     } else {\r
       //\r
       // Wait all APs waken up if this is not the 1st broadcast of SIPI\r
index e41d2db94a9513eb11a5dd45450c06520be4eca3..d13d5c06f59dd3bc03f8a10baf429209cb18ba98 100644 (file)
@@ -176,6 +176,7 @@ typedef struct {
   UINTN                 Cr3;\r
   UINTN                 InitFlag;\r
   CPU_INFO_IN_HOB       *CpuInfo;\r
+  UINTN                 NumApsExecuting;\r
   CPU_MP_DATA           *CpuMpData;\r
   UINTN                 InitializeFloatingPointUnitsAddress;\r
 } MP_CPU_EXCHANGE_INFO;\r
index 114f4e0a7db9308b0e6c27424bbd0696931f7c59..d255ca5e1b9c9a5442ed83762453afd69a06dd42 100644 (file)
@@ -40,5 +40,6 @@ EnableExecuteDisableLocation  equ        LockLocation + 5Ch
 Cr3Location                   equ        LockLocation + 64h\r
 InitFlagLocation              equ        LockLocation + 6Ch\r
 CpuInfoLocation               equ        LockLocation + 74h\r
-InitializeFloatingPointUnitsAddress equ  LockLocation + 84h\r
+NumApsExecutingLocation       equ        LockLocation + 7Ch\r
+InitializeFloatingPointUnitsAddress equ  LockLocation + 8Ch\r
 \r
index 4ada6493d475738398b674e4419d9dac3e94e1aa..21d278600d1bf3878ae37b723867089e33344abd 100644 (file)
@@ -124,6 +124,12 @@ LongModeStart:
     cmp        qword [edi], 1       ; ApInitConfig\r
     jnz        GetApicId\r
 \r
+    ; Increment the number of APs executing here as early as possible\r
+    ; This is decremented in C code when AP is finished executing\r
+    mov        edi, esi\r
+    add        edi, NumApsExecutingLocation\r
+    lock inc   dword [edi]\r
+\r
     ; AP init\r
     mov        edi, esi\r
     add        edi, LockLocation\r