X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;ds=sidebyside;f=UefiCpuPkg%2FLibrary%2FMpInitLib%2FMpLib.h;h=6609c958ce8a63b29f92f5656d58152cdf30babf;hb=fd30b0070773ac4ac5f49abca8f5b3afbeece158;hp=04ffba566dda1049fbeb0a859c1d2bf550f0001f;hpb=20ae57745b19538229ba0670c10e08c13f9e2574;p=mirror_edk2.git diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index 04ffba566d..6609c958ce 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -1,14 +1,8 @@ /** @file Common header file for MP Initialize Library. - Copyright (c) 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -17,10 +11,10 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -49,6 +43,20 @@ #define CPU_SWITCH_STATE_STORED 1 #define CPU_SWITCH_STATE_LOADED 2 +// +// Default maximum number of entries to store the microcode patches information +// +#define DEFAULT_MAX_MICROCODE_PATCH_NUM 8 + +// +// Data structure for microcode patch information +// +typedef struct { + UINTN Address; + UINTN Size; + UINTN AlignedSize; +} MICROCODE_PATCH_INFO; + // // CPU exchange information for switch BSP // @@ -81,6 +89,10 @@ typedef enum { // // AP state // +// The state transitions for an AP when it process a procedure are: +// Idle ----> Ready ----> Busy ----> Idle +// [BSP] [AP] [AP] +// typedef enum { CpuStateIdle, CpuStateReady, @@ -102,6 +114,9 @@ typedef struct { UINTN Dr3; UINTN Dr6; UINTN Dr7; + IA32_DESCRIPTOR Gdtr; + IA32_DESCRIPTOR Idtr; + UINT16 Tr; } CPU_VOLATILE_REGISTERS; // @@ -112,9 +127,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; @@ -124,6 +136,9 @@ typedef struct { UINT64 CurrentTime; UINT64 TotalTime; EFI_EVENT WaitEvent; + UINT32 ProcessorSignature; + UINT8 PlatformId; + UINT64 MicrocodeEntryAddr; } CPU_AP_DATA; // @@ -132,11 +147,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, @@ -149,6 +167,7 @@ typedef struct { UINTN RendezvousFunnelSize; UINT8 *RelocateApLoopFuncAddress; UINTN RelocateApLoopFuncSize; + UINTN ModeTransitionOffset; } MP_ASSEMBLY_ADDRESS_MAP; typedef struct _CPU_MP_DATA CPU_MP_DATA; @@ -169,12 +188,24 @@ typedef struct { IA32_DESCRIPTOR IdtrProfile; UINTN BufferStart; UINTN ModeOffset; - UINTN NumApsExecuting; + UINTN ApIndex; UINTN CodeSegment; UINTN DataSegment; UINTN EnableExecuteDisable; UINTN Cr3; + UINTN InitFlag; + CPU_INFO_IN_HOB *CpuInfo; + UINTN NumApsExecuting; CPU_MP_DATA *CpuMpData; + UINTN InitializeFloatingPointUnitsAddress; + UINT32 ModeTransitionMemory; + UINT16 ModeTransitionSegment; + UINT32 ModeHighMemory; + UINT16 ModeHighSegment; + // + // Enable5LevelPaging indicates whether 5-level paging is enabled in long mode. + // + BOOLEAN Enable5LevelPaging; } MP_CPU_EXCHANGE_INFO; #pragma pack() @@ -186,6 +217,8 @@ struct _CPU_MP_DATA { UINT64 CpuInfoInHob; UINT32 CpuCount; UINT32 BspNumber; + UINT64 MicrocodePatchAddress; + UINT64 MicrocodePatchRegionSize; // // The above fields data will be passed from PEI to DXE // Please make sure the fields offset same in the different @@ -196,13 +229,12 @@ struct _CPU_MP_DATA { UINTN CpuApStackSize; MP_ASSEMBLY_ADDRESS_MAP AddressMap; UINTN WakeupBuffer; + UINTN WakeupBufferHigh; UINTN BackupBuffer; UINTN BackupBufferSize; - BOOLEAN EndOfPeiFlag; - volatile UINT32 StartCount; volatile UINT32 FinishedCount; - volatile UINT32 RunningCount; + UINT32 RunningCount; BOOLEAN SingleThread; EFI_AP_PROCEDURE Procedure; VOID *ProcArguments; @@ -214,8 +246,8 @@ struct _CPU_MP_DATA { UINTN **FailedCpuList; AP_INIT_STATE InitFlag; - BOOLEAN X2ApicEnable; BOOLEAN SwitchBspFlag; + UINTN NewBspNumber; CPU_EXCHANGE_ROLE_INFO BSPInfo; CPU_EXCHANGE_ROLE_INFO APInfo; MTRR_SETTINGS MtrrTable; @@ -224,6 +256,21 @@ struct _CPU_MP_DATA { UINT16 PmCodeSegment; CPU_AP_DATA *CpuData; volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo; + + UINT32 CurrentTimerCount; + UINTN DivideValue; + UINT8 Vector; + BOOLEAN PeriodicMode; + BOOLEAN TimerInterruptState; + + // + // Whether need to use Init-Sipi-Sipi to wake up the APs. + // Two cases need to set this value to TRUE. One is in HLT + // loop mode, the other is resume from S3 which loop mode + // will be hardcode change to HLT mode by PiSmmCpuDxeSmm + // driver. + // + BOOLEAN WakeUpByInitSipiSipi; }; extern EFI_GUID mCpuInitMpLibHobGuid; @@ -247,7 +294,9 @@ VOID (EFIAPI * ASM_RELOCATE_AP_LOOP) ( IN BOOLEAN MwaitSupport, IN UINTN ApTargetCState, - IN UINTN PmCodeSegment + IN UINTN PmCodeSegment, + IN UINTN TopOfApStack, + IN UINTN NumberToFinish ); /** @@ -298,24 +347,35 @@ SaveCpuMpData ( IN CPU_MP_DATA *CpuMpData ); + /** - Allocate reset vector buffer. + Get available system memory below 1MB by specified size. - @param[in, out] CpuMpData The pointer to CPU MP Data structure. + @param[in] WakeupBufferSize Wakeup buffer size required + + @retval other Return wakeup buffer address below 1MB. + @retval -1 Cannot find free memory below 1MB. **/ -VOID -AllocateResetVector ( - IN OUT CPU_MP_DATA *CpuMpData +UINTN +GetWakeupBuffer ( + IN UINTN WakeupBufferSize ); /** - Free AP reset vector buffer. + Get available EfiBootServicesCode memory below 4GB by specified size. + + This buffer is required to safely transfer AP from real address mode to + protected mode or long mode, due to the fact that the buffer returned by + GetWakeupBuffer() may be marked as non-executable. + + @param[in] BufferSize Wakeup transition buffer size. - @param[in] CpuMpData The pointer to CPU MP Data structure. + @retval other Return wakeup transition buffer address below 4GB. + @retval 0 Cannot find free memory below 4GB. **/ -VOID -FreeResetVector ( - IN CPU_MP_DATA *CpuMpData +UINTN +GetModeTransitionBuffer ( + IN UINTN BufferSize ); /** @@ -327,6 +387,7 @@ FreeResetVector ( @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 + @param[in] WakeUpDisabledAps Whether need to wake up disabled APs in broadcast mode. **/ VOID WakeUpAP ( @@ -334,7 +395,8 @@ WakeUpAP ( IN BOOLEAN Broadcast, IN UINTN ProcessorNumber, IN EFI_AP_PROCEDURE Procedure, OPTIONAL - IN VOID *ProcedureArgument OPTIONAL + IN VOID *ProcedureArgument, OPTIONAL + IN BOOLEAN WakeUpDisabledAps OPTIONAL ); /** @@ -347,6 +409,49 @@ 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] ExcludeBsp Whether let BSP also trig this task. + @param[in] WaitEvent The event created by the caller with CreateEvent() + service. + @param[in] TimeoutInMicroseconds 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 +StartupAllCPUsWorker ( + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN BOOLEAN ExcludeBsp, + 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. @@ -356,7 +461,7 @@ InitMpGlobalData ( @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 + @param[in] TimeoutInMicroseconds 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 @@ -388,7 +493,7 @@ StartupThisAPWorker ( enabled AP. Otherwise, it will be disabled. @retval EFI_SUCCESS BSP successfully switched. - @retval others Failed to switch BSP. + @retval others Failed to switch BSP. **/ EFI_STATUS @@ -471,31 +576,60 @@ CheckAndUpdateApsStatus ( /** 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. + @param[in] ProcessorNumber The handle number of the processor. The range is + from 0 to the total number of logical processors + minus 1. **/ VOID MicrocodeDetect ( - IN CPU_MP_DATA *CpuMpData + IN CPU_MP_DATA *CpuMpData, + IN UINTN ProcessorNumber + ); + +/** + Load the required microcode patches data into memory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +LoadMicrocodePatch ( + IN OUT 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. + Enable Debug Agent to support source debugging on AP function. - On S3 boot, this function will restore wakeup buffer data. - On normal boot, this function will flag wakeup buffer to be un-used type. +**/ +VOID +EnableDebugAgent ( + VOID + ); - @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. +/** + Find the current Processor number by APIC ID. + + @param[in] CpuMpData Pointer to PEI CPU MP Data + @param[out] ProcessorNumber Return the pocessor number found - @retval EFI_SUCCESS When everything is OK. + @retval EFI_SUCCESS ProcessorNumber is found and returned. + @retval EFI_NOT_FOUND ProcessorNumber is not found. **/ EFI_STATUS -EFIAPI -CpuMpEndOfPeiCallback ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, - IN VOID *Ppi +GetProcessorNumber ( + IN CPU_MP_DATA *CpuMpData, + OUT UINTN *ProcessorNumber ); #endif