TianoCore EDK2 master
|
#include <PiPei.h>
#include <Register/Intel/Cpuid.h>
#include <Register/Amd/Cpuid.h>
#include <Register/Amd/Ghcb.h>
#include <Register/Intel/Msr.h>
#include <Register/Intel/LocalApic.h>
#include <Register/Intel/Microcode.h>
#include <Library/MpInitLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/LocalApicLib.h>
#include <Library/CpuLib.h>
#include <Library/TimerLib.h>
#include <Library/SynchronizationLib.h>
#include <Library/MtrrLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/MicrocodeLib.h>
#include <Library/CpuPageTableLib.h>
#include <Library/SafeIntLib.h>
#include <ConfidentialComputingGuestAttr.h>
#include <Register/Amd/SevSnpMsr.h>
#include <Guid/MicrocodePatchHob.h>
#include "MpHandOff.h"
Go to the source code of this file.
Data Structures | |
struct | MICROCODE_PATCH_INFO |
struct | CPU_VOLATILE_REGISTERS |
struct | CPU_EXCHANGE_ROLE_INFO |
struct | CPU_AP_DATA |
struct | CPU_INFO_IN_HOB |
struct | MP_ASSEMBLY_ADDRESS_MAP |
struct | MP_CPU_EXCHANGE_INFO |
struct | _CPU_MP_DATA |
struct | AP_STACK_DATA |
struct | SEV_ES_AP_JMP_FAR |
union | RELOCATE_AP_LOOP_ENTRY |
Macros | |
#define | WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P') |
#define | MP_HAND_OFF_SIGNAL SIGNATURE_32 ('M', 'P', 'H', 'O') |
#define | CPU_INIT_MP_LIB_HOB_GUID |
#define | CPU_SWITCH_STATE_IDLE 0 |
#define | CPU_SWITCH_STATE_STORED 1 |
#define | CPU_SWITCH_STATE_LOADED 2 |
#define | DEFAULT_MAX_MICROCODE_PATCH_NUM 8 |
#define | PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull |
#define | AP_SAFE_STACK_SIZE 128 |
#define | AP_RESET_STACK_SIZE AP_SAFE_STACK_SIZE |
Typedefs | |
typedef struct _CPU_MP_DATA | CPU_MP_DATA |
typedef IN UINT16 | Code16 |
typedef IN UINT16 IN UINT16 | Code32 |
typedef IN UINT16 IN UINT16 IN UINTN | StackStart |
typedef VOID(EFIAPI * | ASM_RELOCATE_AP_LOOP_GENERIC) (IN BOOLEAN MwaitSupport, IN UINTN ApTargetCState, IN UINTN TopOfApStack, IN UINTN NumberToFinish, IN UINTN Cr3) |
typedef VOID(EFIAPI * | ASM_RELOCATE_AP_LOOP_AMDSEV) (IN BOOLEAN MwaitSupport, IN UINTN ApTargetCState, IN UINTN PmCodeSegment, IN UINTN TopOfApStack, IN UINTN NumberToFinish, IN UINTN Pm16CodeSegment, IN UINTN SevEsAPJumpTable, IN UINTN WakeupBuffer) |
Variables | |
EFI_GUID | mCpuInitMpLibHobGuid |
volatile UINT32 | mNumberToFinish |
Common header file for MP Initialize Library.
Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
Definition in file MpLib.h.
#define CPU_INIT_MP_LIB_HOB_GUID |
#define MP_HAND_OFF_SIGNAL SIGNATURE_32 ('M', 'P', 'H', 'O') |
#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P') |
typedef VOID(EFIAPI * ASM_RELOCATE_AP_LOOP_AMDSEV) (IN BOOLEAN MwaitSupport, IN UINTN ApTargetCState, IN UINTN PmCodeSegment, IN UINTN TopOfApStack, IN UINTN NumberToFinish, IN UINTN Pm16CodeSegment, IN UINTN SevEsAPJumpTable, IN UINTN WakeupBuffer) |
Assembly code to place AP into safe loop mode for Amd processors with Sev enabled. Place AP into targeted C-State if MONITOR is supported, otherwise place AP into hlt state. Place AP in protected mode if the current is long mode. Due to AP maybe wakeup by some hardware event. It could avoid accessing page table that may not available during booting to OS.
[in] | MwaitSupport | TRUE indicates MONITOR is supported. FALSE indicates MONITOR is not supported. |
[in] | ApTargetCState | Target C-State value. |
[in] | PmCodeSegment | Protected mode code segment value. |
typedef VOID(EFIAPI * ASM_RELOCATE_AP_LOOP_GENERIC) (IN BOOLEAN MwaitSupport, IN UINTN ApTargetCState, IN UINTN TopOfApStack, IN UINTN NumberToFinish, IN UINTN Cr3) |
Assembly code to place AP into safe loop mode.
Place AP into targeted C-State if MONITOR is supported, otherwise place AP into hlt state. Place AP in protected mode if the current is long mode. Due to AP maybe wakeup by some hardware event. It could avoid accessing page table that may not available during booting to OS.
[in] | MwaitSupport | TRUE indicates MONITOR is supported. FALSE indicates MONITOR is not supported. |
[in] | ApTargetCState | Target C-State value. |
[in] | PmCodeSegment | Protected mode code segment value. |
typedef struct _CPU_MP_DATA CPU_MP_DATA |
VOID AllocateApLoopCodeBuffer | ( | IN UINTN | Pages, |
IN OUT EFI_PHYSICAL_ADDRESS * | Address | ||
) |
Allocate buffer for ApLoopCode.
[in] | Pages | Number of pages to allocate. |
[in,out] | Address | Pointer to the allocated buffer. |
Definition at line 401 of file DxeMpLib.c.
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.
[in] | BufferSize | Wakeup transition buffer size. |
other | Return wakeup transition buffer address below 4GB. |
0 | Cannot find free memory below 4GB. |
Definition at line 163 of file DxeMpLib.c.
VOID AllocateSevEsAPMemory | ( | IN OUT CPU_MP_DATA * | CpuMpData | ) |
VOID AmdSevUpdateCpuMpData | ( | IN CPU_MP_DATA * | CpuMpData | ) |
VOID EFIAPI AsmExchangeRole | ( | IN CPU_EXCHANGE_ROLE_INFO * | MyInfo, |
IN CPU_EXCHANGE_ROLE_INFO * | OthersInfo | ||
) |
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.
[in] | MyInfo | Pointer to buffer holding the exchanging information for the executing processor. |
[in] | OthersInfo | Pointer to buffer holding the exchanging information for the peer. |
VOID EFIAPI AsmGetAddressMap | ( | OUT MP_ASSEMBLY_ADDRESS_MAP * | AddressMap | ) |
Assembly code to get starting address and size of the rendezvous entry for APs. Information for fixing a jump instruction in the code is also returned.
[out] | AddressMap | Output buffer for address map information. |
BOOLEAN CanUseSevSnpCreateAP | ( | IN CPU_MP_DATA * | CpuMpData | ) |
EFI_STATUS CheckAllAPs | ( | VOID | ) |
Checks status of all APs.
This function checks whether all APs have finished task assigned by StartupAllAPs(), and whether timeout expires.
EFI_SUCCESS | All APs have finished task assigned by StartupAllAPs(). |
EFI_TIMEOUT | The timeout expires. |
EFI_NOT_READY | APs have not finished task and timeout has not expired. |
VOID CheckAndUpdateApsStatus | ( | VOID | ) |
Checks APs status and updates APs status if needed.
Definition at line 235 of file DxeMpLib.c.
EFI_STATUS CheckThisAP | ( | IN UINTN | ProcessorNumber | ) |
Checks status of specified AP.
This function checks whether the specified AP has finished the task assigned by StartupThisAP(), and whether timeout expires.
[in] | ProcessorNumber | The handle number of processor. |
EFI_SUCCESS | Specified AP has finished task assigned by StartupThisAPs(). |
EFI_TIMEOUT | The timeout expires. |
EFI_NOT_READY | Specified AP has not finished task and timeout has not expired. |
BOOLEAN EFIAPI ConfidentialComputingGuestHas | ( | CONFIDENTIAL_COMPUTING_GUEST_ATTR | Attr | ) |
Check if the specified confidential computing attribute is active.
TRUE | The specified Attr is active. |
FALSE | The specified Attr is not active. |
Create 1:1 mapping page table in reserved memory to map the specified address range.
[in] | LinearAddress | The start of the linear address range. |
[in] | Length | The length of the linear address range. |
Only create page table for x64, and leave the CreatePageTable empty for Ia32.
[in] | LinearAddress | The start of the linear address range. |
[in] | Length | The length of the linear address range. |
Definition at line 17 of file CreatePageTable.c.
VOID EnableDebugAgent | ( | VOID | ) |
Enable Debug Agent to support source debugging on AP function.
Definition at line 40 of file DxeMpLib.c.
EFI_STATUS EnableDisableApWorker | ( | IN UINTN | ProcessorNumber, |
IN BOOLEAN | EnableAP, | ||
IN UINT32 *HealthFlag | OPTIONAL | ||
) |
Worker function to let the caller enable or disable an AP from this point onward. This service may only be called from the BSP.
[in] | ProcessorNumber | The handle number of AP. |
[in] | EnableAP | Specifies the new state for the processor for enabled, FALSE for disabled. |
[in] | HealthFlag | If not NULL, a pointer to a value that specifies the new health status of the AP. |
EFI_SUCCESS | The specified AP was enabled or disabled successfully. |
others | Failed to Enable/Disable AP. |
VOID FillExchangeInfoDataSevEs | ( | IN volatile MP_CPU_EXCHANGE_INFO * | ExchangeInfo | ) |
CPU_MP_DATA * GetCpuMpData | ( | VOID | ) |
Get the pointer to CPU MP Data structure.
Get pointer to CPU MP Data structure.
Get pointer to CPU MP Data structure. For BSP, the pointer is retrieved from HOB. For AP, the structure is stored in the top of each AP's stack.
Definition at line 56 of file DxeMpLib.c.
CPU_MP_DATA * GetCpuMpDataFromGuidedHob | ( | VOID | ) |
BOOLEAN GetMicrocodePatchInfoFromHob | ( | UINT64 * | Address, |
UINT64 * | RegionSize | ||
) |
Get the cached microcode patch base address and size from the microcode patch information cache HOB.
[out] | Address | Base address of the microcode patches data. It will be updated if the microcode patch information cache HOB is found. |
[out] | RegionSize | Size of the microcode patches data. It will be updated if the microcode patch information cache HOB is found. |
TRUE | The microcode patch information cache HOB is found. |
FALSE | The microcode patch information cache HOB is not found. |
Definition at line 358 of file Microcode.c.
MP_HAND_OFF * GetNextMpHandOffHob | ( | IN CONST MP_HAND_OFF * | MpHandOff | ) |
Get pointer to next MP_HAND_OFF GUIDed HOB body.
[in] | MpHandOff | Previous HOB body. Pass NULL to get the first HOB. |
EFI_STATUS GetProcessorNumber | ( | IN CPU_MP_DATA * | CpuMpData, |
OUT UINTN * | ProcessorNumber | ||
) |
UINTN GetSevEsAPMemory | ( | VOID | ) |
Return the address of the SEV-ES AP jump table.
This buffer is required in order for an SEV-ES guest to transition from UEFI into an OS.
Definition at line 193 of file DxeMpLib.c.
Get available system memory below 1MB by specified size.
[in] | WakeupBufferSize | Wakeup buffer size required |
other | Return wakeup buffer address below 1MB. |
-1 | Cannot find free memory below 1MB. |
Get available system memory below 0x88000 by specified size.
[in] | WakeupBufferSize | Wakeup buffer size required |
other | Return wakeup buffer address below 1MB. |
-1 | Cannot find free memory below 1MB. |
Definition at line 86 of file DxeMpLib.c.
VOID InitMpGlobalData | ( | IN CPU_MP_DATA * | CpuMpData | ) |
Initialize global data for MP support.
[in] | CpuMpData | The pointer to CPU MP Data structure. |
Install Notify
Definition at line 499 of file DxeMpLib.c.
BOOLEAN IsMwaitSupport | ( | VOID | ) |
VOID MicrocodeDetect | ( | IN CPU_MP_DATA * | CpuMpData, |
IN UINTN | ProcessorNumber | ||
) |
Detect whether specified processor can find matching microcode patch and load it.
[in] | CpuMpData | The pointer to CPU MP Data structure. |
[in] | ProcessorNumber | The handle number of the processor. The range is from 0 to the total number of logical processors minus 1. |
Definition at line 20 of file Microcode.c.
EFI_STATUS PlatformShadowMicrocode | ( | IN OUT CPU_MP_DATA * | CpuMpData | ) |
This funtion will try to invoke platform specific microcode shadow logic to relocate microcode update patches into memory.
[in,out] | CpuMpData | The pointer to CPU MP Data structure. |
EFI_SUCCESS | Shadow microcode success. |
EFI_OUT_OF_RESOURCES | No enough resource to complete the operation. |
EFI_UNSUPPORTED | Can't find platform specific microcode shadow PPI/Protocol. |
Definition at line 959 of file DxeMpLib.c.
VOID PrepareApLoopCode | ( | IN CPU_MP_DATA * | CpuMpData | ) |
VOID RemoveNxprotection | ( | IN EFI_PHYSICAL_ADDRESS | BaseAddress, |
IN UINTN | Length | ||
) |
Remove Nx protection for the range specific by BaseAddress and Length.
The PEI implementation uses CpuPageTableLib to change the attribute. The DXE implementation uses gDS to change the attribute.
[in] | BaseAddress | BaseAddress of the range. |
[in] | Length | Length of the range. |
Definition at line 427 of file DxeMpLib.c.
VOID SaveCpuMpData | ( | IN CPU_MP_DATA * | CpuMpData | ) |
Save the pointer to CPU MP Data structure.
[in] | CpuMpData | The pointer to CPU MP Data structure will be saved. |
Definition at line 70 of file DxeMpLib.c.
VOID SevEsPlaceApHlt | ( | CPU_MP_DATA * | CpuMpData | ) |
VOID SevSnpCreateAP | ( | IN CPU_MP_DATA * | CpuMpData, |
IN INTN | ProcessorNumber | ||
) |
VOID SevSnpCreateSaveArea | ( | IN CPU_MP_DATA * | CpuMpData, |
IN CPU_AP_DATA * | CpuData, | ||
UINT32 | ApicId | ||
) |
VOID ShadowMicrocodeUpdatePatch | ( | IN OUT CPU_MP_DATA * | CpuMpData | ) |
Shadow the required microcode patches data into memory.
[in,out] | CpuMpData | The pointer to CPU MP Data structure. |
Definition at line 330 of file Microcode.c.
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 execute a caller provided function on all enabled APs.
[in] | Procedure | A pointer to the function to be run on enabled APs of the system. |
[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. |
[in] | ExcludeBsp | Whether let BSP also trig this task. |
[in] | WaitEvent | The event created by the caller with CreateEvent() service. |
[in] | TimeoutInMicroseconds | Indicates the time limit in microseconds for APs to return from Procedure, either for blocking or non-blocking mode. |
[in] | ProcedureArgument | The parameter passed into Procedure for all APs. |
[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. |
EFI_SUCCESS | In blocking mode, all APs have finished before the timeout expired. |
EFI_SUCCESS | In non-blocking mode, function has been dispatched to all enabled APs. |
others | Failed to Startup all APs. |
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 let the caller get one enabled AP to execute a caller-provided function.
[in] | Procedure | A pointer to the function to be run on enabled APs of the system. |
[in] | ProcessorNumber | The handle number of the AP. |
[in] | WaitEvent | The event created by the caller with CreateEvent() service. |
[in] | TimeoutInMicroseconds | Indicates the time limit in microseconds for APs to return from Procedure, either for blocking or non-blocking mode. |
[in] | ProcedureArgument | The parameter passed into Procedure for all APs. |
[out] | Finished | If AP returns from Procedure before the timeout expires, its content is set to TRUE. Otherwise, the value is set to FALSE. |
EFI_SUCCESS | In blocking mode, specified AP finished before the timeout expires. |
others | Failed to Startup AP. |
VOID SwitchApContext | ( | IN CONST MP_HAND_OFF_CONFIG * | MpHandOffConfig, |
IN CONST MP_HAND_OFF * | FirstMpHandOff | ||
) |
Switch Context for each AP.
This function is intended to be invoked by the BSP in order to wake up the AP. The BSP accomplishes this by triggering a start-up signal, which in turn causes any APs that are currently in a loop on the PEI-prepared memory to awaken and begin running the procedure called SwitchContextPerAp. This procedure allows the AP to switch to another section of memory and continue its loop there.
[in] | MpHandOffConfig | Pointer to MP hand-off config HOB body. |
[in] | FirstMpHandOff | Pointer to first MP hand-off HOB body. |
EFI_STATUS SwitchBSPWorker | ( | IN UINTN | ProcessorNumber, |
IN BOOLEAN | EnableOldBSP | ||
) |
Worker function to switch the requested AP to be the BSP from that point onward.
[in] | ProcessorNumber | The handle number of AP that is to become the new BSP. |
[in] | EnableOldBSP | If TRUE, then the old BSP will be listed as an enabled AP. Otherwise, it will be disabled. |
EFI_SUCCESS | BSP successfully switched. |
others | Failed to switch BSP. |
typedef VOID | ( | EFIAPI | AP_RESET | ) |
Assembly code to move an AP from long mode to real mode.
Move an AP from long mode to real mode in preparation to invoking the reset vector. This is used for SEV-ES guests where a hypervisor is not allowed to set the CS and RIP to point to the reset vector.
[in] | BufferStart | The reset vector target. |
[in] | Code16 | 16-bit protected mode code segment value. |
[in] | Code32 | 32-bit protected mode code segment value. |
[in] | StackStart | The start of a stack to be used for transitioning from long mode to real mode. |
VOID WakeUpAP | ( | IN CPU_MP_DATA * | CpuMpData, |
IN BOOLEAN | Broadcast, | ||
IN UINTN | ProcessorNumber, | ||
IN EFI_AP_PROCEDURE Procedure | OPTIONAL, | ||
IN VOID *ProcedureArgument | OPTIONAL, | ||
IN BOOLEAN | WakeUpDisabledAps | ||
) |
This function will be called by BSP to wakeup AP.
[in] | CpuMpData | Pointer to CPU MP Data |
[in] | Broadcast | TRUE: Send broadcast IPI to all APs FALSE: Send IPI to AP by ApicId |
[in] | ProcessorNumber | The handle number of specified processor |
[in] | Procedure | The function to be invoked by AP |
[in] | ProcedureArgument | The argument to be passed into AP function |
[in] | WakeUpDisabledAps | Whether need to wake up disabled APs in broadcast mode. |
This function will be called by BSP to wakeup AP.
[in] | CpuMpData | Pointer to CPU MP Data |
[in] | Broadcast | TRUE: Send broadcast IPI to all APs FALSE: Send IPI to AP by ApicId |
[in] | ProcessorNumber | The handle number of specified processor |
[in] | Procedure | The function to be invoked by AP |
[in] | ProcedureArgument | The argument to be passed into AP function |
[in] | WakeUpDisabledAps | Whether need to wake up disabled APs in broadcast mode. Currently not used on LoongArch. |