TianoCore EDK2 master
Loading...
Searching...
No Matches
MpLib.h
Go to the documentation of this file.
1
11#ifndef _MP_LIB_H_
12#define _MP_LIB_H_
13
14#include <PiPei.h>
15
17#include <Register/Amd/Cpuid.h>
18#include <Register/Amd/Ghcb.h>
19#include <Register/Intel/Msr.h>
22
23#include <Library/MpInitLib.h>
24#include <Library/BaseLib.h>
27#include <Library/DebugLib.h>
29#include <Library/CpuLib.h>
30#include <Library/TimerLib.h>
32#include <Library/MtrrLib.h>
33#include <Library/HobLib.h>
34#include <Library/PcdLib.h>
37#include <Library/SafeIntLib.h>
39
41#include <Register/Amd/Ghcb.h>
42
44#include "MpHandOff.h"
45
46#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')
47//
48// To trigger the start-up signal, BSP writes the specified
49// StartupSignalValue to the StartupSignalAddress of each processor.
50// This address is monitored by the APs, and as soon as they receive
51// the value that matches the MP_HAND_OFF_SIGNAL, they will wake up
52// and switch the context from PEI to DXE phase.
53//
54#define MP_HAND_OFF_SIGNAL SIGNATURE_32 ('M', 'P', 'H', 'O')
55
56#define CPU_INIT_MP_LIB_HOB_GUID \
57 { \
58 0x58eb6a19, 0x3699, 0x4c68, { 0xa8, 0x36, 0xda, 0xcd, 0x8e, 0xdc, 0xad, 0x4a } \
59 }
60
61//
62// The MP data for switch BSP
63//
64#define CPU_SWITCH_STATE_IDLE 0
65#define CPU_SWITCH_STATE_STORED 1
66#define CPU_SWITCH_STATE_LOADED 2
67
68//
69// Default maximum number of entries to store the microcode patches information
70//
71#define DEFAULT_MAX_MICROCODE_PATCH_NUM 8
72
73#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull
74
75//
76// Data structure for microcode patch information
77//
78typedef struct {
79 UINTN Address;
80 UINTN Size;
82
83//
84// CPU volatile registers around INIT-SIPI-SIPI
85//
86typedef struct {
87 UINTN Cr0;
88 UINTN Cr3;
89 UINTN Cr4;
90 UINTN Dr0;
91 UINTN Dr1;
92 UINTN Dr2;
93 UINTN Dr3;
94 UINTN Dr6;
95 UINTN Dr7;
96 IA32_DESCRIPTOR Gdtr;
97 IA32_DESCRIPTOR Idtr;
98 UINT16 Tr;
100
101//
102// CPU exchange information for switch BSP
103//
104typedef struct {
105 UINT8 State; // offset 0
106 UINTN StackPointer; // offset 4 / 8
107 CPU_VOLATILE_REGISTERS VolatileRegisters; // offset 8 / 16
109
110//
111// AP loop state when APs are in idle state
112// It's value is the same with PcdCpuApLoopMode
113//
114typedef enum {
115 ApInHltLoop = 1,
116 ApInMwaitLoop = 2,
117 ApInRunLoop = 3
118} AP_LOOP_MODE;
119
120//
121// AP initialization state during APs wakeup
122//
123typedef enum {
124 ApInitConfig = 1,
125 ApInitDone = 2
126} AP_INIT_STATE;
127
128//
129// AP state
130//
131// The state transitions for an AP when it process a procedure are:
132// Idle ----> Ready ----> Busy ----> Idle
133// [BSP] [AP] [AP]
134//
135typedef enum {
136 CpuStateIdle,
137 CpuStateReady,
138 CpuStateBusy,
139 CpuStateFinished,
140 CpuStateDisabled
141} CPU_STATE;
142
143//
144// AP related data
145//
146typedef struct {
147 SPIN_LOCK ApLock;
148 volatile UINT32 *StartupApSignal;
149 volatile UINTN ApFunction;
150 volatile UINTN ApFunctionArgument;
151 BOOLEAN CpuHealthy;
152 volatile CPU_STATE State;
153 CPU_VOLATILE_REGISTERS VolatileRegisters;
154 BOOLEAN Waiting;
155 BOOLEAN *Finished;
156 UINT64 ExpectedTime;
157 UINT64 CurrentTime;
158 UINT64 TotalTime;
159 EFI_EVENT WaitEvent;
160 UINT32 ProcessorSignature;
161 UINT8 PlatformId;
162 UINT64 MicrocodeEntryAddr;
163 UINT32 MicrocodeRevision;
164 SEV_ES_SAVE_AREA *SevEsSaveArea;
166
167//
168// Basic CPU information saved in Guided HOB.
169// Because the contents will be shard between PEI and DXE,
170// we need to make sure the each fields offset same in different
171// architecture.
172//
173#pragma pack (1)
174typedef struct {
175 UINT32 InitialApicId;
176 UINT32 ApicId;
177 UINT32 Health;
178 UINT64 ApTopOfStack;
180#pragma pack ()
181
182//
183// AP reset code information including code address and size,
184// this structure will be shared be C code and assembly code.
185// It is natural aligned by design.
186//
187typedef struct {
188 UINT8 *RendezvousFunnelAddress;
189 UINTN ModeEntryOffset;
190 UINTN RendezvousFunnelSize;
191 UINT8 *RelocateApLoopFuncAddressGeneric;
192 UINTN RelocateApLoopFuncSizeGeneric;
193 UINT8 *RelocateApLoopFuncAddressAmdSev;
194 UINTN RelocateApLoopFuncSizeAmdSev;
195 UINTN ModeTransitionOffset;
196 UINTN SwitchToRealNoNxOffset;
197 UINTN SwitchToRealPM16ModeOffset;
198 UINTN SwitchToRealPM16ModeSize;
200
201typedef struct _CPU_MP_DATA CPU_MP_DATA;
202
203#pragma pack(1)
204
205//
206// MP CPU exchange information for AP reset code
207// This structure is required to be packed because fixed field offsets
208// into this structure are used in assembly code in this module
209// Assembly routines should refrain from directly interacting with
210// the internal details of CPU_MP_DATA.
211//
212typedef struct {
213 UINTN StackStart;
214 UINTN StackSize;
215 UINTN CFunction;
216 IA32_DESCRIPTOR GdtrProfile;
217 IA32_DESCRIPTOR IdtrProfile;
218 UINTN BufferStart;
219 UINTN ModeOffset;
220 UINTN ApIndex;
221 UINTN CodeSegment;
222 UINTN DataSegment;
223 UINTN EnableExecuteDisable;
224 UINTN Cr3;
225 UINTN InitFlag;
226 CPU_INFO_IN_HOB *CpuInfo;
227 UINTN NumApsExecuting;
228 CPU_MP_DATA *CpuMpData;
229 UINTN InitializeFloatingPointUnitsAddress;
230 UINT32 ModeTransitionMemory;
231 UINT16 ModeTransitionSegment;
232 UINT32 ModeHighMemory;
233 UINT16 ModeHighSegment;
234 //
235 // Enable5LevelPaging indicates whether 5-level paging is enabled in long mode.
236 //
237 BOOLEAN Enable5LevelPaging;
238 BOOLEAN SevEsIsEnabled;
239 BOOLEAN SevSnpIsEnabled;
240 UINTN GhcbBase;
241 BOOLEAN ExtTopoAvail;
243
244#pragma pack()
245
246//
247// CPU MP Data save in memory, and intended for use in C code.
248// There are some duplicated fields, such as XD status, between
249// CpuMpData and ExchangeInfo. These duplications in CpuMpData
250// are present to avoid to be direct accessed and comprehended
251// in assembly code.
252//
254 UINT64 CpuInfoInHob;
255 UINT32 CpuCount;
256 UINT32 BspNumber;
257 SPIN_LOCK MpLock;
258 UINTN Buffer;
259
260 //
261 // InitialBspApicMode stores the initial BSP APIC mode.
262 // It is used to synchronize the BSP APIC mode with APs
263 // in the first time APs wake up.
264 // Its value doesn't reflect the current APIC mode since there are
265 // two cases the APIC mode is changed:
266 // 1. MpLib explicitly switches to X2 APIC mode because number of threads is greater than 255,
267 // or there are any logical processors reporting an initial APIC ID of 255 or greater.
268 // 2. Some code switches to X2 APIC mode in all threads through MP services PPI/Protocol.
269 //
270 UINTN InitialBspApicMode;
271 UINTN CpuApStackSize;
272 MP_ASSEMBLY_ADDRESS_MAP AddressMap;
273 UINTN WakeupBuffer;
274 UINTN WakeupBufferHigh;
275 UINTN BackupBuffer;
276 UINTN BackupBufferSize;
277
278 volatile UINT32 FinishedCount;
279 UINT32 RunningCount;
280 BOOLEAN SingleThread;
281 EFI_AP_PROCEDURE Procedure;
282 VOID *ProcArguments;
283 BOOLEAN *Finished;
284 UINT64 ExpectedTime;
285 UINT64 CurrentTime;
286 UINT64 TotalTime;
287 EFI_EVENT WaitEvent;
288 UINTN **FailedCpuList;
289 BOOLEAN EnableExecuteDisableForSwitchContext;
290
291 AP_INIT_STATE InitFlag;
292 BOOLEAN SwitchBspFlag;
293 UINTN NewBspNumber;
296 MTRR_SETTINGS MtrrTable;
297 UINT8 ApLoopMode;
298 UINT8 ApTargetCState;
299 UINT16 PmCodeSegment;
300 UINT16 Pm16CodeSegment;
301 CPU_AP_DATA *CpuData;
302 volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
303
304 UINT32 InitTimerCount;
305 UINTN DivideValue;
306 UINT8 Vector;
307 BOOLEAN PeriodicMode;
308 BOOLEAN TimerInterruptState;
309 UINT64 MicrocodePatchAddress;
310 UINT64 MicrocodePatchRegionSize;
311
312 //
313 // Whether need to use Init-Sipi-Sipi to wake up the APs.
314 // Two cases need to set this value to TRUE. One is in HLT
315 // loop mode, the other is resume from S3 which loop mode
316 // will be hardcode change to HLT mode by PiSmmCpuDxeSmm
317 // driver.
318 //
319 BOOLEAN WakeUpByInitSipiSipi;
320
321 BOOLEAN SevEsIsEnabled;
322 BOOLEAN SevSnpIsEnabled;
323 BOOLEAN UseSevEsAPMethod;
324 UINTN SevEsAPBuffer;
325 UINTN SevEsAPResetStackStart;
326 CPU_MP_DATA *NewCpuMpData;
327
328 UINT64 GhcbBase;
329};
330
331//
332// AP_STACK_DATA is stored at the top of each AP stack.
333//
334typedef struct {
335 UINTN Bist;
336 CPU_MP_DATA *MpData;
338
339#define AP_SAFE_STACK_SIZE 128
340#define AP_RESET_STACK_SIZE AP_SAFE_STACK_SIZE
341STATIC_ASSERT ((AP_SAFE_STACK_SIZE & (CPU_STACK_ALIGNMENT - 1)) == 0, "AP_SAFE_STACK_SIZE is not aligned with CPU_STACK_ALIGNMENT");
342
343#pragma pack(1)
344
345typedef struct {
346 UINT8 InsnBuffer[8];
347 UINT16 Rip;
348 UINT16 Segment;
350
351#pragma pack()
352
366typedef
367 VOID
368(EFIAPI AP_RESET)(
369 IN UINTN BufferStart,
370 IN UINT16 Code16,
371 IN UINT16 Code32,
372 IN UINTN StackStart
373 );
374
375extern EFI_GUID mCpuInitMpLibHobGuid;
376extern volatile UINT32 mNumberToFinish;
377
392typedef
393 VOID
395 IN BOOLEAN MwaitSupport,
396 IN UINTN ApTargetCState,
397 IN UINTN TopOfApStack,
398 IN UINTN NumberToFinish,
399 IN UINTN Cr3
400 );
401
415typedef
416 VOID
418 IN BOOLEAN MwaitSupport,
419 IN UINTN ApTargetCState,
420 IN UINTN PmCodeSegment,
421 IN UINTN TopOfApStack,
422 IN UINTN NumberToFinish,
423 IN UINTN Pm16CodeSegment,
424 IN UINTN SevEsAPJumpTable,
425 IN UINTN WakeupBuffer
426 );
427
434VOID
435EFIAPI
437 OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap
438 );
439
449VOID
450EFIAPI
453 IN CPU_EXCHANGE_ROLE_INFO *OthersInfo
454 );
455
456typedef union {
457 VOID *Data;
458 ASM_RELOCATE_AP_LOOP_AMDSEV AmdSevEntry; // 64-bit AMD Sev processors
459 ASM_RELOCATE_AP_LOOP_GENERIC GenericEntry; // Intel processors (32-bit or 64-bit), 32-bit AMD processors, or AMD non-Sev processors
461
469 VOID
470 );
471
477VOID
479 IN CPU_MP_DATA *CpuMpData
480 );
481
490UINTN
492 IN UINTN WakeupBufferSize
493 );
494
499VOID
501 IN CONST MP_HAND_OFF_CONFIG *MpHandOffConfig,
502 IN CONST MP_HAND_OFF *FirstMpHandOff
503 );
504
514 IN CONST MP_HAND_OFF *MpHandOff
515 );
516
529UINTN
531 IN UINTN BufferSize
532 );
533
542UINTN
544 VOID
545 );
546
553UINTN
555 IN UINTN Address,
556 IN UINTN Length
557 );
558
570VOID
571WakeUpAP (
572 IN CPU_MP_DATA *CpuMpData,
573 IN BOOLEAN Broadcast,
574 IN UINTN ProcessorNumber,
575 IN EFI_AP_PROCEDURE Procedure OPTIONAL,
576 IN VOID *ProcedureArgument OPTIONAL,
577 IN BOOLEAN WakeUpDisabledAps
578 );
579
585VOID
587 IN CPU_MP_DATA *CpuMpData
588 );
589
624 IN EFI_AP_PROCEDURE Procedure,
625 IN BOOLEAN SingleThread,
626 IN BOOLEAN ExcludeBsp,
627 IN EFI_EVENT WaitEvent OPTIONAL,
628 IN UINTN TimeoutInMicroseconds,
629 IN VOID *ProcedureArgument OPTIONAL,
630 OUT UINTN **FailedCpuList OPTIONAL
631 );
632
658 IN EFI_AP_PROCEDURE Procedure,
659 IN UINTN ProcessorNumber,
660 IN EFI_EVENT WaitEvent OPTIONAL,
661 IN UINTN TimeoutInMicroseconds,
662 IN VOID *ProcedureArgument OPTIONAL,
663 OUT BOOLEAN *Finished OPTIONAL
664 );
665
679 IN UINTN ProcessorNumber,
680 IN BOOLEAN EnableOldBSP
681 );
682
699 IN UINTN ProcessorNumber,
700 IN BOOLEAN EnableAP,
701 IN UINT32 *HealthFlag OPTIONAL
702 );
703
711 VOID
712 );
713
727 IN UINTN ProcessorNumber
728 );
729
742 VOID
743 );
744
749VOID
751 VOID
752 );
753
762VOID
764 IN CPU_MP_DATA *CpuMpData,
765 IN UINTN ProcessorNumber
766 );
767
773VOID
775 IN OUT CPU_MP_DATA *CpuMpData
776 );
777
793BOOLEAN
795 UINT64 *Address,
796 UINT64 *RegionSize
797 );
798
805BOOLEAN
807 VOID
808 );
809
814VOID
816 VOID
817 );
818
830 IN CPU_MP_DATA *CpuMpData,
831 OUT UINTN *ProcessorNumber
832 );
833
847 IN OUT CPU_MP_DATA *CpuMpData
848 );
849
855VOID
857 IN OUT CPU_MP_DATA *CpuMpData
858 );
859
865VOID
867 IN UINTN SipiVector
868 );
869
875VOID
877 CPU_MP_DATA *CpuMpData
878 );
879
886BOOLEAN
887EFIAPI
889 CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr
890 );
891
897VOID
899 IN volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo
900 );
901
909VOID
911 IN CPU_MP_DATA *CpuMpData,
912 IN CPU_AP_DATA *CpuData,
913 UINT32 ApicId
914 );
915
923VOID
925 IN CPU_MP_DATA *CpuMpData,
926 IN INTN ProcessorNumber
927 );
928
937BOOLEAN
939 IN CPU_MP_DATA *CpuMpData
940 );
941
947VOID
949 IN CPU_MP_DATA *CpuMpData
950 );
951
957VOID
959 IN CPU_MP_DATA *CpuMpData
960 );
961
967VOID
968EFIAPI
970 IN OUT VOID *Buffer
971 );
972
979VOID
981 IN UINTN Pages,
983 );
984
994VOID
996 IN EFI_PHYSICAL_ADDRESS BaseAddress,
997 IN UINTN Length
998 );
999
1000#endif
UINT64 UINTN
INT64 INTN
#define CPU_STACK_ALIGNMENT
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)
Definition: MpLib.c:1176
CPU_MP_DATA * GetCpuMpDataFromGuidedHob(VOID)
Definition: MpLib.c:1609
EFI_STATUS EnableDisableApWorker(IN UINTN ProcessorNumber, IN BOOLEAN EnableAP, IN UINT32 *HealthFlag OPTIONAL)
Definition: MpLib.c:2745
VOID CheckAndUpdateApsStatus(VOID)
Definition: DxeMpLib.c:235
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)
Definition: MpLib.c:672
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)
Definition: MpLib.c:1019
EFI_STATUS CheckThisAP(IN UINTN ProcessorNumber)
Definition: MpLib.c:863
CPU_MP_DATA * GetCpuMpData(VOID)
Definition: DxeMpLib.c:56
EFI_STATUS CheckAllAPs(VOID)
Definition: MpLib.c:910
VOID InitMpGlobalData(IN CPU_MP_DATA *CpuMpData)
Definition: DxeMpLib.c:499
VOID EnableDebugAgent(VOID)
Definition: DxeMpLib.c:40
VOID SaveCpuMpData(IN CPU_MP_DATA *CpuMpData)
Definition: DxeMpLib.c:70
#define CONST
Definition: Base.h:259
#define STATIC_ASSERT
Definition: Base.h:808
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
VOID EFIAPI RelocateApLoop(IN OUT VOID *Buffer)
Definition: MpLib.c:3364
VOID AllocateSevEsAPMemory(IN OUT CPU_MP_DATA *CpuMpData)
Definition: AmdSev.c:158
VOID AmdSevUpdateCpuMpData(IN CPU_MP_DATA *CpuMpData)
Definition: AmdSev.c:304
VOID EFIAPI AsmExchangeRole(IN CPU_EXCHANGE_ROLE_INFO *MyInfo, IN CPU_EXCHANGE_ROLE_INFO *OthersInfo)
VOID SetSevEsJumpTable(IN UINTN SipiVector)
Definition: AmdSev.c:174
VOID SwitchApContext(IN CONST MP_HAND_OFF_CONFIG *MpHandOffConfig, IN CONST MP_HAND_OFF *FirstMpHandOff)
Definition: MpLib.c:1945
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)
Definition: MpLib.h:417
VOID ShadowMicrocodeUpdatePatch(IN OUT CPU_MP_DATA *CpuMpData)
Definition: Microcode.c:330
VOID RemoveNxprotection(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINTN Length)
Definition: DxeMpLib.c:427
MP_HAND_OFF * GetNextMpHandOffHob(IN CONST MP_HAND_OFF *MpHandOff)
Definition: MpLib.c:2011
UINTN GetWakeupBuffer(IN UINTN WakeupBufferSize)
Definition: DxeMpLib.c:86
VOID PrepareApLoopCode(IN CPU_MP_DATA *CpuMpData)
Definition: MpLib.c:3424
BOOLEAN EFIAPI ConfidentialComputingGuestHas(CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr)
VOID EFIAPI AsmGetAddressMap(OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap)
VOID AllocateApLoopCodeBuffer(IN UINTN Pages, IN OUT EFI_PHYSICAL_ADDRESS *Address)
Definition: DxeMpLib.c:401
VOID SevSnpCreateAP(IN CPU_MP_DATA *CpuMpData, IN INTN ProcessorNumber)
Definition: AmdSev.c:41
BOOLEAN IsMwaitSupport(VOID)
Definition: MpLib.c:295
VOID MicrocodeDetect(IN CPU_MP_DATA *CpuMpData, IN UINTN ProcessorNumber)
Definition: Microcode.c:20
EFI_STATUS GetProcessorNumber(IN CPU_MP_DATA *CpuMpData, OUT UINTN *ProcessorNumber)
Definition: MpLib.c:78
BOOLEAN GetMicrocodePatchInfoFromHob(UINT64 *Address, UINT64 *RegionSize)
Definition: Microcode.c:358
BOOLEAN CanUseSevSnpCreateAP(IN CPU_MP_DATA *CpuMpData)
Definition: AmdSev.c:61
VOID(EFIAPI * ASM_RELOCATE_AP_LOOP_GENERIC)(IN BOOLEAN MwaitSupport, IN UINTN ApTargetCState, IN UINTN TopOfApStack, IN UINTN NumberToFinish, IN UINTN Cr3)
Definition: MpLib.h:394
EFI_STATUS SwitchBSPWorker(IN UINTN ProcessorNumber, IN BOOLEAN EnableOldBSP)
Definition: MpLib.c:2581
VOID SevEsPlaceApHlt(CPU_MP_DATA *CpuMpData)
Definition: AmdSev.c:223
UINTN AllocateCodeBuffer(IN UINTN BufferSize)
Definition: DxeMpLib.c:163
VOID FillExchangeInfoDataSevEs(IN volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo)
Definition: AmdSev.c:276
UINTN CreatePageTable(IN UINTN Address, IN UINTN Length)
EFI_STATUS PlatformShadowMicrocode(IN OUT CPU_MP_DATA *CpuMpData)
Definition: DxeMpLib.c:959
UINTN GetSevEsAPMemory(VOID)
Definition: DxeMpLib.c:193
VOID SevSnpCreateSaveArea(IN CPU_MP_DATA *CpuMpData, IN CPU_AP_DATA *CpuData, UINT32 ApicId)
Definition: AmdSev.c:21
VOID(EFIAPI * EFI_AP_PROCEDURE)(IN OUT VOID *Buffer)
Definition: PiMultiPhase.h:198
volatile UINTN SPIN_LOCK
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
Definition: Base.h:213