\r
#include "CpuMpPei.h"\r
\r
-//\r
-// Global Descriptor Table (GDT)\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = {\r
-/* selector { Global Segment Descriptor } */\r
-/* 0x00 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, //null descriptor\r
-/* 0x08 */ {{0xffff, 0, 0, 0x2, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}}, //linear data segment descriptor\r
-/* 0x10 */ {{0xffff, 0, 0, 0xf, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}}, //linear code segment descriptor\r
-/* 0x18 */ {{0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}}, //system data segment descriptor\r
-/* 0x20 */ {{0xffff, 0, 0, 0xa, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}}, //system code segment descriptor\r
-/* 0x28 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, //spare segment descriptor\r
-/* 0x30 */ {{0xffff, 0, 0, 0x2, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}}, //system data segment descriptor\r
-/* 0x38 */ {{0xffff, 0, 0, 0xa, 1, 0, 1, 0xf, 0, 1, 0, 1, 0}}, //system code segment descriptor\r
-/* 0x40 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, //spare segment descriptor\r
-};\r
-\r
-//\r
-// IA32 Gdt register\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = {\r
- sizeof (mGdtEntries) - 1,\r
- (UINTN) mGdtEntries\r
- };\r
-\r
GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {\r
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
&gEfiEndOfPeiSignalPpiGuid,\r
\r
@param PeiCpuMpData Pointer to PEI CPU MP Data\r
**/\r
+STATIC\r
VOID\r
SortApicId (\r
IN PEI_CPU_MP_DATA *PeiCpuMpData\r
\r
@param Buffer Pointer to private data buffer.\r
**/\r
+STATIC\r
VOID\r
EFIAPI\r
ApFuncEnableX2Apic (\r
\r
@return The AP loop mode.\r
**/\r
+STATIC\r
UINT8\r
GetApLoopMode (\r
OUT UINT16 *MonitorFilterSize\r
\r
@param VolatileRegisters Returns buffer saved the volatile resisters\r
**/\r
+STATIC\r
VOID\r
SaveVolatileRegisters (\r
OUT CPU_VOLATILE_REGISTERS *VolatileRegisters\r
@param IsRestoreDr TRUE: Restore DRx if supported\r
FALSE: Do not restore DRx\r
**/\r
+STATIC\r
VOID\r
RestoreVolatileRegisters (\r
IN CPU_VOLATILE_REGISTERS *VolatileRegisters,\r
}\r
}\r
\r
+/**\r
+ Find the current Processor number by APIC ID.\r
+\r
+ @param PeiCpuMpData Pointer to PEI CPU MP Data\r
+ @param ProcessorNumber Return the pocessor number found\r
+\r
+ @retval EFI_SUCCESS ProcessorNumber is found and returned.\r
+ @retval EFI_NOT_FOUND ProcessorNumber is not found.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GetProcessorNumber (\r
+ IN PEI_CPU_MP_DATA *PeiCpuMpData,\r
+ OUT UINTN *ProcessorNumber\r
+ )\r
+{\r
+ UINTN TotalProcessorNumber;\r
+ UINTN Index;\r
+\r
+ TotalProcessorNumber = PeiCpuMpData->CpuCount;\r
+ for (Index = 0; Index < TotalProcessorNumber; Index ++) {\r
+ if (PeiCpuMpData->CpuData[Index].ApicId == GetInitialApicId ()) {\r
+ *ProcessorNumber = Index;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
/**\r
This function will be called from AP reset code if BSP uses WakeUpAP.\r
\r
@param ExchangeInfo Pointer to the MP exchange info buffer\r
@param NumApsExecuting Number of current executing AP\r
**/\r
+STATIC\r
VOID\r
EFIAPI\r
ApCFunction (\r
@param Procedure The function to be invoked by AP\r
@param ProcedureArgument The argument to be passed into AP function\r
**/\r
+STATIC\r
VOID\r
WakeUpAP (\r
IN PEI_CPU_MP_DATA *PeiCpuMpData,\r
ExchangeInfo->StackStart = PeiCpuMpData->Buffer;\r
ExchangeInfo->StackSize = PeiCpuMpData->CpuApStackSize;\r
ExchangeInfo->BufferStart = PeiCpuMpData->WakeupBuffer;\r
- ExchangeInfo->PmodeOffset = PeiCpuMpData->AddressMap.PModeEntryOffset;\r
- ExchangeInfo->LmodeOffset = PeiCpuMpData->AddressMap.LModeEntryOffset;\r
+ ExchangeInfo->ModeOffset = PeiCpuMpData->AddressMap.ModeEntryOffset;\r
ExchangeInfo->Cr3 = AsmReadCr3 ();\r
+ ExchangeInfo->CodeSegment = AsmReadCs ();\r
+ ExchangeInfo->DataSegment = AsmReadDs ();\r
ExchangeInfo->CFunction = (UINTN) ApCFunction;\r
ExchangeInfo->NumApsExecuting = 0;\r
ExchangeInfo->PeiCpuMpData = PeiCpuMpData;\r
//\r
// Get the BSP's data of GDT and IDT\r
//\r
- CopyMem ((VOID *)&ExchangeInfo->GdtrProfile, &mGdt, sizeof(mGdt));\r
+ AsmReadGdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->GdtrProfile);\r
AsmReadIdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->IdtrProfile);\r
\r
if (PeiCpuMpData->ApLoopMode == ApInMwaitLoop) {\r
@retval other Return wakeup buffer address below 1MB.\r
@retval -1 Cannot find free memory below 1MB.\r
**/\r
+STATIC\r
UINTN\r
GetWakeupBuffer (\r
IN UINTN WakeupBufferSize\r
\r
@param PeiCpuMpData Pointer to PEI CPU MP Data\r
**/\r
+STATIC\r
VOID\r
BackupAndPrepareWakeupBuffer(\r
IN PEI_CPU_MP_DATA *PeiCpuMpData\r
\r
@param PeiCpuMpData Pointer to PEI CPU MP Data\r
**/\r
+STATIC\r
VOID\r
RestoreWakeupBuffer(\r
IN PEI_CPU_MP_DATA *PeiCpuMpData\r
@retval EFI_SUCCESS When everything is OK.\r
\r
**/\r
+STATIC\r
EFI_STATUS\r
EFIAPI\r
CpuMpEndOfPeiCallback (\r
IN CONST EFI_PEI_SERVICES **PeiServices\r
)\r
{\r
- EFI_STATUS Status;\r
- PEI_CPU_MP_DATA *PeiCpuMpData;\r
+ EFI_STATUS Status;\r
EFI_VECTOR_HANDOFF_INFO *VectorInfo;\r
EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;\r
\r
- //\r
- // Load new GDT table on BSP\r
- //\r
- AsmInitializeGdt (&mGdt);\r
//\r
// Get Vector Hand-off Info PPI\r
//\r
}\r
Status = InitializeCpuExceptionHandlers (VectorInfo);\r
ASSERT_EFI_ERROR (Status);\r
+ \r
//\r
- // Get wakeup buffer and copy AP reset code in it\r
- //\r
- PeiCpuMpData = PrepareAPStartupVector ();\r
- //\r
- // Count processor number and collect processor information\r
- //\r
- CountProcessorNumber (PeiCpuMpData);\r
- //\r
- // Build location of PEI CPU MP DATA buffer in HOB\r
+ // Wakeup APs to do initialization\r
//\r
- BuildGuidDataHob (\r
- &gEfiCallerIdGuid,\r
- (VOID *)&PeiCpuMpData,\r
- sizeof(UINT64)\r
- );\r
+ Status = MpInitLibInitialize ();\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
//\r
// Update and publish CPU BIST information\r
//\r
- CollectBistDataFromPpi (PeiServices, PeiCpuMpData);\r
- //\r
- // register an event for EndOfPei\r
- //\r
- Status = PeiServicesNotifyPpi (&mNotifyList);\r
- ASSERT_EFI_ERROR (Status);\r
+ CollectBistDataFromPpi (PeiServices);\r
+\r
//\r
// Install CPU MP PPI\r
//\r