EFI_STATUS Status;\r
UINTN ProcessorNumber;\r
\r
- Status = CpuMpServicesWhoAmI (&mMpSercicesTemplate, &ProcessorNumber);\r
+ Status = CpuMpServicesWhoAmI (&mMpServicesTemplate, &ProcessorNumber);\r
if (EFI_ERROR (Status)) {\r
return FALSE;\r
}\r
return EFI_NOT_FOUND;\r
}\r
\r
+/**\r
+ * Calculated and stalled the interval time by BSP to check whether\r
+ * the APs have finished.\r
+ *\r
+ * @param[in] Timeout The time limit in microseconds for\r
+ * APs to return from Procedure.\r
+ *\r
+ * @retval StallTime Time of execution stall.\r
+**/\r
+UINTN\r
+CalculateAndStallInterval (\r
+ IN UINTN Timeout\r
+ )\r
+{\r
+ UINTN StallTime;\r
\r
+ if (Timeout < gPollInterval && Timeout != 0) {\r
+ StallTime = Timeout;\r
+ } else {\r
+ StallTime = gPollInterval;\r
+ }\r
+ gBS->Stall (StallTime);\r
\r
+ return StallTime;\r
+}\r
\r
/**\r
This service retrieves the number of logical processor in the platform\r
UINTN NextNumber;\r
PROCESSOR_STATE APInitialState;\r
PROCESSOR_STATE ProcessorState;\r
- INTN Timeout;\r
+ UINTN Timeout;\r
\r
\r
if (!IsBSP ()) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
+ for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {\r
+ ProcessorData = &gMPSystem.ProcessorData[Number];\r
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {\r
+ // Skip BSP\r
+ continue;\r
+ }\r
+\r
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {\r
+ // Skip Disabled processors\r
+ continue;\r
+ }\r
+ gThread->MutexLock(ProcessorData->StateLock);\r
+ if (ProcessorData->State != CPU_STATE_IDLE) {\r
+ gThread->MutexUnlock (ProcessorData->StateLock);\r
+ return EFI_NOT_READY;\r
+ }\r
+ gThread->MutexUnlock(ProcessorData->StateLock);\r
+ }\r
\r
if (FailedCpuList != NULL) {\r
gMPSystem.FailedList = AllocatePool ((gMPSystem.NumberOfProcessors + 1) * sizeof (UINTN));\r
// state 1 by 1, until the previous 1 finished its task\r
// if not "SingleThread", all APs are put to ready state from the beginning\r
//\r
- if (ProcessorData->State == CPU_STATE_IDLE) {\r
- gMPSystem.StartCount++;\r
-\r
- gThread->MutexLock (&ProcessorData->StateLock);\r
- ProcessorData->State = APInitialState;\r
- gThread->MutexUnlock (&ProcessorData->StateLock);\r
+ gThread->MutexLock(ProcessorData->StateLock);\r
+ ASSERT (ProcessorData->State == CPU_STATE_IDLE);\r
+ ProcessorData->State = APInitialState;\r
+ gThread->MutexUnlock (ProcessorData->StateLock);\r
\r
- if (SingleThread) {\r
- APInitialState = CPU_STATE_BLOCKED;\r
- }\r
- } else {\r
- return EFI_NOT_READY;\r
+ gMPSystem.StartCount++;\r
+ if (SingleThread) {\r
+ APInitialState = CPU_STATE_BLOCKED;\r
}\r
}\r
\r
continue;\r
}\r
\r
- SetApProcedure (ProcessorData, Procedure, ProcedureArgument);\r
+ gThread->MutexLock (ProcessorData->StateLock);\r
+ ProcessorState = ProcessorData->State;\r
+ gThread->MutexUnlock (ProcessorData->StateLock);\r
+\r
+ if (ProcessorState == CPU_STATE_READY) {\r
+ SetApProcedure (ProcessorData, Procedure, ProcedureArgument);\r
+ }\r
}\r
\r
//\r
if (SingleThread) {\r
Status = GetNextBlockedNumber (&NextNumber);\r
if (!EFI_ERROR (Status)) {\r
+ gThread->MutexLock (gMPSystem.ProcessorData[NextNumber].StateLock);\r
gMPSystem.ProcessorData[NextNumber].State = CPU_STATE_READY;\r
+ gThread->MutexUnlock (gMPSystem.ProcessorData[NextNumber].StateLock);\r
}\r
}\r
\r
+ gThread->MutexLock (ProcessorData->StateLock);\r
ProcessorData->State = CPU_STATE_IDLE;\r
+ gThread->MutexUnlock (ProcessorData->StateLock);\r
+\r
break;\r
\r
default:\r
goto Done;\r
}\r
\r
- if ((TimeoutInMicroseconds != 0) && (Timeout < 0)) {\r
+ if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {\r
Status = EFI_TIMEOUT;\r
goto Done;\r
}\r
\r
- gBS->Stall (gPollInterval);\r
- Timeout -= gPollInterval;\r
+ Timeout -= CalculateAndStallInterval (Timeout);\r
}\r
\r
Done:\r
OUT BOOLEAN *Finished OPTIONAL\r
)\r
{\r
- INTN Timeout;\r
+ UINTN Timeout;\r
\r
if (!IsBSP ()) {\r
return EFI_DEVICE_ERROR;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ gThread->MutexLock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
if (gMPSystem.ProcessorData[ProcessorNumber].State != CPU_STATE_IDLE) {\r
+ gThread->MutexUnlock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
return EFI_NOT_READY;\r
}\r
+ gThread->MutexUnlock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
\r
if ((WaitEvent != NULL) && gReadToBoot) {\r
return EFI_UNSUPPORTED;\r
\r
// Blocking\r
while (TRUE) {\r
- gThread->MutexLock (&gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+ gThread->MutexLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
if (gMPSystem.ProcessorData[ProcessorNumber].State == CPU_STATE_FINISHED) {\r
gMPSystem.ProcessorData[ProcessorNumber].State = CPU_STATE_IDLE;\r
- gThread->MutexUnlock (&gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
break;\r
}\r
\r
- gThread->MutexUnlock (&gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
\r
- if ((TimeoutInMicroseconds != 0) && (Timeout < 0)) {\r
+ if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {\r
return EFI_TIMEOUT;\r
}\r
\r
- gBS->Stall (gPollInterval);\r
- Timeout -= gPollInterval;\r
+ Timeout -= CalculateAndStallInterval (Timeout);\r
}\r
\r
return EFI_SUCCESS;\r
}\r
ASSERT (Index != gMPSystem.NumberOfProcessors);\r
\r
+ gThread->MutexLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
if (gMPSystem.ProcessorData[ProcessorNumber].State != CPU_STATE_IDLE) {\r
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
return EFI_NOT_READY;\r
}\r
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
\r
// Skip for now as we need switch a bunch of stack stuff around and it's complex\r
// May not be worth it?\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ gThread->MutexLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
if (gMPSystem.ProcessorData[ProcessorNumber].State != CPU_STATE_IDLE) {\r
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
return EFI_UNSUPPORTED;\r
}\r
-\r
- gThread->MutexLock (&gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
\r
if (EnableAP) {\r
if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0 ) {\r
gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag |= (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT);\r
}\r
\r
- gThread->MutexUnlock (&gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
-\r
return EFI_SUCCESS;\r
}\r
\r
\r
\r
\r
-EFI_MP_SERVICES_PROTOCOL mMpSercicesTemplate = {\r
+EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {\r
CpuMpServicesGetNumberOfProcessors,\r
CpuMpServicesGetProcessorInfo,\r
CpuMpServicesStartupAllAps,\r
BOOLEAN Found;\r
\r
if (gMPSystem.TimeoutActive) {\r
- gMPSystem.Timeout -= gPollInterval;\r
+ gMPSystem.Timeout -= CalculateAndStallInterval (gMPSystem.Timeout);\r
}\r
\r
- ProcessorData = (PROCESSOR_DATA_BLOCK *) Context;\r
-\r
for (ProcessorNumber = 0; ProcessorNumber < gMPSystem.NumberOfProcessors; ProcessorNumber++) {\r
- if ((ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {\r
+ ProcessorData = &gMPSystem.ProcessorData[ProcessorNumber];\r
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {\r
// Skip BSP\r
continue;\r
}\r
// context. Meaning deadlock. Which is a bad thing.\r
// So, try lock it. If we can get it, cool, do our thing.\r
// otherwise, just dump out & try again on the next iteration.\r
- Status = gThread->MutexTryLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+ Status = gThread->MutexTryLock (ProcessorData->StateLock);\r
if (EFI_ERROR(Status)) {\r
return;\r
}\r
- ProcessorState = gMPSystem.ProcessorData[ProcessorNumber].State;\r
- gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+ ProcessorState = ProcessorData->State;\r
+ gThread->MutexUnlock (ProcessorData->StateLock);\r
\r
switch (ProcessorState) {\r
- case CPU_STATE_READY:\r
- SetApProcedure (ProcessorData, gMPSystem.Procedure, gMPSystem.ProcedureArgument);\r
- break;\r
-\r
case CPU_STATE_FINISHED:\r
if (gMPSystem.SingleThread) {\r
Status = GetNextBlockedNumber (&NextNumber);\r
if (!EFI_ERROR (Status)) {\r
NextData = &gMPSystem.ProcessorData[NextNumber];\r
\r
- gThread->MutexLock (&NextData->ProcedureLock);\r
+ gThread->MutexLock (NextData->StateLock);\r
NextData->State = CPU_STATE_READY;\r
- gThread->MutexUnlock (&NextData->ProcedureLock);\r
+ gThread->MutexUnlock (NextData->StateLock);\r
\r
SetApProcedure (NextData, gMPSystem.Procedure, gMPSystem.ProcedureArgument);\r
}\r
}\r
\r
- gMPSystem.ProcessorData[ProcessorNumber].State = CPU_STATE_IDLE;\r
+ gThread->MutexLock (ProcessorData->StateLock);\r
+ ProcessorData->State = CPU_STATE_IDLE;\r
+ gThread->MutexUnlock (ProcessorData->StateLock);\r
gMPSystem.FinishCount++;\r
break;\r
\r
}\r
}\r
\r
- if (gMPSystem.TimeoutActive && gMPSystem.Timeout < 0) {\r
+ if (gMPSystem.TimeoutActive && gMPSystem.Timeout == 0) {\r
//\r
// Timeout\r
//\r
if (gMPSystem.FailedList != NULL) {\r
for (ProcessorNumber = 0; ProcessorNumber < gMPSystem.NumberOfProcessors; ProcessorNumber++) {\r
- if ((ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {\r
+ ProcessorData = &gMPSystem.ProcessorData[ProcessorNumber];\r
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {\r
// Skip BSP\r
continue;\r
}\r
}\r
\r
// Mark the\r
- Status = gThread->MutexTryLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+ Status = gThread->MutexTryLock (ProcessorData->StateLock);\r
if (EFI_ERROR(Status)) {\r
return;\r
}\r
- ProcessorState = gMPSystem.ProcessorData[ProcessorNumber].State;\r
- gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);\r
+ ProcessorState = ProcessorData->State;\r
+ gThread->MutexUnlock (ProcessorData->StateLock);\r
\r
if (ProcessorState != CPU_STATE_IDLE) {\r
// If we are retrying make sure we don't double count\r
Handle = NULL;\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&Handle,\r
- &gEfiMpServiceProtocolGuid, &mMpSercicesTemplate,\r
+ &gEfiMpServiceProtocolGuid, &mMpServicesTemplate,\r
NULL\r
);\r
return Status;\r