\r
#include "MpLib.h"\r
\r
+EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID;\r
+\r
+/**\r
+ Get the Application Processors state.\r
+\r
+ @param[in] CpuData The pointer to CPU_AP_DATA of specified AP\r
+\r
+ @return The AP status\r
+**/\r
+CPU_STATE\r
+GetApState (\r
+ IN CPU_AP_DATA *CpuData\r
+ )\r
+{\r
+ return CpuData->State;\r
+}\r
+\r
+/**\r
+ Set the Application Processors state.\r
+\r
+ @param[in] CpuData The pointer to CPU_AP_DATA of specified AP\r
+ @param[in] State The AP status\r
+**/\r
+VOID\r
+SetApState (\r
+ IN CPU_AP_DATA *CpuData,\r
+ IN CPU_STATE State\r
+ )\r
+{\r
+ AcquireSpinLock (&CpuData->ApLock);\r
+ CpuData->State = State;\r
+ ReleaseSpinLock (&CpuData->ApLock);\r
+}\r
+\r
+/**\r
+ Save the volatile registers required to be restored following INIT IPI.\r
+\r
+ @param[out] VolatileRegisters Returns buffer saved the volatile resisters\r
+**/\r
+VOID\r
+SaveVolatileRegisters (\r
+ OUT CPU_VOLATILE_REGISTERS *VolatileRegisters\r
+ )\r
+{\r
+ CPUID_VERSION_INFO_EDX VersionInfoEdx;\r
+\r
+ VolatileRegisters->Cr0 = AsmReadCr0 ();\r
+ VolatileRegisters->Cr3 = AsmReadCr3 ();\r
+ VolatileRegisters->Cr4 = AsmReadCr4 ();\r
+\r
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);\r
+ if (VersionInfoEdx.Bits.DE != 0) {\r
+ //\r
+ // If processor supports Debugging Extensions feature\r
+ // by CPUID.[EAX=01H]:EDX.BIT2\r
+ //\r
+ VolatileRegisters->Dr0 = AsmReadDr0 ();\r
+ VolatileRegisters->Dr1 = AsmReadDr1 ();\r
+ VolatileRegisters->Dr2 = AsmReadDr2 ();\r
+ VolatileRegisters->Dr3 = AsmReadDr3 ();\r
+ VolatileRegisters->Dr6 = AsmReadDr6 ();\r
+ VolatileRegisters->Dr7 = AsmReadDr7 ();\r
+ }\r
+}\r
+\r
+/**\r
+ Restore the volatile registers following INIT IPI.\r
+\r
+ @param[in] VolatileRegisters Pointer to volatile resisters\r
+ @param[in] IsRestoreDr TRUE: Restore DRx if supported\r
+ FALSE: Do not restore DRx\r
+**/\r
+VOID\r
+RestoreVolatileRegisters (\r
+ IN CPU_VOLATILE_REGISTERS *VolatileRegisters,\r
+ IN BOOLEAN IsRestoreDr\r
+ )\r
+{\r
+ CPUID_VERSION_INFO_EDX VersionInfoEdx;\r
+\r
+ AsmWriteCr0 (VolatileRegisters->Cr0);\r
+ AsmWriteCr3 (VolatileRegisters->Cr3);\r
+ AsmWriteCr4 (VolatileRegisters->Cr4);\r
+\r
+ if (IsRestoreDr) {\r
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);\r
+ if (VersionInfoEdx.Bits.DE != 0) {\r
+ //\r
+ // If processor supports Debugging Extensions feature\r
+ // by CPUID.[EAX=01H]:EDX.BIT2\r
+ //\r
+ AsmWriteDr0 (VolatileRegisters->Dr0);\r
+ AsmWriteDr1 (VolatileRegisters->Dr1);\r
+ AsmWriteDr2 (VolatileRegisters->Dr2);\r
+ AsmWriteDr3 (VolatileRegisters->Dr3);\r
+ AsmWriteDr6 (VolatileRegisters->Dr6);\r
+ AsmWriteDr7 (VolatileRegisters->Dr7);\r
+ }\r
+ }\r
+}\r
\r
/**\r
Detect whether Mwait-monitor feature is supported.\r
\r
return ApLoopMode;\r
}\r
+/*\r
+ Initialize CPU AP Data when AP is wakeup at the first time.\r
+\r
+ @param[in, out] CpuMpData Pointer to PEI CPU MP Data\r
+ @param[in] ProcessorNumber The handle number of processor\r
+ @param[in] BistData Processor BIST data\r
+\r
+**/\r
+VOID\r
+InitializeApData (\r
+ IN OUT CPU_MP_DATA *CpuMpData,\r
+ IN UINTN ProcessorNumber,\r
+ IN UINT32 BistData\r
+ )\r
+{\r
+ CpuMpData->CpuData[ProcessorNumber].Waiting = FALSE;\r
+ CpuMpData->CpuData[ProcessorNumber].Health = BistData;\r
+ CpuMpData->CpuData[ProcessorNumber].CpuHealthy = (BistData == 0) ? TRUE : FALSE;\r
+ CpuMpData->CpuData[ProcessorNumber].ApicId = GetApicId ();\r
+ CpuMpData->CpuData[ProcessorNumber].InitialApicId = GetInitialApicId ();\r
+ if (CpuMpData->CpuData[ProcessorNumber].InitialApicId >= 0xFF) {\r
+ //\r
+ // Set x2APIC mode if there are any logical processor reporting\r
+ // an Initial APIC ID of 255 or greater.\r
+ //\r
+ AcquireSpinLock(&CpuMpData->MpLock);\r
+ CpuMpData->X2ApicEnable = TRUE;\r
+ ReleaseSpinLock(&CpuMpData->MpLock);\r
+ }\r
+\r
+ InitializeSpinLock(&CpuMpData->CpuData[ProcessorNumber].ApLock);\r
+ SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);\r
+}\r
+\r
/**\r
MP Initialize Library initialization.\r
\r
CPU_MP_DATA *CpuMpData;\r
UINT8 ApLoopMode;\r
UINT8 *MonitorBuffer;\r
+ UINTN Index;\r
UINTN ApResetVectorSize;\r
UINTN BackupBufferAddr;\r
MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber);\r
CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);\r
InitializeSpinLock(&CpuMpData->MpLock);\r
//\r
+ // Save BSP's Control registers to APs\r
+ //\r
+ SaveVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters);\r
+ //\r
+ // Set BSP basic information\r
+ //\r
+ InitializeApData (CpuMpData, 0, 0);\r
+ //\r
// Save assembly code information\r
//\r
CopyMem (&CpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP));\r
CpuMpData->ApLoopMode = ApLoopMode;\r
DEBUG ((DEBUG_INFO, "AP Loop Mode is %d\n", CpuMpData->ApLoopMode));\r
//\r
+ // Set up APs wakeup signal buffer\r
+ //\r
+ for (Index = 0; Index < MaxLogicalProcessorNumber; Index++) {\r
+ CpuMpData->CpuData[Index].StartupApSignal =\r
+ (UINT32 *)(MonitorBuffer + MonitorFilterSize * Index);\r
+ }\r
+ //\r
+ // Load Microcode on BSP\r
+ //\r
+ MicrocodeDetect (CpuMpData);\r
+ //\r
// Store BSP's MTRR setting\r
//\r
MtrrGetAllMtrrs (&CpuMpData->MtrrTable);\r
\r
+\r
+ //\r
+ // Initialize global data for MP support\r
+ //\r
+ InitMpGlobalData (CpuMpData);\r
+\r
return EFI_SUCCESS;\r
}\r
\r
{\r
return EFI_UNSUPPORTED;\r
}\r
+/**\r
+ Get pointer to CPU MP Data structure from GUIDed HOB.\r
+\r
+ @return The pointer to CPU MP Data structure.\r
+**/\r
+CPU_MP_DATA *\r
+GetCpuMpDataFromGuidedHob (\r
+ VOID\r
+ )\r
+{\r
+ EFI_HOB_GUID_TYPE *GuidHob;\r
+ VOID *DataInHob;\r
+ CPU_MP_DATA *CpuMpData;\r
+\r
+ CpuMpData = NULL;\r
+ GuidHob = GetFirstGuidHob (&mCpuInitMpLibHobGuid);\r
+ if (GuidHob != NULL) {\r
+ DataInHob = GET_GUID_HOB_DATA (GuidHob);\r
+ CpuMpData = (CPU_MP_DATA *) (*(UINTN *) DataInHob);\r
+ }\r
+ return CpuMpData;\r
+}\r