@retval EFI_SUCCESS Processor information successfully returned.\r
@retval EFI_DEVICE_ERROR Caller processor is AP.\r
@retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL\r
- @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber does not exist. \r
+ @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber does not exist.\r
\r
**/\r
EFI_STATUS\r
ASSERT_EFI_ERROR (Status);\r
\r
ProcessorInfoBuffer->ProcessorId = (UINT64) ProcessorContextBuffer.ApicID;\r
- \r
+\r
//\r
// Get Status Flag of specified processor\r
//\r
@param FailedCpuList The list of processor numbers that fail to finish the function before\r
TimeoutInMicrosecsond expires.\r
\r
- @retval EFI_SUCCESS In blocking mode, all APs have finished before the timeout expired. \r
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before the timeout expired.\r
@retval EFI_SUCCESS In non-blocking mode, function has been dispatched to all enabled APs.\r
@retval EFI_DEVICE_ERROR Caller processor is AP.\r
@retval EFI_NOT_STARTED No enabled AP exists in the system.\r
mStopCheckAPsStatus = FALSE;\r
return EFI_NOT_READY;\r
} else {\r
- // \r
+ //\r
// Mark this processor as responsible for current calling.\r
//\r
mMPSystemData.CpuList[ProcessorNumber] = TRUE;\r
}\r
}\r
}\r
- \r
+\r
//\r
// If no enabled AP exists, return EFI_NOT_STARTED.\r
//\r
@retval EFI_DEVICE_ERROR Caller processor is AP.\r
@retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber does not exist.\r
@retval EFI_INVALID_PARAMETERS ProcessorNumber specifies the BSP.\r
- \r
+\r
**/\r
EFI_STATUS\r
EFIAPI\r
ASSERT_EFI_ERROR (Status);\r
\r
ChangeCpuState (ProcessorNumber, EnableAP);\r
- \r
+\r
return EFI_SUCCESS;\r
}\r
\r
UINTN ProcessorNumber;\r
CPU_DATA_BLOCK *CpuData;\r
EFI_STATUS Status;\r
- \r
+\r
//\r
// If CheckAPsStatus() is stopped, then return immediately.\r
//\r
ASSERT (*mMPSystemData.FailedCpuList != NULL);\r
}\r
ListIndex = 0;\r
- \r
+\r
for (ProcessorNumber = 0; ProcessorNumber < mNumberOfProcessors; ProcessorNumber++) {\r
//\r
// Check whether this processor is responsible for StartupAllAPs().\r
AcquireSpinLock (&CpuData->CpuDataLock);\r
CpuData->State = CpuStateIdle;\r
ReleaseSpinLock (&CpuData->CpuDataLock);\r
- \r
+\r
if (CpuData->Finished != NULL) {\r
*(CpuData->Finished) = TRUE;\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 (27, 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
UINTN ProcessorNumber;\r
CPU_DATA_BLOCK *CpuData;\r
\r
+ ProgramVirtualWireMode (FALSE);\r
+\r
WhoAmI (&mMpService, &ProcessorNumber);\r
CpuData = &mMPSystemData.CpuData[ProcessorNumber];\r
\r
UINTN ApicBase;\r
UINT32 ICRLow;\r
UINT32 ICRHigh;\r
- \r
+\r
UINT32 VectorNumber;\r
UINT32 DeliveryMode;\r
\r
\r
/**\r
Function to wake up a specified AP and assign procedure to it.\r
- \r
+\r
@param ProcessorNumber Handle number of the specified processor.\r
@param Procedure Procedure to assign.\r
@param ProcArguments Argument for Procedure.\r
\r
/**\r
Terminate AP's task and set it to idle state.\r
- \r
+\r
This function terminates AP's task due to timeout by sending INIT-SIPI,\r
and sends it to idle state.\r
\r
{\r
MP_ASSEMBLY_ADDRESS_MAP AddressMap;\r
IA32_DESCRIPTOR GdtrForBSP;\r
+ IA32_DESCRIPTOR IdtrForBSP;\r
EFI_PHYSICAL_ADDRESS GdtForAP;\r
+ EFI_PHYSICAL_ADDRESS IdtForAP;\r
EFI_STATUS Status;\r
\r
//\r
mExchangeInfo->StackSize = AP_STACK_SIZE;\r
\r
AsmReadGdtr (&GdtrForBSP);\r
+ AsmReadIdtr (&IdtrForBSP);\r
\r
//\r
// Allocate memory under 4G to hold GDT for APs\r
Status = gBS->AllocatePages (\r
AllocateMaxAddress,\r
EfiBootServicesData,\r
- EFI_SIZE_TO_PAGES (GdtrForBSP.Limit + 1),\r
+ EFI_SIZE_TO_PAGES ((GdtrForBSP.Limit + 1) + (IdtrForBSP.Limit + 1)),\r
&GdtForAP\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ IdtForAP = (UINTN) GdtForAP + GdtrForBSP.Limit + 1;\r
+\r
CopyMem ((VOID *) (UINTN) GdtForAP, (VOID *) GdtrForBSP.Base, GdtrForBSP.Limit + 1);\r
+ CopyMem ((VOID *) (UINTN) IdtForAP, (VOID *) IdtrForBSP.Base, IdtrForBSP.Limit + 1);\r
\r
mExchangeInfo->GdtrProfile.Base = (UINTN) GdtForAP;\r
mExchangeInfo->GdtrProfile.Limit = GdtrForBSP.Limit;\r
+ mExchangeInfo->IdtrProfile.Base = (UINTN) IdtForAP;\r
+ mExchangeInfo->IdtrProfile.Limit = IdtrForBSP.Limit;\r
\r
mExchangeInfo->BufferStart = (UINT32) mStartupVector;\r
mExchangeInfo->Cr3 = (UINT32) (AsmReadCr3 ());\r
\r
/**\r
Prepares memory region for processor configuration.\r
- \r
+\r
This function prepares memory region for processor configuration.\r
\r
**/\r
for (Index = 0; Index < MAX_CPU_NUMBER; Index++) {\r
InitializeSpinLock (&mMPSystemData.CpuData[Index].CpuDataLock);\r
}\r
- \r
+\r
PrepareAPStartupVector ();\r
}\r
\r
/**\r
Gets the processor number of BSP.\r
- \r
+\r
@return The processor number of BSP.\r
\r
**/\r
&ProcessorContextBuffer\r
);\r
ASSERT_EFI_ERROR (Status);\r
- \r
+\r
if (ProcessorContextBuffer.Designation == EfiCpuBSP) {\r
break;\r
}\r
/**\r
Entrypoint of MP Services Protocol thunk driver.\r
\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
@param[in] SystemTable A pointer to the EFI System Table.\r
- \r
+\r
@retval EFI_SUCCESS The entry point is executed successfully.\r
\r
**/\r
// Locates Framework version MP Services Protocol\r
//\r
Status = gBS->LocateProtocol (\r
- &gFrameworkEfiMpServiceProtocolGuid, \r
- NULL, \r
+ &gFrameworkEfiMpServiceProtocolGuid,\r
+ NULL,\r
(VOID **) &mFrameworkMpService\r
);\r
ASSERT_EFI_ERROR (Status);\r