VolatileRegisters->Dr6 = AsmReadDr6 ();\r
VolatileRegisters->Dr7 = AsmReadDr7 ();\r
}\r
+\r
+ AsmReadGdtr (&VolatileRegisters->Gdtr);\r
+ AsmReadIdtr (&VolatileRegisters->Idtr);\r
+ VolatileRegisters->Tr = AsmReadTr ();\r
}\r
\r
/**\r
)\r
{\r
CPUID_VERSION_INFO_EDX VersionInfoEdx;\r
+ IA32_TSS_DESCRIPTOR *Tss;\r
\r
AsmWriteCr0 (VolatileRegisters->Cr0);\r
AsmWriteCr3 (VolatileRegisters->Cr3);\r
AsmWriteDr7 (VolatileRegisters->Dr7);\r
}\r
}\r
+\r
+ AsmWriteGdtr (&VolatileRegisters->Gdtr);\r
+ AsmWriteIdtr (&VolatileRegisters->Idtr);\r
+ if (VolatileRegisters->Tr != 0 &&\r
+ VolatileRegisters->Tr < VolatileRegisters->Gdtr.Limit) {\r
+ Tss = (IA32_TSS_DESCRIPTOR *)(VolatileRegisters->Gdtr.Base +\r
+ VolatileRegisters->Tr);\r
+ if (Tss->Bits.P == 1) {\r
+ Tss->Bits.Type &= 0xD; // 1101 - Clear busy bit just in case\r
+ AsmWriteTr (VolatileRegisters->Tr);\r
+ }\r
+ }\r
}\r
\r
/**\r
This function will be called from AP reset code if BSP uses WakeUpAP.\r
\r
@param[in] ExchangeInfo Pointer to the MP exchange info buffer\r
- @param[in] NumApsExecuting Number of current executing AP\r
+ @param[in] ApIndex Number of current executing AP\r
**/\r
VOID\r
EFIAPI\r
ApWakeupFunction (\r
IN MP_CPU_EXCHANGE_INFO *ExchangeInfo,\r
- IN UINTN NumApsExecuting\r
+ IN UINTN ApIndex\r
)\r
{\r
CPU_MP_DATA *CpuMpData;\r
// Add CPU number\r
//\r
InterlockedIncrement ((UINT32 *) &CpuMpData->CpuCount);\r
- ProcessorNumber = NumApsExecuting;\r
+ ProcessorNumber = ApIndex;\r
//\r
// This is first time AP wakeup, get BIST information from AP stack\r
//\r
// 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
ExchangeInfo->Cr3 = AsmReadCr3 ();\r
\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
}\r
if (CpuMpData->InitFlag == ApInitConfig) {\r
//\r
- // Wait for all potential APs waken up in one specified period\r
+ // Here support two methods to collect AP count through adjust\r
+ // PcdCpuApInitTimeOutInMicroSeconds values.\r
+ //\r
+ // one way is set a value to just let the first AP to start the\r
+ // initialization, then through the later while loop to wait all Aps\r
+ // finsh the initialization.\r
+ // The other way is set a value to let all APs finished the initialzation.\r
+ // In this case, the later while loop is useless.\r
//\r
TimedWaitForApFinish (\r
CpuMpData,\r
PcdGet32 (PcdCpuMaxLogicalProcessorNumber) - 1,\r
PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds)\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