X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=UefiCpuPkg%2FLibrary%2FMpInitLib%2FMpLib.h;h=a8ca03efb8e3d8e75363dd66ad77fcb740b1c8ed;hp=e53deb449d977be7ef81a6ae1ad72eb56961dd77;hb=8dd962a657b28d9db65ed7a35817a4b82f06301a;hpb=4d3314f694881f4a4a53636515da144230f1d913 diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index e53deb449d..a8ca03efb8 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -1,14 +1,10 @@ /** @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 + Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2020, AMD Inc. All rights reserved.
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -17,10 +13,11 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include @@ -34,6 +31,9 @@ #include #include #include +#include + +#include #define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P') @@ -49,6 +49,19 @@ #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; +} MICROCODE_PATCH_INFO; + // // CPU exchange information for switch BSP // @@ -81,6 +94,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 +119,9 @@ typedef struct { UINTN Dr3; UINTN Dr6; UINTN Dr7; + IA32_DESCRIPTOR Gdtr; + IA32_DESCRIPTOR Idtr; + UINT16 Tr; } CPU_VOLATILE_REGISTERS; // @@ -112,9 +132,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 +141,9 @@ typedef struct { UINT64 CurrentTime; UINT64 TotalTime; EFI_EVENT WaitEvent; + UINT32 ProcessorSignature; + UINT8 PlatformId; + UINT64 MicrocodeEntryAddr; } CPU_AP_DATA; // @@ -132,11 +152,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 +172,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 +193,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() @@ -196,13 +232,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 +249,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 +259,23 @@ 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; + UINT64 MicrocodePatchAddress; + UINT64 MicrocodePatchRegionSize; + + // + // 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 +299,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 +352,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 +392,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 +400,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 ); /** @@ -358,9 +425,10 @@ InitMpGlobalData ( 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] 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 @@ -379,9 +447,10 @@ InitMpGlobalData ( **/ EFI_STATUS -StartupAllAPsWorker ( +StartupAllCPUsWorker ( IN EFI_AP_PROCEDURE Procedure, IN BOOLEAN SingleThread, + IN BOOLEAN ExcludeBsp, IN EFI_EVENT WaitEvent OPTIONAL, IN UINTN TimeoutInMicroseconds, IN VOID *ProcedureArgument OPTIONAL, @@ -397,7 +466,7 @@ StartupAllAPsWorker ( @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 @@ -429,7 +498,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 @@ -512,11 +581,46 @@ 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 + ); + +/** + Shadow the required microcode patches data into memory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. +**/ +VOID +ShadowMicrocodeUpdatePatch ( + IN OUT CPU_MP_DATA *CpuMpData + ); + +/** + Get the cached microcode patch base address and size from the microcode patch + information cache HOB. + + @param[out] Address Base address of the microcode patches data. + It will be updated if the microcode patch + information cache HOB is found. + @param[out] RegionSize Size of the microcode patches data. + It will be updated if the microcode patch + information cache HOB is found. + + @retval TRUE The microcode patch information cache HOB is found. + @retval FALSE The microcode patch information cache HOB is not found. + +**/ +BOOLEAN +GetMicrocodePatchInfoFromHob ( + UINT64 *Address, + UINT64 *RegionSize ); /** @@ -531,23 +635,43 @@ IsMwaitSupport ( ); /** - 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 + ); + +/** + Find the current Processor number by APIC ID. - @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. + @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 + ); + +/** + This funtion will try to invoke platform specific microcode shadow logic to + relocate microcode update patches into memory. + + @param[in, out] CpuMpData The pointer to CPU MP Data structure. + + @retval EFI_SUCCESS Shadow microcode success. + @retval EFI_OUT_OF_RESOURCES No enough resource to complete the operation. + @retval EFI_UNSUPPORTED Can't find platform specific microcode shadow + PPI/Protocol. +**/ +EFI_STATUS +PlatformShadowMicrocode ( + IN OUT CPU_MP_DATA *CpuMpData ); #endif