]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/MpInitLib/MpLib.h
UefiCpuPkg/MpInitLib: Rollback old change 2a5997f8.
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / MpLib.h
1 /** @file
2 Common header file for MP Initialize Library.
3
4 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #ifndef _MP_LIB_H_
16 #define _MP_LIB_H_
17
18 #include <PiPei.h>
19
20 #include <Register/Cpuid.h>
21 #include <Register/Msr.h>
22 #include <Register/LocalApic.h>
23 #include <Register/Microcode.h>
24
25 #include <Library/MpInitLib.h>
26 #include <Library/BaseLib.h>
27 #include <Library/BaseMemoryLib.h>
28 #include <Library/MemoryAllocationLib.h>
29 #include <Library/DebugLib.h>
30 #include <Library/LocalApicLib.h>
31 #include <Library/CpuLib.h>
32 #include <Library/UefiCpuLib.h>
33 #include <Library/TimerLib.h>
34 #include <Library/SynchronizationLib.h>
35 #include <Library/MtrrLib.h>
36 #include <Library/HobLib.h>
37
38 #define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')
39
40 #define CPU_INIT_MP_LIB_HOB_GUID \
41 { \
42 0x58eb6a19, 0x3699, 0x4c68, { 0xa8, 0x36, 0xda, 0xcd, 0x8e, 0xdc, 0xad, 0x4a } \
43 }
44
45 //
46 // The MP data for switch BSP
47 //
48 #define CPU_SWITCH_STATE_IDLE 0
49 #define CPU_SWITCH_STATE_STORED 1
50 #define CPU_SWITCH_STATE_LOADED 2
51
52 //
53 // CPU exchange information for switch BSP
54 //
55 typedef struct {
56 UINT8 State; // offset 0
57 UINTN StackPointer; // offset 4 / 8
58 IA32_DESCRIPTOR Gdtr; // offset 8 / 16
59 IA32_DESCRIPTOR Idtr; // offset 14 / 26
60 } CPU_EXCHANGE_ROLE_INFO;
61
62 //
63 // AP loop state when APs are in idle state
64 // It's value is the same with PcdCpuApLoopMode
65 //
66 typedef enum {
67 ApInHltLoop = 1,
68 ApInMwaitLoop = 2,
69 ApInRunLoop = 3
70 } AP_LOOP_MODE;
71
72 //
73 // AP initialization state during APs wakeup
74 //
75 typedef enum {
76 ApInitConfig = 1,
77 ApInitReconfig = 2,
78 ApInitDone = 3
79 } AP_INIT_STATE;
80
81 //
82 // AP state
83 //
84 // The state transitions for an AP when it process a procedure are:
85 // Idle ----> Ready ----> Busy ----> Idle
86 // [BSP] [AP] [AP]
87 //
88 typedef enum {
89 CpuStateIdle,
90 CpuStateReady,
91 CpuStateBusy,
92 CpuStateFinished,
93 CpuStateDisabled
94 } CPU_STATE;
95
96 //
97 // CPU volatile registers around INIT-SIPI-SIPI
98 //
99 typedef struct {
100 UINTN Cr0;
101 UINTN Cr3;
102 UINTN Cr4;
103 UINTN Dr0;
104 UINTN Dr1;
105 UINTN Dr2;
106 UINTN Dr3;
107 UINTN Dr6;
108 UINTN Dr7;
109 IA32_DESCRIPTOR Gdtr;
110 IA32_DESCRIPTOR Idtr;
111 UINT16 Tr;
112 } CPU_VOLATILE_REGISTERS;
113
114 //
115 // AP related data
116 //
117 typedef struct {
118 SPIN_LOCK ApLock;
119 volatile UINT32 *StartupApSignal;
120 volatile UINTN ApFunction;
121 volatile UINTN ApFunctionArgument;
122 BOOLEAN CpuHealthy;
123 volatile CPU_STATE State;
124 CPU_VOLATILE_REGISTERS VolatileRegisters;
125 BOOLEAN Waiting;
126 BOOLEAN *Finished;
127 UINT64 ExpectedTime;
128 UINT64 CurrentTime;
129 UINT64 TotalTime;
130 EFI_EVENT WaitEvent;
131 } CPU_AP_DATA;
132
133 //
134 // Basic CPU information saved in Guided HOB.
135 // Because the contents will be shard between PEI and DXE,
136 // we need to make sure the each fields offset same in different
137 // architecture.
138 //
139 #pragma pack (1)
140 typedef struct {
141 UINT32 InitialApicId;
142 UINT32 ApicId;
143 UINT32 Health;
144 UINT64 ApTopOfStack;
145 } CPU_INFO_IN_HOB;
146 #pragma pack ()
147
148 //
149 // AP reset code information including code address and size,
150 // this structure will be shared be C code and assembly code.
151 // It is natural aligned by design.
152 //
153 typedef struct {
154 UINT8 *RendezvousFunnelAddress;
155 UINTN ModeEntryOffset;
156 UINTN RendezvousFunnelSize;
157 UINT8 *RelocateApLoopFuncAddress;
158 UINTN RelocateApLoopFuncSize;
159 UINTN ModeTransitionOffset;
160 } MP_ASSEMBLY_ADDRESS_MAP;
161
162 typedef struct _CPU_MP_DATA CPU_MP_DATA;
163
164 #pragma pack(1)
165
166 //
167 // MP CPU exchange information for AP reset code
168 // This structure is required to be packed because fixed field offsets
169 // into this structure are used in assembly code in this module
170 //
171 typedef struct {
172 UINTN Lock;
173 UINTN StackStart;
174 UINTN StackSize;
175 UINTN CFunction;
176 IA32_DESCRIPTOR GdtrProfile;
177 IA32_DESCRIPTOR IdtrProfile;
178 UINTN BufferStart;
179 UINTN ModeOffset;
180 UINTN ApIndex;
181 UINTN CodeSegment;
182 UINTN DataSegment;
183 UINTN EnableExecuteDisable;
184 UINTN Cr3;
185 UINTN InitFlag;
186 CPU_INFO_IN_HOB *CpuInfo;
187 UINTN NumApsExecuting;
188 CPU_MP_DATA *CpuMpData;
189 UINTN InitializeFloatingPointUnitsAddress;
190 UINT32 ModeTransitionMemory;
191 UINT16 ModeTransitionSegment;
192 UINT32 ModeHighMemory;
193 UINT16 ModeHighSegment;
194 } MP_CPU_EXCHANGE_INFO;
195
196 #pragma pack()
197
198 //
199 // CPU MP Data save in memory
200 //
201 struct _CPU_MP_DATA {
202 UINT64 CpuInfoInHob;
203 UINT32 CpuCount;
204 UINT32 BspNumber;
205 //
206 // The above fields data will be passed from PEI to DXE
207 // Please make sure the fields offset same in the different
208 // architecture.
209 //
210 SPIN_LOCK MpLock;
211 UINTN Buffer;
212 UINTN CpuApStackSize;
213 MP_ASSEMBLY_ADDRESS_MAP AddressMap;
214 UINTN WakeupBuffer;
215 UINTN WakeupBufferHigh;
216 UINTN BackupBuffer;
217 UINTN BackupBufferSize;
218
219 volatile UINT32 FinishedCount;
220 UINT32 RunningCount;
221 BOOLEAN SingleThread;
222 EFI_AP_PROCEDURE Procedure;
223 VOID *ProcArguments;
224 BOOLEAN *Finished;
225 UINT64 ExpectedTime;
226 UINT64 CurrentTime;
227 UINT64 TotalTime;
228 EFI_EVENT WaitEvent;
229 UINTN **FailedCpuList;
230
231 AP_INIT_STATE InitFlag;
232 BOOLEAN X2ApicEnable;
233 BOOLEAN SwitchBspFlag;
234 UINTN NewBspNumber;
235 CPU_EXCHANGE_ROLE_INFO BSPInfo;
236 CPU_EXCHANGE_ROLE_INFO APInfo;
237 MTRR_SETTINGS MtrrTable;
238 UINT8 ApLoopMode;
239 UINT8 ApTargetCState;
240 UINT16 PmCodeSegment;
241 CPU_AP_DATA *CpuData;
242 volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
243
244 UINT32 CurrentTimerCount;
245 UINTN DivideValue;
246 UINT8 Vector;
247 BOOLEAN PeriodicMode;
248 BOOLEAN TimerInterruptState;
249 UINT64 MicrocodePatchAddress;
250 UINT64 MicrocodePatchRegionSize;
251
252 UINT32 ProcessorSignature;
253 UINT32 ProcessorFlags;
254 UINT64 MicrocodeDataAddress;
255 UINT32 MicrocodeRevision;
256
257 //
258 // Whether need to use Init-Sipi-Sipi to wake up the APs.
259 // Two cases need to set this value to TRUE. One is in HLT
260 // loop mode, the other is resume from S3 which loop mode
261 // will be hardcode change to HLT mode by PiSmmCpuDxeSmm
262 // driver.
263 //
264 BOOLEAN WakeUpByInitSipiSipi;
265 };
266
267 extern EFI_GUID mCpuInitMpLibHobGuid;
268
269 /**
270 Assembly code to place AP into safe loop mode.
271
272 Place AP into targeted C-State if MONITOR is supported, otherwise
273 place AP into hlt state.
274 Place AP in protected mode if the current is long mode. Due to AP maybe
275 wakeup by some hardware event. It could avoid accessing page table that
276 may not available during booting to OS.
277
278 @param[in] MwaitSupport TRUE indicates MONITOR is supported.
279 FALSE indicates MONITOR is not supported.
280 @param[in] ApTargetCState Target C-State value.
281 @param[in] PmCodeSegment Protected mode code segment value.
282 **/
283 typedef
284 VOID
285 (EFIAPI * ASM_RELOCATE_AP_LOOP) (
286 IN BOOLEAN MwaitSupport,
287 IN UINTN ApTargetCState,
288 IN UINTN PmCodeSegment,
289 IN UINTN TopOfApStack,
290 IN UINTN NumberToFinish
291 );
292
293 /**
294 Assembly code to get starting address and size of the rendezvous entry for APs.
295 Information for fixing a jump instruction in the code is also returned.
296
297 @param[out] AddressMap Output buffer for address map information.
298 **/
299 VOID
300 EFIAPI
301 AsmGetAddressMap (
302 OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap
303 );
304
305 /**
306 This function is called by both the BSP and the AP which is to become the BSP to
307 Exchange execution context including stack between them. After return from this
308 function, the BSP becomes AP and the AP becomes the BSP.
309
310 @param[in] MyInfo Pointer to buffer holding the exchanging information for the executing processor.
311 @param[in] OthersInfo Pointer to buffer holding the exchanging information for the peer.
312
313 **/
314 VOID
315 EFIAPI
316 AsmExchangeRole (
317 IN CPU_EXCHANGE_ROLE_INFO *MyInfo,
318 IN CPU_EXCHANGE_ROLE_INFO *OthersInfo
319 );
320
321 /**
322 Get the pointer to CPU MP Data structure.
323
324 @return The pointer to CPU MP Data structure.
325 **/
326 CPU_MP_DATA *
327 GetCpuMpData (
328 VOID
329 );
330
331 /**
332 Save the pointer to CPU MP Data structure.
333
334 @param[in] CpuMpData The pointer to CPU MP Data structure will be saved.
335 **/
336 VOID
337 SaveCpuMpData (
338 IN CPU_MP_DATA *CpuMpData
339 );
340
341
342 /**
343 Get available system memory below 1MB by specified size.
344
345 @param[in] WakeupBufferSize Wakeup buffer size required
346
347 @retval other Return wakeup buffer address below 1MB.
348 @retval -1 Cannot find free memory below 1MB.
349 **/
350 UINTN
351 GetWakeupBuffer (
352 IN UINTN WakeupBufferSize
353 );
354
355 /**
356 Get available EfiBootServicesCode memory below 4GB by specified size.
357
358 This buffer is required to safely transfer AP from real address mode to
359 protected mode or long mode, due to the fact that the buffer returned by
360 GetWakeupBuffer() may be marked as non-executable.
361
362 @param[in] BufferSize Wakeup transition buffer size.
363
364 @retval other Return wakeup transition buffer address below 4GB.
365 @retval 0 Cannot find free memory below 4GB.
366 **/
367 UINTN
368 GetModeTransitionBuffer (
369 IN UINTN BufferSize
370 );
371
372 /**
373 This function will be called by BSP to wakeup AP.
374
375 @param[in] CpuMpData Pointer to CPU MP Data
376 @param[in] Broadcast TRUE: Send broadcast IPI to all APs
377 FALSE: Send IPI to AP by ApicId
378 @param[in] ProcessorNumber The handle number of specified processor
379 @param[in] Procedure The function to be invoked by AP
380 @param[in] ProcedureArgument The argument to be passed into AP function
381 @param[in] WakeUpDisabledAps Whether need to wake up disabled APs in broadcast mode.
382 **/
383 VOID
384 WakeUpAP (
385 IN CPU_MP_DATA *CpuMpData,
386 IN BOOLEAN Broadcast,
387 IN UINTN ProcessorNumber,
388 IN EFI_AP_PROCEDURE Procedure, OPTIONAL
389 IN VOID *ProcedureArgument, OPTIONAL
390 IN BOOLEAN WakeUpDisabledAps OPTIONAL
391 );
392
393 /**
394 Initialize global data for MP support.
395
396 @param[in] CpuMpData The pointer to CPU MP Data structure.
397 **/
398 VOID
399 InitMpGlobalData (
400 IN CPU_MP_DATA *CpuMpData
401 );
402
403 /**
404 Worker function to execute a caller provided function on all enabled APs.
405
406 @param[in] Procedure A pointer to the function to be run on
407 enabled APs of the system.
408 @param[in] SingleThread If TRUE, then all the enabled APs execute
409 the function specified by Procedure one by
410 one, in ascending order of processor handle
411 number. If FALSE, then all the enabled APs
412 execute the function specified by Procedure
413 simultaneously.
414 @param[in] WaitEvent The event created by the caller with CreateEvent()
415 service.
416 @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
417 APs to return from Procedure, either for
418 blocking or non-blocking mode.
419 @param[in] ProcedureArgument The parameter passed into Procedure for
420 all APs.
421 @param[out] FailedCpuList If all APs finish successfully, then its
422 content is set to NULL. If not all APs
423 finish before timeout expires, then its
424 content is set to address of the buffer
425 holding handle numbers of the failed APs.
426
427 @retval EFI_SUCCESS In blocking mode, all APs have finished before
428 the timeout expired.
429 @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
430 to all enabled APs.
431 @retval others Failed to Startup all APs.
432
433 **/
434 EFI_STATUS
435 StartupAllAPsWorker (
436 IN EFI_AP_PROCEDURE Procedure,
437 IN BOOLEAN SingleThread,
438 IN EFI_EVENT WaitEvent OPTIONAL,
439 IN UINTN TimeoutInMicroseconds,
440 IN VOID *ProcedureArgument OPTIONAL,
441 OUT UINTN **FailedCpuList OPTIONAL
442 );
443
444 /**
445 Worker function to let the caller get one enabled AP to execute a caller-provided
446 function.
447
448 @param[in] Procedure A pointer to the function to be run on
449 enabled APs of the system.
450 @param[in] ProcessorNumber The handle number of the AP.
451 @param[in] WaitEvent The event created by the caller with CreateEvent()
452 service.
453 @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
454 APs to return from Procedure, either for
455 blocking or non-blocking mode.
456 @param[in] ProcedureArgument The parameter passed into Procedure for
457 all APs.
458 @param[out] Finished If AP returns from Procedure before the
459 timeout expires, its content is set to TRUE.
460 Otherwise, the value is set to FALSE.
461
462 @retval EFI_SUCCESS In blocking mode, specified AP finished before
463 the timeout expires.
464 @retval others Failed to Startup AP.
465
466 **/
467 EFI_STATUS
468 StartupThisAPWorker (
469 IN EFI_AP_PROCEDURE Procedure,
470 IN UINTN ProcessorNumber,
471 IN EFI_EVENT WaitEvent OPTIONAL,
472 IN UINTN TimeoutInMicroseconds,
473 IN VOID *ProcedureArgument OPTIONAL,
474 OUT BOOLEAN *Finished OPTIONAL
475 );
476
477 /**
478 Worker function to switch the requested AP to be the BSP from that point onward.
479
480 @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.
481 @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
482 enabled AP. Otherwise, it will be disabled.
483
484 @retval EFI_SUCCESS BSP successfully switched.
485 @retval others Failed to switch BSP.
486
487 **/
488 EFI_STATUS
489 SwitchBSPWorker (
490 IN UINTN ProcessorNumber,
491 IN BOOLEAN EnableOldBSP
492 );
493
494 /**
495 Worker function to let the caller enable or disable an AP from this point onward.
496 This service may only be called from the BSP.
497
498 @param[in] ProcessorNumber The handle number of AP.
499 @param[in] EnableAP Specifies the new state for the processor for
500 enabled, FALSE for disabled.
501 @param[in] HealthFlag If not NULL, a pointer to a value that specifies
502 the new health status of the AP.
503
504 @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
505 @retval others Failed to Enable/Disable AP.
506
507 **/
508 EFI_STATUS
509 EnableDisableApWorker (
510 IN UINTN ProcessorNumber,
511 IN BOOLEAN EnableAP,
512 IN UINT32 *HealthFlag OPTIONAL
513 );
514
515 /**
516 Get pointer to CPU MP Data structure from GUIDed HOB.
517
518 @return The pointer to CPU MP Data structure.
519 **/
520 CPU_MP_DATA *
521 GetCpuMpDataFromGuidedHob (
522 VOID
523 );
524
525 /** Checks status of specified AP.
526
527 This function checks whether the specified AP has finished the task assigned
528 by StartupThisAP(), and whether timeout expires.
529
530 @param[in] ProcessorNumber The handle number of processor.
531
532 @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs().
533 @retval EFI_TIMEOUT The timeout expires.
534 @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired.
535 **/
536 EFI_STATUS
537 CheckThisAP (
538 IN UINTN ProcessorNumber
539 );
540
541 /**
542 Checks status of all APs.
543
544 This function checks whether all APs have finished task assigned by StartupAllAPs(),
545 and whether timeout expires.
546
547 @retval EFI_SUCCESS All APs have finished task assigned by StartupAllAPs().
548 @retval EFI_TIMEOUT The timeout expires.
549 @retval EFI_NOT_READY APs have not finished task and timeout has not expired.
550 **/
551 EFI_STATUS
552 CheckAllAPs (
553 VOID
554 );
555
556 /**
557 Checks APs status and updates APs status if needed.
558
559 **/
560 VOID
561 CheckAndUpdateApsStatus (
562 VOID
563 );
564
565 /**
566 Detect whether specified processor can find matching microcode patch and load it.
567
568 @param[in] CpuMpData The pointer to CPU MP Data structure.
569 @param[in] IsBspCallIn Indicate whether the caller is BSP or not.
570 **/
571 VOID
572 MicrocodeDetect (
573 IN CPU_MP_DATA *CpuMpData,
574 IN BOOLEAN IsBspCallIn
575 );
576
577 /**
578 Detect whether Mwait-monitor feature is supported.
579
580 @retval TRUE Mwait-monitor feature is supported.
581 @retval FALSE Mwait-monitor feature is not supported.
582 **/
583 BOOLEAN
584 IsMwaitSupport (
585 VOID
586 );
587
588 /**
589 Enable Debug Agent to support source debugging on AP function.
590
591 **/
592 VOID
593 EnableDebugAgent (
594 VOID
595 );
596
597 #endif
598