#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
+// The MP data for switch BSP\r
+//\r
+#define CPU_SWITCH_STATE_IDLE 0\r
+#define CPU_SWITCH_STATE_STORED 1\r
+#define CPU_SWITCH_STATE_LOADED 2\r
+\r
+//\r
+// CPU exchange information for switch BSP\r
+//\r
+typedef struct {\r
+ UINT8 State; // offset 0\r
+ UINTN StackPointer; // offset 4 / 8\r
+ IA32_DESCRIPTOR Gdtr; // offset 8 / 16\r
+ IA32_DESCRIPTOR Idtr; // offset 14 / 26\r
+} CPU_EXCHANGE_ROLE_INFO;\r
+\r
//\r
// AP loop state when APs are in idle state\r
// It's value is the same with PcdCpuApLoopMode\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
UINTN DataSegment;\r
UINTN EnableExecuteDisable;\r
UINTN Cr3;\r
+ UINTN InitFlag;\r
+ CPU_INFO_IN_HOB *CpuInfo;\r
CPU_MP_DATA *CpuMpData;\r
} MP_CPU_EXCHANGE_INFO;\r
\r
UINTN WakeupBuffer;\r
UINTN BackupBuffer;\r
UINTN BackupBufferSize;\r
- BOOLEAN EndOfPeiFlag;\r
+ BOOLEAN SaveRestoreFlag;\r
\r
volatile UINT32 StartCount;\r
volatile UINT32 FinishedCount;\r
\r
AP_INIT_STATE InitFlag;\r
BOOLEAN X2ApicEnable;\r
+ BOOLEAN SwitchBspFlag;\r
+ CPU_EXCHANGE_ROLE_INFO BSPInfo;\r
+ CPU_EXCHANGE_ROLE_INFO APInfo;\r
MTRR_SETTINGS MtrrTable;\r
UINT8 ApLoopMode;\r
UINT8 ApTargetCState;\r
OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap\r
);\r
\r
+/**\r
+ This function is called by both the BSP and the AP which is to become the BSP to\r
+ Exchange execution context including stack between them. After return from this\r
+ function, the BSP becomes AP and the AP becomes the BSP.\r
+\r
+ @param[in] MyInfo Pointer to buffer holding the exchanging information for the executing processor.\r
+ @param[in] OthersInfo Pointer to buffer holding the exchanging information for the peer.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmExchangeRole (\r
+ IN CPU_EXCHANGE_ROLE_INFO *MyInfo,\r
+ IN CPU_EXCHANGE_ROLE_INFO *OthersInfo\r
+ );\r
+\r
/**\r
Get the pointer to CPU MP Data structure.\r
\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
IN CPU_MP_DATA *CpuMpData\r
);\r
\r
+/**\r
+ Worker function to execute a caller provided function on all enabled APs.\r
+\r
+ @param[in] Procedure A pointer to the function to be run on\r
+ enabled APs of the system.\r
+ @param[in] SingleThread If TRUE, then all the enabled APs execute\r
+ the function specified by Procedure one by\r
+ one, in ascending order of processor handle\r
+ number. If FALSE, then all the enabled APs\r
+ execute the function specified by Procedure\r
+ simultaneously.\r
+ @param[in] WaitEvent The event created by the caller with CreateEvent()\r
+ service.\r
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for\r
+ APs to return from Procedure, either for\r
+ blocking or non-blocking mode.\r
+ @param[in] ProcedureArgument The parameter passed into Procedure for\r
+ all APs.\r
+ @param[out] FailedCpuList If all APs finish successfully, then its\r
+ content is set to NULL. If not all APs\r
+ finish before timeout expires, then its\r
+ content is set to address of the buffer\r
+ holding handle numbers of the failed APs.\r
+\r
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before\r
+ the timeout expired.\r
+ @retval EFI_SUCCESS In non-blocking mode, function has been dispatched\r
+ to all enabled APs.\r
+ @retval others Failed to Startup all APs.\r
+\r
+**/\r
+EFI_STATUS\r
+StartupAllAPsWorker (\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN BOOLEAN SingleThread,\r
+ IN EFI_EVENT WaitEvent OPTIONAL,\r
+ IN UINTN TimeoutInMicroseconds,\r
+ IN VOID *ProcedureArgument OPTIONAL,\r
+ OUT UINTN **FailedCpuList OPTIONAL\r
+ );\r
+\r
+/**\r
+ Worker function to let the caller get one enabled AP to execute a caller-provided\r
+ function.\r
+\r
+ @param[in] Procedure A pointer to the function to be run on\r
+ enabled APs of the system.\r
+ @param[in] ProcessorNumber The handle number of the AP.\r
+ @param[in] WaitEvent The event created by the caller with CreateEvent()\r
+ service.\r
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for\r
+ APs to return from Procedure, either for\r
+ blocking or non-blocking mode.\r
+ @param[in] ProcedureArgument The parameter passed into Procedure for\r
+ all APs.\r
+ @param[out] Finished If AP returns from Procedure before the\r
+ timeout expires, its content is set to TRUE.\r
+ Otherwise, the value is set to FALSE.\r
+\r
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before\r
+ the timeout expires.\r
+ @retval others Failed to Startup AP.\r
+\r
+**/\r
+EFI_STATUS\r
+StartupThisAPWorker (\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN UINTN ProcessorNumber,\r
+ IN EFI_EVENT WaitEvent OPTIONAL,\r
+ IN UINTN TimeoutInMicroseconds,\r
+ IN VOID *ProcedureArgument OPTIONAL,\r
+ OUT BOOLEAN *Finished OPTIONAL\r
+ );\r
+\r
+/**\r
+ Worker function to switch the requested AP to be the BSP from that point onward.\r
+\r
+ @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.\r
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an\r
+ enabled AP. Otherwise, it will be disabled.\r
+\r
+ @retval EFI_SUCCESS BSP successfully switched.\r
+ @retval others Failed to switch BSP. \r
+\r
+**/\r
+EFI_STATUS\r
+SwitchBSPWorker (\r
+ IN UINTN ProcessorNumber,\r
+ IN BOOLEAN EnableOldBSP\r
+ );\r
+\r
+/**\r
+ Worker function to let the caller enable or disable an AP from this point onward.\r
+ This service may only be called from the BSP.\r
+\r
+ @param[in] ProcessorNumber The handle number of AP.\r
+ @param[in] EnableAP Specifies the new state for the processor for\r
+ enabled, FALSE for disabled.\r
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies\r
+ the new health status of the AP.\r
+\r
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.\r
+ @retval others Failed to Enable/Disable AP.\r
+\r
+**/\r
+EFI_STATUS\r
+EnableDisableApWorker (\r
+ IN UINTN ProcessorNumber,\r
+ IN BOOLEAN EnableAP,\r
+ IN UINT32 *HealthFlag OPTIONAL\r
+ );\r
+\r
/**\r
Get pointer to CPU MP Data structure from GUIDed HOB.\r
\r
GetCpuMpDataFromGuidedHob (\r
VOID\r
);\r
- \r
+\r
+/** Checks status of specified AP.\r
+\r
+ This function checks whether the specified AP has finished the task assigned\r
+ by StartupThisAP(), and whether timeout expires.\r
+\r
+ @param[in] ProcessorNumber The handle number of processor.\r
+\r
+ @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs().\r
+ @retval EFI_TIMEOUT The timeout expires.\r
+ @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired.\r
+**/\r
+EFI_STATUS\r
+CheckThisAP (\r
+ IN UINTN ProcessorNumber\r
+ );\r
+\r
+/**\r
+ Checks status of all APs.\r
+\r
+ This function checks whether all APs have finished task assigned by StartupAllAPs(),\r
+ and whether timeout expires.\r
+\r
+ @retval EFI_SUCCESS All APs have finished task assigned by StartupAllAPs().\r
+ @retval EFI_TIMEOUT The timeout expires.\r
+ @retval EFI_NOT_READY APs have not finished task and timeout has not expired.\r
+**/\r
+EFI_STATUS\r
+CheckAllAPs (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Checks APs status and updates APs status if needed.\r
+\r
+**/\r
+VOID\r
+CheckAndUpdateApsStatus (\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
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
**/\r
VOID\r
MicrocodeDetect (\r
IN CPU_MP_DATA *CpuMpData\r
);\r
\r
+/**\r
+ Detect whether Mwait-monitor feature is supported.\r
+\r
+ @retval TRUE Mwait-monitor feature is supported.\r
+ @retval FALSE Mwait-monitor feature is not supported.\r
+**/\r
+BOOLEAN\r
+IsMwaitSupport (\r
+ VOID\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
+/**\r
+ Get available system memory below 1MB by specified size.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+BackupAndPrepareWakeupBuffer(\r
+ IN CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
+/**\r
+ Restore wakeup buffer data.\r
+\r
+ @param[in] CpuMpData The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+RestoreWakeupBuffer(\r
+ IN CPU_MP_DATA *CpuMpData\r
+ );\r
+\r
#endif\r
\r