summaryrefslogtreecommitdiff
path: root/UefiCpuPkg
diff options
context:
space:
mode:
authorEric Dong <eric.dong@intel.com>2017-10-23 15:02:36 +0800
committerEric Dong <eric.dong@intel.com>2017-10-24 16:05:37 +0800
commit0594ec417c89ed00cbea6a0b0458334727c4dc28 (patch)
treef16cff7d94f418b9c7cdf0c14052b4849c20e969 /UefiCpuPkg
parent37676b9f82ab17bb043a0901d054cd8ab519543c (diff)
downloadedk2-0594ec417c89ed00cbea6a0b0458334727c4dc28.zip
edk2-0594ec417c89ed00cbea6a0b0458334727c4dc28.tar.gz
edk2-0594ec417c89ed00cbea6a0b0458334727c4dc28.tar.bz2
UefiCpuPkg/MpInitLib: Enhance waiting for AP initialization logic.
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>
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r--UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc1
-rw-r--r--UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm6
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.c20
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.h1
-rw-r--r--UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc3
-rw-r--r--UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm6
6 files changed, 30 insertions, 7 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
index 976af1f..bdfe0d3 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpEqu.inc
@@ -40,4 +40,5 @@ EnableExecuteDisableLocation equ LockLocation + 30h
Cr3Location equ LockLocation + 34h
InitFlagLocation equ LockLocation + 38h
CpuInfoLocation equ LockLocation + 3Ch
+NumApsExecutingLocation equ LockLocation + 40h
diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
index 1b9c6a6..2b6c27d 100644
--- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
@@ -86,6 +86,12 @@ Flat32Start: ; protected mode entry point
mov esi, ebx
+ ; Increment the number of APs executing here as early as possible
+ ; This is decremented in C code when AP is finished executing
+ mov edi, esi
+ add edi, NumApsExecutingLocation
+ lock inc dword [edi]
+
mov edi, esi
add edi, EnableExecuteDisableLocation
cmp byte [edi], 0
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index db923c9..48f930b 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -662,6 +662,7 @@ ApWakeupFunction (
// AP finished executing C code
//
InterlockedIncrement ((UINT32 *) &CpuMpData->FinishedCount);
+ InterlockedDecrement ((UINT32 *) &CpuMpData->MpCpuExchangeInfo->NumApsExecuting);
//
// Place AP is specified loop mode
@@ -765,6 +766,7 @@ FillExchangeInfoData (
ExchangeInfo->CFunction = (UINTN) ApWakeupFunction;
ExchangeInfo->ApIndex = 0;
+ ExchangeInfo->NumApsExecuting = 0;
ExchangeInfo->InitFlag = (UINTN) CpuMpData->InitFlag;
ExchangeInfo->CpuInfo = (CPU_INFO_IN_HOB *) (UINTN) CpuMpData->CpuInfoInHob;
ExchangeInfo->CpuMpData = CpuMpData;
@@ -934,13 +936,19 @@ WakeUpAP (
}
if (CpuMpData->InitFlag == ApInitConfig) {
//
- // Wait for all potential APs waken up in one specified period
+ // Wait for one potential AP waken up in one specified period
//
- TimedWaitForApFinish (
- CpuMpData,
- PcdGet32 (PcdCpuMaxLogicalProcessorNumber) - 1,
- PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds)
- );
+ if (CpuMpData->CpuCount == 0) {
+ TimedWaitForApFinish (
+ CpuMpData,
+ PcdGet32 (PcdCpuMaxLogicalProcessorNumber) - 1,
+ PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds)
+ );
+ }
+
+ while (CpuMpData->MpCpuExchangeInfo->NumApsExecuting != 0) {
+ CpuPause();
+ }
} else {
//
// Wait all APs waken up if this is not the 1st broadcast of SIPI
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index e41d2db..d13d5c0 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -176,6 +176,7 @@ typedef struct {
UINTN Cr3;
UINTN InitFlag;
CPU_INFO_IN_HOB *CpuInfo;
+ UINTN NumApsExecuting;
CPU_MP_DATA *CpuMpData;
UINTN InitializeFloatingPointUnitsAddress;
} MP_CPU_EXCHANGE_INFO;
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc b/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
index 114f4e0..d255ca5 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpEqu.inc
@@ -40,5 +40,6 @@ EnableExecuteDisableLocation equ LockLocation + 5Ch
Cr3Location equ LockLocation + 64h
InitFlagLocation equ LockLocation + 6Ch
CpuInfoLocation equ LockLocation + 74h
-InitializeFloatingPointUnitsAddress equ LockLocation + 84h
+NumApsExecutingLocation equ LockLocation + 7Ch
+InitializeFloatingPointUnitsAddress equ LockLocation + 8Ch
diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
index 4ada649..21d2786 100644
--- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
+++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm
@@ -124,6 +124,12 @@ LongModeStart:
cmp qword [edi], 1 ; ApInitConfig
jnz GetApicId
+ ; Increment the number of APs executing here as early as possible
+ ; This is decremented in C code when AP is finished executing
+ mov edi, esi
+ add edi, NumApsExecutingLocation
+ lock inc dword [edi]
+
; AP init
mov edi, esi
add edi, LockLocation