X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=UefiCpuPkg%2FLibrary%2FMpInitLib%2FMpLib.h;h=e6dea18428768f7fdc6b03136e4efa268130e65b;hb=bf2786dc7900cb5ef04c9c5c720c0a26f11898b8;hp=d3ccac8d06b7528321425dfe2b9b849ed94fa8f5;hpb=93ca4c0fd7d96f182790e56f147463ab1799da2a;p=mirror_edk2.git diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index d3ccac8d06..e6dea18428 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -35,11 +35,30 @@ #include #include +#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P') + #define CPU_INIT_MP_LIB_HOB_GUID \ { \ 0x58eb6a19, 0x3699, 0x4c68, { 0xa8, 0x36, 0xda, 0xcd, 0x8e, 0xdc, 0xad, 0x4a } \ } +// +// The MP data for switch BSP +// +#define CPU_SWITCH_STATE_IDLE 0 +#define CPU_SWITCH_STATE_STORED 1 +#define CPU_SWITCH_STATE_LOADED 2 + +// +// CPU exchange information for switch BSP +// +typedef struct { + UINT8 State; // offset 0 + UINTN StackPointer; // offset 4 / 8 + IA32_DESCRIPTOR Gdtr; // offset 8 / 16 + IA32_DESCRIPTOR Idtr; // offset 14 / 26 +} CPU_EXCHANGE_ROLE_INFO; + // // AP loop state when APs are in idle state // It's value is the same with PcdCpuApLoopMode @@ -93,9 +112,6 @@ typedef struct { volatile UINT32 *StartupApSignal; volatile UINTN ApFunction; volatile UINTN ApFunctionArgument; - UINT32 InitialApicId; - UINT32 ApicId; - UINT32 Health; BOOLEAN CpuHealthy; volatile CPU_STATE State; CPU_VOLATILE_REGISTERS VolatileRegisters; @@ -113,11 +129,14 @@ typedef struct { // we need to make sure the each fields offset same in different // architecture. // +#pragma pack (1) typedef struct { UINT32 InitialApicId; UINT32 ApicId; UINT32 Health; + UINT64 ApTopOfStack; } CPU_INFO_IN_HOB; +#pragma pack () // // AP reset code information including code address and size, @@ -155,6 +174,8 @@ typedef struct { UINTN DataSegment; UINTN EnableExecuteDisable; UINTN Cr3; + UINTN InitFlag; + CPU_INFO_IN_HOB *CpuInfo; CPU_MP_DATA *CpuMpData; } MP_CPU_EXCHANGE_INFO; @@ -179,7 +200,7 @@ struct _CPU_MP_DATA { UINTN WakeupBuffer; UINTN BackupBuffer; UINTN BackupBufferSize; - BOOLEAN EndOfPeiFlag; + BOOLEAN SaveRestoreFlag; volatile UINT32 StartCount; volatile UINT32 FinishedCount; @@ -196,6 +217,10 @@ struct _CPU_MP_DATA { AP_INIT_STATE InitFlag; BOOLEAN X2ApicEnable; + BOOLEAN SwitchBspFlag; + UINTN NewBspNumber; + CPU_EXCHANGE_ROLE_INFO BSPInfo; + CPU_EXCHANGE_ROLE_INFO APInfo; MTRR_SETTINGS MtrrTable; UINT8 ApLoopMode; UINT8 ApTargetCState; @@ -225,7 +250,8 @@ VOID (EFIAPI * ASM_RELOCATE_AP_LOOP) ( IN BOOLEAN MwaitSupport, IN UINTN ApTargetCState, - IN UINTN PmCodeSegment + IN UINTN PmCodeSegment, + IN UINTN TopOfApStack ); /** @@ -240,6 +266,22 @@ AsmGetAddressMap ( OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap ); +/** + This function is called by both the BSP and the AP which is to become the BSP to + Exchange execution context including stack between them. After return from this + function, the BSP becomes AP and the AP becomes the BSP. + + @param[in] MyInfo Pointer to buffer holding the exchanging information for the executing processor. + @param[in] OthersInfo Pointer to buffer holding the exchanging information for the peer. + +**/ +VOID +EFIAPI +AsmExchangeRole ( + IN CPU_EXCHANGE_ROLE_INFO *MyInfo, + IN CPU_EXCHANGE_ROLE_INFO *OthersInfo + ); + /** Get the pointer to CPU MP Data structure. @@ -260,6 +302,45 @@ SaveCpuMpData ( IN CPU_MP_DATA *CpuMpData ); +/** + Allocate reset vector buffer. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +AllocateResetVector ( + IN OUT CPU_MP_DATA *CpuMpData + ); + +/** + Free AP reset vector buffer. + + @param[in] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +FreeResetVector ( + IN CPU_MP_DATA *CpuMpData + ); + +/** + This function will be called by BSP to wakeup AP. + + @param[in] CpuMpData Pointer to CPU MP Data + @param[in] Broadcast TRUE: Send broadcast IPI to all APs + FALSE: Send IPI to AP by ApicId + @param[in] ProcessorNumber The handle number of specified processor + @param[in] Procedure The function to be invoked by AP + @param[in] ProcedureArgument The argument to be passed into AP function +**/ +VOID +WakeUpAP ( + IN CPU_MP_DATA *CpuMpData, + IN BOOLEAN Broadcast, + IN UINTN ProcessorNumber, + IN EFI_AP_PROCEDURE Procedure, OPTIONAL + IN VOID *ProcedureArgument OPTIONAL + ); + /** Initialize global data for MP support. @@ -270,6 +351,118 @@ InitMpGlobalData ( IN CPU_MP_DATA *CpuMpData ); +/** + Worker function to execute a caller provided function on all enabled APs. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. + @param[in] SingleThread If TRUE, then all the enabled APs execute + the function specified by Procedure one by + one, in ascending order of processor handle + number. If FALSE, then all the enabled APs + execute the function specified by Procedure + simultaneously. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. + @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] FailedCpuList If all APs finish successfully, then its + content is set to NULL. If not all APs + finish before timeout expires, then its + content is set to address of the buffer + holding handle numbers of the failed APs. + + @retval EFI_SUCCESS In blocking mode, all APs have finished before + the timeout expired. + @retval EFI_SUCCESS In non-blocking mode, function has been dispatched + to all enabled APs. + @retval others Failed to Startup all APs. + +**/ +EFI_STATUS +StartupAllAPsWorker ( + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL + ); + +/** + Worker function to let the caller get one enabled AP to execute a caller-provided + function. + + @param[in] Procedure A pointer to the function to be run on + enabled APs of the system. + @param[in] ProcessorNumber The handle number of the AP. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. + @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for + APs to return from Procedure, either for + blocking or non-blocking mode. + @param[in] ProcedureArgument The parameter passed into Procedure for + all APs. + @param[out] Finished If AP returns from Procedure before the + timeout expires, its content is set to TRUE. + Otherwise, the value is set to FALSE. + + @retval EFI_SUCCESS In blocking mode, specified AP finished before + the timeout expires. + @retval others Failed to Startup AP. + +**/ +EFI_STATUS +StartupThisAPWorker ( + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL + ); + +/** + Worker function to switch the requested AP to be the BSP from that point onward. + + @param[in] ProcessorNumber The handle number of AP that is to become the new BSP. + @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an + enabled AP. Otherwise, it will be disabled. + + @retval EFI_SUCCESS BSP successfully switched. + @retval others Failed to switch BSP. + +**/ +EFI_STATUS +SwitchBSPWorker ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP + ); + +/** + Worker function to let the caller enable or disable an AP from this point onward. + This service may only be called from the BSP. + + @param[in] ProcessorNumber The handle number of AP. + @param[in] EnableAP Specifies the new state for the processor for + enabled, FALSE for disabled. + @param[in] HealthFlag If not NULL, a pointer to a value that specifies + the new health status of the AP. + + @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. + @retval others Failed to Enable/Disable AP. + +**/ +EFI_STATUS +EnableDisableApWorker ( + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL + ); + /** Get pointer to CPU MP Data structure from GUIDed HOB. @@ -279,16 +472,107 @@ CPU_MP_DATA * GetCpuMpDataFromGuidedHob ( VOID ); - + +/** Checks status of specified AP. + + This function checks whether the specified AP has finished the task assigned + by StartupThisAP(), and whether timeout expires. + + @param[in] ProcessorNumber The handle number of processor. + + @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs(). + @retval EFI_TIMEOUT The timeout expires. + @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired. +**/ +EFI_STATUS +CheckThisAP ( + IN UINTN ProcessorNumber + ); + +/** + Checks status of all APs. + + This function checks whether all APs have finished task assigned by StartupAllAPs(), + and whether timeout expires. + + @retval EFI_SUCCESS All APs have finished task assigned by StartupAllAPs(). + @retval EFI_TIMEOUT The timeout expires. + @retval EFI_NOT_READY APs have not finished task and timeout has not expired. +**/ +EFI_STATUS +CheckAllAPs ( + VOID + ); + +/** + Checks APs status and updates APs status if needed. + +**/ +VOID +CheckAndUpdateApsStatus ( + VOID + ); + /** Detect whether specified processor can find matching microcode patch and load it. - @param[in] PeiCpuMpData Pointer to PEI CPU MP Data + @param[in] CpuMpData The pointer to CPU MP Data structure. **/ VOID MicrocodeDetect ( IN CPU_MP_DATA *CpuMpData ); +/** + Detect whether Mwait-monitor feature is supported. + + @retval TRUE Mwait-monitor feature is supported. + @retval FALSE Mwait-monitor feature is not supported. +**/ +BOOLEAN +IsMwaitSupport ( + VOID + ); + +/** + Notify function on End Of PEI PPI. + + On S3 boot, this function will restore wakeup buffer data. + On normal boot, this function will flag wakeup buffer to be un-used type. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] NotifyDescriptor Address of the notification descriptor data structure. + @param[in] Ppi Address of the PPI that was installed. + + @retval EFI_SUCCESS When everything is OK. +**/ +EFI_STATUS +EFIAPI +CpuMpEndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +/** + Get available system memory below 1MB by specified size. + + @param[in] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +BackupAndPrepareWakeupBuffer( + IN CPU_MP_DATA *CpuMpData + ); + +/** + Restore wakeup buffer data. + + @param[in] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +RestoreWakeupBuffer( + IN CPU_MP_DATA *CpuMpData + ); + #endif