*(mSmmMpSyncData->CpuData[CpuIndex].Present));\r
}\r
\r
-/**\r
- Check whether execute in single AP or all APs.\r
-\r
- Compare two Tokens used by different APs to know whether in StartAllAps call.\r
-\r
- Whether is an valid AP base on AP's Present flag.\r
-\r
- @retval TRUE IN StartAllAps call.\r
- @retval FALSE Not in StartAllAps call.\r
-\r
-**/\r
-BOOLEAN\r
-InStartAllApsCall (\r
- VOID\r
- )\r
-{\r
- UINTN ApIndex;\r
- UINTN ApIndex2;\r
-\r
- for (ApIndex = mMaxNumberOfCpus; ApIndex-- > 0;) {\r
- if (IsPresentAp (ApIndex) && (mSmmMpSyncData->CpuData[ApIndex].Token != NULL)) {\r
- for (ApIndex2 = ApIndex; ApIndex2-- > 0;) {\r
- if (IsPresentAp (ApIndex2) && (mSmmMpSyncData->CpuData[ApIndex2].Token != NULL)) {\r
- return mSmmMpSyncData->CpuData[ApIndex2].Token == mSmmMpSyncData->CpuData[ApIndex].Token;\r
- }\r
- }\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
/**\r
Clean up the status flags used during executing the procedure.\r
\r
IN UINTN CpuIndex\r
)\r
{\r
- UINTN Index;\r
- BOOLEAN Released;\r
+ PROCEDURE_TOKEN *Token;\r
\r
- if (InStartAllApsCall ()) {\r
- //\r
- // In Start All APs mode, make sure all APs have finished task.\r
- //\r
- if (WaitForAllAPsNotBusy (FALSE)) {\r
- //\r
- // Clean the flags update in the function call.\r
- //\r
- Released = FALSE;\r
- for (Index = mMaxNumberOfCpus; Index-- > 0;) {\r
- //\r
- // Only In SMM APs need to be clean up.\r
- //\r
- if (mSmmMpSyncData->CpuData[Index].Present && mSmmMpSyncData->CpuData[Index].Token != NULL) {\r
- if (!Released) {\r
- ReleaseSpinLock (mSmmMpSyncData->CpuData[Index].Token);\r
- Released = TRUE;\r
- }\r
- mSmmMpSyncData->CpuData[Index].Token = NULL;\r
- }\r
- }\r
- }\r
- } else {\r
- //\r
- // In single AP mode.\r
- //\r
- if (mSmmMpSyncData->CpuData[CpuIndex].Token != NULL) {\r
- ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Token);\r
- mSmmMpSyncData->CpuData[CpuIndex].Token = NULL;\r
- }\r
+ Token = mSmmMpSyncData->CpuData[CpuIndex].Token;\r
+\r
+ if (InterlockedDecrement (&Token->RunningApCount) == 0) {\r
+ ReleaseSpinLock (Token->SpinLock);\r
}\r
+\r
+ mSmmMpSyncData->CpuData[CpuIndex].Token = NULL;\r
}\r
\r
/**\r
*mSmmMpSyncData->CpuData[CpuIndex].Status = ProcedureStatus;\r
}\r
\r
+ if (mSmmMpSyncData->CpuData[CpuIndex].Token != NULL) {\r
+ ReleaseToken (CpuIndex);\r
+ }\r
+\r
//\r
// Release BUSY\r
//\r
ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
-\r
- ReleaseToken (CpuIndex);\r
}\r
\r
if (SmmCpuFeaturesNeedConfigureMtrrs()) {\r
while (!IsNull (&gSmmCpuPrivate->TokenList, Link)) {\r
ProcToken = PROCEDURE_TOKEN_FROM_LINK (Link);\r
\r
- if (ProcToken->ProcedureToken == Token) {\r
+ if (ProcToken->SpinLock == Token) {\r
return TRUE;\r
}\r
\r
/**\r
create token and save it to the maintain list.\r
\r
+ @param RunningApCount Input running AP count.\r
+\r
@retval return the spin lock used as token.\r
\r
**/\r
-SPIN_LOCK *\r
+PROCEDURE_TOKEN *\r
CreateToken (\r
- VOID\r
+ IN UINT32 RunningApCount\r
)\r
{\r
PROCEDURE_TOKEN *ProcToken;\r
- SPIN_LOCK *CpuToken;\r
+ SPIN_LOCK *SpinLock;\r
UINTN SpinLockSize;\r
TOKEN_BUFFER *TokenBuf;\r
UINT32 TokenCountPerChunk;\r
gSmmCpuPrivate->UsedTokenNum = 0;\r
}\r
\r
- CpuToken = (SPIN_LOCK *)(gSmmCpuPrivate->CurrentTokenBuf + SpinLockSize * gSmmCpuPrivate->UsedTokenNum);\r
+ SpinLock = (SPIN_LOCK *)(gSmmCpuPrivate->CurrentTokenBuf + SpinLockSize * gSmmCpuPrivate->UsedTokenNum);\r
gSmmCpuPrivate->UsedTokenNum++;\r
\r
- InitializeSpinLock (CpuToken);\r
- AcquireSpinLock (CpuToken);\r
+ InitializeSpinLock (SpinLock);\r
+ AcquireSpinLock (SpinLock);\r
\r
ProcToken = AllocatePool (sizeof (PROCEDURE_TOKEN));\r
ASSERT (ProcToken != NULL);\r
ProcToken->Signature = PROCEDURE_TOKEN_SIGNATURE;\r
- ProcToken->ProcedureToken = CpuToken;\r
+ ProcToken->SpinLock = SpinLock;\r
+ ProcToken->RunningApCount = RunningApCount;\r
\r
InsertTailList (&gSmmCpuPrivate->TokenList, &ProcToken->Link);\r
\r
- return CpuToken;\r
+ return ProcToken;\r
}\r
\r
/**\r
IN OUT EFI_STATUS *CpuStatus\r
)\r
{\r
+ PROCEDURE_TOKEN *ProcToken;\r
+\r
if (CpuIndex >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus) {\r
DEBUG((DEBUG_ERROR, "CpuIndex(%d) >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus(%d)\n", CpuIndex, gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));\r
return EFI_INVALID_PARAMETER;\r
\r
AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
\r
- if (Token != NULL) {\r
- *Token = (MM_COMPLETION) CreateToken ();\r
- }\r
-\r
mSmmMpSyncData->CpuData[CpuIndex].Procedure = Procedure;\r
mSmmMpSyncData->CpuData[CpuIndex].Parameter = ProcArguments;\r
if (Token != NULL) {\r
- mSmmMpSyncData->CpuData[CpuIndex].Token = (SPIN_LOCK *)(*Token);\r
+ ProcToken= CreateToken (1);\r
+ mSmmMpSyncData->CpuData[CpuIndex].Token = ProcToken;\r
+ *Token = (MM_COMPLETION)ProcToken->SpinLock;\r
}\r
mSmmMpSyncData->CpuData[CpuIndex].Status = CpuStatus;\r
if (mSmmMpSyncData->CpuData[CpuIndex].Status != NULL) {\r
{\r
UINTN Index;\r
UINTN CpuCount;\r
+ PROCEDURE_TOKEN *ProcToken;\r
\r
if ((TimeoutInMicroseconds != 0) && ((mSmmMp.Attributes & EFI_MM_MP_TIMEOUT_SUPPORTED) == 0)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
if (Token != NULL) {\r
- *Token = (MM_COMPLETION) CreateToken ();\r
+ ProcToken = CreateToken ((UINT32)mMaxNumberOfCpus);\r
+ *Token = (MM_COMPLETION)ProcToken->SpinLock;\r
+ } else {\r
+ ProcToken = NULL;\r
}\r
\r
//\r
if (IsPresentAp (Index)) {\r
mSmmMpSyncData->CpuData[Index].Procedure = (EFI_AP_PROCEDURE2) Procedure;\r
mSmmMpSyncData->CpuData[Index].Parameter = ProcedureArguments;\r
- if (Token != NULL) {\r
- mSmmMpSyncData->CpuData[Index].Token = (SPIN_LOCK *)(*Token);\r
+ if (ProcToken != NULL) {\r
+ mSmmMpSyncData->CpuData[Index].Token = ProcToken;\r
}\r
if (CPUStatus != NULL) {\r
mSmmMpSyncData->CpuData[Index].Status = &CPUStatus[Index];\r
if (CPUStatus != NULL) {\r
CPUStatus[Index] = EFI_NOT_STARTED;\r
}\r
+\r
+ //\r
+ // Decrease the count to mark this processor(AP or BSP) as finished.\r
+ //\r
+ if (ProcToken != NULL) {\r
+ WaitForSemaphore (&ProcToken->RunningApCount);\r
+ }\r
}\r
}\r
\r