/** @file\r
CPU MP Initialize Library common functions.\r
\r
- Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
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
// We need to re-initialize them at here\r
//\r
ProgramVirtualWireMode ();\r
+ //\r
+ // Mask the LINT0 and LINT1 so that AP doesn't enter the system timer interrupt handler.\r
+ //\r
+ DisableLvtInterrupts ();\r
SyncLocalApicTimerSetting (CpuMpData);\r
\r
CurrentApicMode = GetApicMode ();\r
}\r
if (CpuMpData->InitFlag == ApInitConfig) {\r
//\r
- // Wait for one potential AP waken up in one specified period\r
+ // Here support two methods to collect AP count through adjust\r
+ // PcdCpuApInitTimeOutInMicroSeconds values.\r
//\r
- if (CpuMpData->CpuCount == 0) {\r
- TimedWaitForApFinish (\r
- CpuMpData,\r
- PcdGet32 (PcdCpuMaxLogicalProcessorNumber) - 1,\r
- PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds)\r
- );\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
// Set BSP basic information\r
//\r
- InitializeApData (CpuMpData, 0, 0, CpuMpData->Buffer);\r
+ InitializeApData (CpuMpData, 0, 0, CpuMpData->Buffer + ApStackSize);\r
//\r
// Save assembly code information\r
//\r
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
ApicBaseMsr.Bits.BSP = 1;\r
AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);\r
+ ProgramVirtualWireMode ();\r
\r
//\r
// Wait for old BSP finished AP task\r