#include <Library/MtrrLib.h>\r
#include <Library/HobLib.h>\r
\r
+#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')\r
+\r
+#define CPU_INIT_MP_LIB_HOB_GUID \\r
+ { \\r
+ 0x58eb6a19, 0x3699, 0x4c68, { 0xa8, 0x36, 0xda, 0xcd, 0x8e, 0xdc, 0xad, 0x4a } \\r
+ }\r
+\r
+//\r
+// AP loop state when APs are in idle state\r
+// It's value is the same with PcdCpuApLoopMode\r
+//\r
+typedef enum {\r
+ ApInHltLoop = 1,\r
+ ApInMwaitLoop = 2,\r
+ ApInRunLoop = 3\r
+} AP_LOOP_MODE;\r
+\r
+//\r
+// AP initialization state during APs wakeup\r
+//\r
+typedef enum {\r
+ ApInitConfig = 1,\r
+ ApInitReconfig = 2,\r
+ ApInitDone = 3\r
+} AP_INIT_STATE;\r
+\r
+//\r
+// AP state\r
+//\r
+typedef enum {\r
+ CpuStateIdle,\r
+ CpuStateReady,\r
+ CpuStateBusy,\r
+ CpuStateFinished,\r
+ CpuStateDisabled\r
+} CPU_STATE;\r
+\r
+//\r
+// CPU volatile registers around INIT-SIPI-SIPI\r
+//\r
+typedef struct {\r
+ UINTN Cr0;\r
+ UINTN Cr3;\r
+ UINTN Cr4;\r
+ UINTN Dr0;\r
+ UINTN Dr1;\r
+ UINTN Dr2;\r
+ UINTN Dr3;\r
+ UINTN Dr6;\r
+ UINTN Dr7;\r
+} CPU_VOLATILE_REGISTERS;\r
+\r
+//\r
+// AP related data\r
+//\r
+typedef struct {\r
+ SPIN_LOCK ApLock;\r
+ volatile UINT32 *StartupApSignal;\r
+ volatile UINTN ApFunction;\r
+ volatile UINTN ApFunctionArgument;\r
+ UINT32 InitialApicId;\r
+ UINT32 ApicId;\r
+ UINT32 Health;\r
+ BOOLEAN CpuHealthy;\r
+ volatile CPU_STATE State;\r
+ CPU_VOLATILE_REGISTERS VolatileRegisters;\r
+ BOOLEAN Waiting;\r
+ BOOLEAN *Finished;\r
+ UINT64 ExpectedTime;\r
+ UINT64 CurrentTime;\r
+ UINT64 TotalTime;\r
+ EFI_EVENT WaitEvent;\r
+} CPU_AP_DATA;\r
+\r
+//\r
+// Basic CPU information saved in Guided HOB.\r
+// Because the contents will be shard between PEI and DXE,\r
+// we need to make sure the each fields offset same in different\r
+// architecture.\r
+//\r
+typedef struct {\r
+ UINT32 InitialApicId;\r
+ UINT32 ApicId;\r
+ UINT32 Health;\r
+} CPU_INFO_IN_HOB;\r
+\r
+//\r
+// AP reset code information including code address and size,\r
+// this structure will be shared be C code and assembly code.\r
+// It is natural aligned by design.\r
+//\r
+typedef struct {\r
+ UINT8 *RendezvousFunnelAddress;\r
+ UINTN ModeEntryOffset;\r
+ UINTN RendezvousFunnelSize;\r
+ UINT8 *RelocateApLoopFuncAddress;\r
+ UINTN RelocateApLoopFuncSize;\r
+} MP_ASSEMBLY_ADDRESS_MAP;\r
+\r
+typedef struct _CPU_MP_DATA CPU_MP_DATA;\r
\r
#pragma pack(1)\r
\r
UINTN DataSegment;\r
UINTN EnableExecuteDisable;\r
UINTN Cr3;\r
+ CPU_MP_DATA *CpuMpData;\r
} MP_CPU_EXCHANGE_INFO;\r
\r
#pragma pack()\r
+\r
+//\r
+// CPU MP Data save in memory\r
+//\r
+struct _CPU_MP_DATA {\r
+ UINT64 CpuInfoInHob;\r
+ UINT32 CpuCount;\r
+ UINT32 BspNumber;\r
+ //\r
+ // The above fields data will be passed from PEI to DXE\r
+ // Please make sure the fields offset same in the different\r
+ // architecture.\r
+ //\r
+ SPIN_LOCK MpLock;\r
+ UINTN Buffer;\r
+ UINTN CpuApStackSize;\r
+ MP_ASSEMBLY_ADDRESS_MAP AddressMap;\r
+ UINTN WakeupBuffer;\r
+ UINTN BackupBuffer;\r
+ UINTN BackupBufferSize;\r
+ BOOLEAN EndOfPeiFlag;\r
+\r
+ volatile UINT32 StartCount;\r
+ volatile UINT32 FinishedCount;\r
+ volatile UINT32 RunningCount;\r
+ BOOLEAN SingleThread;\r
+ EFI_AP_PROCEDURE Procedure;\r
+ VOID *ProcArguments;\r
+ BOOLEAN *Finished;\r
+ UINT64 ExpectedTime;\r
+ UINT64 CurrentTime;\r
+ UINT64 TotalTime;\r
+ EFI_EVENT WaitEvent;\r
+ UINTN **FailedCpuList;\r
+\r
+ AP_INIT_STATE InitFlag;\r
+ BOOLEAN X2ApicEnable;\r
+ MTRR_SETTINGS MtrrTable;\r
+ UINT8 ApLoopMode;\r
+ UINT8 ApTargetCState;\r
+ UINT16 PmCodeSegment;\r
+ CPU_AP_DATA *CpuData;\r
+ volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;\r
+};\r
+\r
+extern EFI_GUID mCpuInitMpLibHobGuid;\r
+\r
+/**\r
+ Assembly code to place AP into safe loop mode.\r
+\r
+ Place AP into targeted C-State if MONITOR is supported, otherwise\r
+ place AP into hlt state.\r
+ Place AP in protected mode if the current is long mode. Due to AP maybe\r
+ wakeup by some hardware event. It could avoid accessing page table that\r
+ may not available during booting to OS.\r
+\r
+ @param[in] MwaitSupport TRUE indicates MONITOR is supported.\r
+ FALSE indicates MONITOR is not supported.\r
+ @param[in] ApTargetCState Target C-State value.\r
+ @param[in] PmCodeSegment Protected mode code segment value.\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI * ASM_RELOCATE_AP_LOOP) (\r
+ IN BOOLEAN MwaitSupport,\r
+ IN UINTN ApTargetCState,\r
+ IN UINTN PmCodeSegment\r
+ );\r
+\r
+/**\r
+ Assembly code to get starting address and size of the rendezvous entry for APs.\r
+ Information for fixing a jump instruction in the code is also returned.\r
+\r
+ @param[out] AddressMap Output buffer for address map information.\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmGetAddressMap (\r
+ OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap\r
+ );\r
+\r
+/**\r
+ Get the pointer to CPU MP Data structure.\r
+\r
+ @return The pointer to CPU MP Data structure.\r
+**/\r
+CPU_MP_DATA *\r
+GetCpuMpData (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Save the pointer to CPU MP Data structure.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure will be saved.\r
+**/\r
+VOID\r
+SaveCpuMpData (\r
+ IN CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
+/**\r
+ Allocate reset vector buffer.\r
+\r
+ @param[in, out] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+AllocateResetVector (\r
+ IN OUT CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
+/**\r
+ Free AP reset vector buffer.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+FreeResetVector (\r
+ IN CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
+/**\r
+ This function will be called by BSP to wakeup AP.\r
+\r
+ @param[in] CpuMpData Pointer to CPU MP Data\r
+ @param[in] Broadcast TRUE: Send broadcast IPI to all APs\r
+ FALSE: Send IPI to AP by ApicId\r
+ @param[in] ProcessorNumber The handle number of specified processor\r
+ @param[in] Procedure The function to be invoked by AP\r
+ @param[in] ProcedureArgument The argument to be passed into AP function\r
+**/\r
+VOID\r
+WakeUpAP (\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ IN BOOLEAN Broadcast,\r
+ IN UINTN ProcessorNumber,\r
+ IN EFI_AP_PROCEDURE Procedure, OPTIONAL\r
+ IN VOID *ProcedureArgument OPTIONAL\r
+ );\r
+\r
+/**\r
+ Initialize global data for MP support.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+InitMpGlobalData (\r
+ IN CPU_MP_DATA *CpuMpData\r
+ );\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
+/**\r
+ Detect whether specified processor can find matching microcode patch and load it.\r
+\r
+ @param[in] PeiCpuMpData Pointer to PEI CPU MP Data\r
+**/\r
+VOID\r
+MicrocodeDetect (\r
+ IN CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
+/**\r
+ Notify function on End Of PEI PPI.\r
+\r
+ On S3 boot, this function will restore wakeup buffer data.\r
+ On normal boot, this function will flag wakeup buffer to be un-used type.\r
+\r
+ @param[in] PeiServices The pointer to the PEI Services Table.\r
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
+ @param[in] Ppi Address of the PPI that was installed.\r
+\r
+ @retval EFI_SUCCESS When everything is OK.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CpuMpEndOfPeiCallback (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
+ IN VOID *Ppi\r
+ );\r
+\r
#endif\r
\r