/**\r
Checks APs' status periodically.\r
\r
- This function is triggerred by timer perodically to check the\r
+ This function is triggered by timer periodically to check the\r
state of APs for StartupAllAPs() and StartupThisAP() executed\r
in non-blocking mode.\r
\r
return EFI_NOT_FOUND;\r
}\r
\r
-/**\r
- Programs Local APIC registers for virtual wire mode.\r
-\r
- This function programs Local APIC registers for virtual wire mode.\r
-\r
- @param Bsp Indicates whether the programmed processor is going to be BSP\r
-\r
-**/\r
-VOID\r
-ProgramVirtualWireMode (\r
- BOOLEAN Bsp\r
- )\r
-{\r
- UINTN ApicBase;\r
- UINT32 Value;\r
-\r
- ApicBase = (UINTN)AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE, 12, 35) << 12;\r
-\r
- //\r
- // Program the Spurious Vector entry\r
- // Set bit 8 (APIC Software Enable/Disable) to enable local APIC,\r
- // and set Spurious Vector as 0x0F.\r
- //\r
- MmioBitFieldWrite32 (ApicBase + APIC_REGISTER_SPURIOUS_VECTOR_OFFSET, 0, 9, 0x10F);\r
-\r
- //\r
- // Program the LINT0 vector entry as ExtInt\r
- // Set bits 8..10 to 7 as ExtInt Delivery Mode,\r
- // and clear bits for Delivery Status, Interrupt Input Pin Polarity, Remote IRR,\r
- // Trigger Mode, and Mask\r
- //\r
- if (!Bsp) {\r
- DisableInterrupts ();\r
- }\r
- Value = MmioRead32 (ApicBase + APIC_REGISTER_LINT0_VECTOR_OFFSET);\r
- Value = BitFieldWrite32 (Value, 8, 10, 7);\r
- Value = BitFieldWrite32 (Value, 12, 16, 0);\r
- if (!Bsp) {\r
- //\r
- // For APs, LINT0 is masked\r
- //\r
- Value = BitFieldWrite32 (Value, 16, 16, 1);\r
- }\r
- MmioWrite32 (ApicBase + APIC_REGISTER_LINT0_VECTOR_OFFSET, Value);\r
-\r
- //\r
- // Program the LINT1 vector entry as NMI\r
- // Set bits 8..10 to 4 as NMI Delivery Mode,\r
- // and clear bits for Delivery Status, Interrupt Input Pin Polarity, Remote IRR,\r
- // Trigger Mode.\r
- // For BSP clear Mask bit, and for AP set mask bit.\r
- //\r
- Value = MmioRead32 (ApicBase + APIC_REGISTER_LINT1_VECTOR_OFFSET);\r
- Value = BitFieldWrite32 (Value, 8, 10, 4);\r
- Value = BitFieldWrite32 (Value, 12, 16, 0);\r
- if (!Bsp) {\r
- //\r
- // For APs, LINT1 is masked\r
- //\r
- Value = BitFieldWrite32 (Value, 16, 16, 1);\r
- }\r
- MmioWrite32 (ApicBase + APIC_REGISTER_LINT1_VECTOR_OFFSET, Value);\r
-}\r
-\r
\r
/**\r
Wrapper function for all procedures assigned to AP.\r
//\r
// Program virtual wire mode for AP, since it will be lost after AP wake up\r
//\r
- ProgramVirtualWireMode (FALSE);\r
+ ProgramVirtualWireMode ();\r
+ DisableLvtInterrupts ();\r
\r
//\r
// Initialize Debug Agent to support source level debug on AP code.\r
ReleaseSpinLock (&CpuData->CpuDataLock);\r
}\r
\r
-/**\r
- Sends INIT-SIPI-SIPI to AP.\r
-\r
- This function sends INIT-SIPI-SIPI to AP, and assign procedure specified by ApFunction.\r
-\r
- @param ProcessorNumber The processor number of the specified AP.\r
- @param ApicID The Local APIC ID of the specified AP.\r
- @param ApFunction The procedure for AP to work on.\r
-\r
-**/\r
-VOID\r
-SendInitSipiSipi (\r
- IN UINTN ProcessorNumber,\r
- IN UINT32 ApicID,\r
- IN VOID *ApFunction\r
- )\r
-{\r
- UINTN ApicBase;\r
- UINT32 ICRLow;\r
- UINT32 ICRHigh;\r
-\r
- UINT32 VectorNumber;\r
- UINT32 DeliveryMode;\r
-\r
- ASSERT (ApicID < MAX_CPU_NUMBER);\r
-\r
- mExchangeInfo->ApFunction = ApFunction;\r
- mExchangeInfo->ProcessorNumber[ApicID] = (UINT32) ProcessorNumber;\r
-\r
- ICRHigh = ApicID << 24;\r
- ICRLow = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;\r
-\r
- VectorNumber = 0;\r
- DeliveryMode = DELIVERY_MODE_INIT;\r
- ICRLow |= VectorNumber | (DeliveryMode << 8);\r
-\r
- ApicBase = (UINTN)AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE, 12, 35) << 12;;\r
-\r
- //\r
- // Write Interrupt Command Registers to send INIT IPI.\r
- //\r
- MmioWrite32 (ApicBase + APIC_REGISTER_ICR_HIGH_OFFSET, ICRHigh);\r
- MmioWrite32 (ApicBase + APIC_REGISTER_ICR_LOW_OFFSET, ICRLow);\r
-\r
- MicroSecondDelay (10);\r
-\r
- VectorNumber = (UINT32) RShiftU64 (mStartupVector, 12);\r
- DeliveryMode = DELIVERY_MODE_SIPI;\r
- ICRLow = SPECIFY_CPU_MODE_BIT | TRIGGER_MODE_LEVEL_BIT | ASSERT_BIT;\r
-\r
- ICRLow |= VectorNumber | (DeliveryMode << 8);\r
-\r
- //\r
- // Write Interrupt Command Register to send first SIPI IPI.\r
- //\r
- MmioWrite32 (ApicBase + APIC_REGISTER_ICR_LOW_OFFSET, ICRLow);\r
-\r
- MicroSecondDelay (200);\r
-\r
- //\r
- // Write Interrupt Command Register to send second SIPI IPI.\r
- //\r
- MmioWrite32 (ApicBase + APIC_REGISTER_ICR_LOW_OFFSET, ICRLow);\r
-}\r
-\r
/**\r
Function to wake up a specified AP and assign procedure to it.\r
\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ mExchangeInfo->ApFunction = (VOID *) (UINTN) ApProcWrapper;\r
+ mExchangeInfo->ProcessorNumber[ProcessorInfoBuffer.ProcessorId] = (UINT32) ProcessorNumber;\r
SendInitSipiSipi (\r
- ProcessorNumber,\r
(UINT32) ProcessorInfoBuffer.ProcessorId,\r
- (VOID *) (UINTN) ApProcWrapper\r
+ (UINT32) (UINTN) mStartupVector\r
);\r
}\r
\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ mExchangeInfo->ApFunction = NULL;\r
+ mExchangeInfo->ProcessorNumber[ProcessorInfoBuffer.ProcessorId] = (UINT32) ProcessorNumber;\r
SendInitSipiSipi (\r
- ProcessorNumber,\r
(UINT32) ProcessorInfoBuffer.ProcessorId,\r
- NULL\r
+ (UINT32) (UINTN) mStartupVector\r
);\r
\r
CpuData = &mMPSystemData.CpuData[ProcessorNumber];\r