1 /** @file
2   Common header file for MP Initialize Library.
3 
4   Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
5   Copyright (c) 2020, AMD Inc. All rights reserved.<BR>
6 
7   SPDX-License-Identifier: BSD-2-Clause-Patent
8 
9 **/
10 
11 #ifndef _MP_LIB_H_
12 #define _MP_LIB_H_
13 
14 #include <PiPei.h>
15 
16 #include <Register/Intel/Cpuid.h>
17 #include <Register/Amd/Cpuid.h>
18 #include <Register/Intel/Msr.h>
19 #include <Register/Intel/LocalApic.h>
20 #include <Register/Intel/Microcode.h>
21 
22 #include <Library/MpInitLib.h>
23 #include <Library/BaseLib.h>
24 #include <Library/BaseMemoryLib.h>
25 #include <Library/MemoryAllocationLib.h>
26 #include <Library/DebugLib.h>
27 #include <Library/LocalApicLib.h>
28 #include <Library/CpuLib.h>
29 #include <Library/UefiCpuLib.h>
30 #include <Library/TimerLib.h>
31 #include <Library/SynchronizationLib.h>
32 #include <Library/MtrrLib.h>
33 #include <Library/HobLib.h>
34 #include <Library/PcdLib.h>
35 
36 #include <Guid/MicrocodePatchHob.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 // Default maximum number of entries to store the microcode patches information
54 //
55 #define DEFAULT_MAX_MICROCODE_PATCH_NUM 8
56 
57 //
58 // Data structure for microcode patch information
59 //
60 typedef struct {
61   UINTN    Address;
62   UINTN    Size;
63 } MICROCODE_PATCH_INFO;
64 
65 //
66 // CPU exchange information for switch BSP
67 //
68 typedef struct {
69   UINT8             State;        // offset 0
70   UINTN             StackPointer; // offset 4 / 8
71   IA32_DESCRIPTOR   Gdtr;         // offset 8 / 16
72   IA32_DESCRIPTOR   Idtr;         // offset 14 / 26
73 } CPU_EXCHANGE_ROLE_INFO;
74 
75 //
76 // AP loop state when APs are in idle state
77 // It's value is the same with PcdCpuApLoopMode
78 //
79 typedef enum {
80   ApInHltLoop   = 1,
81   ApInMwaitLoop = 2,
82   ApInRunLoop   = 3
83 } AP_LOOP_MODE;
84 
85 //
86 // AP initialization state during APs wakeup
87 //
88 typedef enum {
89   ApInitConfig   = 1,
90   ApInitReconfig = 2,
91   ApInitDone     = 3
92 } AP_INIT_STATE;
93 
94 //
95 // AP state
96 //
97 // The state transitions for an AP when it process a procedure are:
98 //  Idle ----> Ready ----> Busy ----> Idle
99 //       [BSP]       [AP]       [AP]
100 //
101 typedef enum {
102   CpuStateIdle,
103   CpuStateReady,
104   CpuStateBusy,
105   CpuStateFinished,
106   CpuStateDisabled
107 } CPU_STATE;
108 
109 //
110 // CPU volatile registers around INIT-SIPI-SIPI
111 //
112 typedef struct {
113   UINTN                          Cr0;
114   UINTN                          Cr3;
115   UINTN                          Cr4;
116   UINTN                          Dr0;
117   UINTN                          Dr1;
118   UINTN                          Dr2;
119   UINTN                          Dr3;
120   UINTN                          Dr6;
121   UINTN                          Dr7;
122   IA32_DESCRIPTOR                Gdtr;
123   IA32_DESCRIPTOR                Idtr;
124   UINT16                         Tr;
125 } CPU_VOLATILE_REGISTERS;
126 
127 //
128 // AP related data
129 //
130 typedef struct {
131   SPIN_LOCK                      ApLock;
132   volatile UINT32                *StartupApSignal;
133   volatile UINTN                 ApFunction;
134   volatile UINTN                 ApFunctionArgument;
135   BOOLEAN                        CpuHealthy;
136   volatile CPU_STATE             State;
137   CPU_VOLATILE_REGISTERS         VolatileRegisters;
138   BOOLEAN                        Waiting;
139   BOOLEAN                        *Finished;
140   UINT64                         ExpectedTime;
141   UINT64                         CurrentTime;
142   UINT64                         TotalTime;
143   EFI_EVENT                      WaitEvent;
144   UINT32                         ProcessorSignature;
145   UINT8                          PlatformId;
146   UINT64                         MicrocodeEntryAddr;
147 } CPU_AP_DATA;
148 
149 //
150 // Basic CPU information saved in Guided HOB.
151 // Because the contents will be shard between PEI and DXE,
152 // we need to make sure the each fields offset same in different
153 // architecture.
154 //
155 #pragma pack (1)
156 typedef struct {
157   UINT32                         InitialApicId;
158   UINT32                         ApicId;
159   UINT32                         Health;
160   UINT64                         ApTopOfStack;
161 } CPU_INFO_IN_HOB;
162 #pragma pack ()
163 
164 //
165 // AP reset code information including code address and size,
166 // this structure will be shared be C code and assembly code.
167 // It is natural aligned by design.
168 //
169 typedef struct {
170   UINT8             *RendezvousFunnelAddress;
171   UINTN             ModeEntryOffset;
172   UINTN             RendezvousFunnelSize;
173   UINT8             *RelocateApLoopFuncAddress;
174   UINTN             RelocateApLoopFuncSize;
175   UINTN             ModeTransitionOffset;
176   UINTN             SwitchToRealSize;
177   UINTN             SwitchToRealOffset;
178   UINTN             SwitchToRealNoNxOffset;
179   UINTN             SwitchToRealPM16ModeOffset;
180   UINTN             SwitchToRealPM16ModeSize;
181 } MP_ASSEMBLY_ADDRESS_MAP;
182 
183 typedef struct _CPU_MP_DATA  CPU_MP_DATA;
184 
185 #pragma pack(1)
186 
187 //
188 // MP CPU exchange information for AP reset code
189 // This structure is required to be packed because fixed field offsets
190 // into this structure are used in assembly code in this module
191 //
192 typedef struct {
193   UINTN                 Lock;
194   UINTN                 StackStart;
195   UINTN                 StackSize;
196   UINTN                 CFunction;
197   IA32_DESCRIPTOR       GdtrProfile;
198   IA32_DESCRIPTOR       IdtrProfile;
199   UINTN                 BufferStart;
200   UINTN                 ModeOffset;
201   UINTN                 ApIndex;
202   UINTN                 CodeSegment;
203   UINTN                 DataSegment;
204   UINTN                 EnableExecuteDisable;
205   UINTN                 Cr3;
206   UINTN                 InitFlag;
207   CPU_INFO_IN_HOB       *CpuInfo;
208   UINTN                 NumApsExecuting;
209   CPU_MP_DATA           *CpuMpData;
210   UINTN                 InitializeFloatingPointUnitsAddress;
211   UINT32                ModeTransitionMemory;
212   UINT16                ModeTransitionSegment;
213   UINT32                ModeHighMemory;
214   UINT16                ModeHighSegment;
215   //
216   // Enable5LevelPaging indicates whether 5-level paging is enabled in long mode.
217   //
218   BOOLEAN               Enable5LevelPaging;
219   BOOLEAN               SevEsIsEnabled;
220   UINTN                 GhcbBase;
221 } MP_CPU_EXCHANGE_INFO;
222 
223 #pragma pack()
224 
225 //
226 // CPU MP Data save in memory
227 //
228 struct _CPU_MP_DATA {
229   UINT64                         CpuInfoInHob;
230   UINT32                         CpuCount;
231   UINT32                         BspNumber;
232   //
233   // The above fields data will be passed from PEI to DXE
234   // Please make sure the fields offset same in the different
235   // architecture.
236   //
237   SPIN_LOCK                      MpLock;
238   UINTN                          Buffer;
239   UINTN                          CpuApStackSize;
240   MP_ASSEMBLY_ADDRESS_MAP        AddressMap;
241   UINTN                          WakeupBuffer;
242   UINTN                          WakeupBufferHigh;
243   UINTN                          BackupBuffer;
244   UINTN                          BackupBufferSize;
245 
246   volatile UINT32                FinishedCount;
247   UINT32                         RunningCount;
248   BOOLEAN                        SingleThread;
249   EFI_AP_PROCEDURE               Procedure;
250   VOID                           *ProcArguments;
251   BOOLEAN                        *Finished;
252   UINT64                         ExpectedTime;
253   UINT64                         CurrentTime;
254   UINT64                         TotalTime;
255   EFI_EVENT                      WaitEvent;
256   UINTN                          **FailedCpuList;
257 
258   AP_INIT_STATE                  InitFlag;
259   BOOLEAN                        SwitchBspFlag;
260   UINTN                          NewBspNumber;
261   CPU_EXCHANGE_ROLE_INFO         BSPInfo;
262   CPU_EXCHANGE_ROLE_INFO         APInfo;
263   MTRR_SETTINGS                  MtrrTable;
264   UINT8                          ApLoopMode;
265   UINT8                          ApTargetCState;
266   UINT16                         PmCodeSegment;
267   UINT16                         Pm16CodeSegment;
268   CPU_AP_DATA                    *CpuData;
269   volatile MP_CPU_EXCHANGE_INFO  *MpCpuExchangeInfo;
270 
271   UINT32                         CurrentTimerCount;
272   UINTN                          DivideValue;
273   UINT8                          Vector;
274   BOOLEAN                        PeriodicMode;
275   BOOLEAN                        TimerInterruptState;
276   UINT64                         MicrocodePatchAddress;
277   UINT64                         MicrocodePatchRegionSize;
278 
279   //
280   // Whether need to use Init-Sipi-Sipi to wake up the APs.
281   // Two cases need to set this value to TRUE. One is in HLT
282   // loop mode, the other is resume from S3 which loop mode
283   // will be hardcode change to HLT mode by PiSmmCpuDxeSmm
284   // driver.
285   //
286   BOOLEAN                        WakeUpByInitSipiSipi;
287 
288   BOOLEAN                        SevEsIsEnabled;
289   UINTN                          SevEsAPBuffer;
290   UINTN                          SevEsAPResetStackStart;
291   CPU_MP_DATA                    *NewCpuMpData;
292 
293   UINT64                         GhcbBase;
294 };
295 
296 #define AP_SAFE_STACK_SIZE  128
297 #define AP_RESET_STACK_SIZE AP_SAFE_STACK_SIZE
298 
299 #pragma pack(1)
300 
301 typedef struct {
302   UINT8   InsnBuffer[8];
303   UINT16  Rip;
304   UINT16  Segment;
305 } SEV_ES_AP_JMP_FAR;
306 
307 #pragma pack()
308 
309 /**
310   Assembly code to move an AP from long mode to real mode.
311 
312   Move an AP from long mode to real mode in preparation to invoking
313   the reset vector.  This is used for SEV-ES guests where a hypervisor
314   is not allowed to set the CS and RIP to point to the reset vector.
315 
316   @param[in]  BufferStart  The reset vector target.
317   @param[in]  Code16       16-bit protected mode code segment value.
318   @param[in]  Code32       32-bit protected mode code segment value.
319   @param[in]  StackStart   The start of a stack to be used for transitioning
320                            from long mode to real mode.
321 **/
322 typedef
323 VOID
324 (EFIAPI AP_RESET) (
325   IN UINTN    BufferStart,
326   IN UINT16   Code16,
327   IN UINT16   Code32,
328   IN UINTN    StackStart
329   );
330 
331 extern EFI_GUID mCpuInitMpLibHobGuid;
332 
333 /**
334   Assembly code to place AP into safe loop mode.
335 
336   Place AP into targeted C-State if MONITOR is supported, otherwise
337   place AP into hlt state.
338   Place AP in protected mode if the current is long mode. Due to AP maybe
339   wakeup by some hardware event. It could avoid accessing page table that
340   may not available during booting to OS.
341 
342   @param[in] MwaitSupport    TRUE indicates MONITOR is supported.
343                              FALSE indicates MONITOR is not supported.
344   @param[in] ApTargetCState  Target C-State value.
345   @param[in] PmCodeSegment   Protected mode code segment value.
346 **/
347 typedef
348 VOID
349 (EFIAPI * ASM_RELOCATE_AP_LOOP) (
350   IN BOOLEAN                 MwaitSupport,
351   IN UINTN                   ApTargetCState,
352   IN UINTN                   PmCodeSegment,
353   IN UINTN                   TopOfApStack,
354   IN UINTN                   NumberToFinish,
355   IN UINTN                   Pm16CodeSegment,
356   IN UINTN                   SevEsAPJumpTable,
357   IN UINTN                   WakeupBuffer
358   );
359 
360 /**
361   Assembly code to get starting address and size of the rendezvous entry for APs.
362   Information for fixing a jump instruction in the code is also returned.
363 
364   @param[out] AddressMap  Output buffer for address map information.
365 **/
366 VOID
367 EFIAPI
368 AsmGetAddressMap (
369   OUT MP_ASSEMBLY_ADDRESS_MAP    *AddressMap
370   );
371 
372 /**
373   This function is called by both the BSP and the AP which is to become the BSP to
374   Exchange execution context including stack between them. After return from this
375   function, the BSP becomes AP and the AP becomes the BSP.
376 
377   @param[in] MyInfo      Pointer to buffer holding the exchanging information for the executing processor.
378   @param[in] OthersInfo  Pointer to buffer holding the exchanging information for the peer.
379 
380 **/
381 VOID
382 EFIAPI
383 AsmExchangeRole (
384   IN CPU_EXCHANGE_ROLE_INFO    *MyInfo,
385   IN CPU_EXCHANGE_ROLE_INFO    *OthersInfo
386   );
387 
388 /**
389   Get the pointer to CPU MP Data structure.
390 
391   @return  The pointer to CPU MP Data structure.
392 **/
393 CPU_MP_DATA *
394 GetCpuMpData (
395   VOID
396   );
397 
398 /**
399   Save the pointer to CPU MP Data structure.
400 
401   @param[in] CpuMpData  The pointer to CPU MP Data structure will be saved.
402 **/
403 VOID
404 SaveCpuMpData (
405   IN CPU_MP_DATA   *CpuMpData
406   );
407 
408 
409 /**
410   Get available system memory below 1MB by specified size.
411 
412   @param[in] WakeupBufferSize   Wakeup buffer size required
413 
414   @retval other   Return wakeup buffer address below 1MB.
415   @retval -1      Cannot find free memory below 1MB.
416 **/
417 UINTN
418 GetWakeupBuffer (
419   IN UINTN                WakeupBufferSize
420   );
421 
422 /**
423   Get available EfiBootServicesCode memory below 4GB by specified size.
424 
425   This buffer is required to safely transfer AP from real address mode to
426   protected mode or long mode, due to the fact that the buffer returned by
427   GetWakeupBuffer() may be marked as non-executable.
428 
429   @param[in] BufferSize   Wakeup transition buffer size.
430 
431   @retval other   Return wakeup transition buffer address below 4GB.
432   @retval 0       Cannot find free memory below 4GB.
433 **/
434 UINTN
435 GetModeTransitionBuffer (
436   IN UINTN                BufferSize
437   );
438 
439 /**
440   Return the address of the SEV-ES AP jump table.
441 
442   This buffer is required in order for an SEV-ES guest to transition from
443   UEFI into an OS.
444 
445   @return         Return SEV-ES AP jump table buffer
446 **/
447 UINTN
448 GetSevEsAPMemory (
449   VOID
450   );
451 
452 /**
453   This function will be called by BSP to wakeup AP.
454 
455   @param[in] CpuMpData          Pointer to CPU MP Data
456   @param[in] Broadcast          TRUE:  Send broadcast IPI to all APs
457                                 FALSE: Send IPI to AP by ApicId
458   @param[in] ProcessorNumber    The handle number of specified processor
459   @param[in] Procedure          The function to be invoked by AP
460   @param[in] ProcedureArgument  The argument to be passed into AP function
461   @param[in] WakeUpDisabledAps  Whether need to wake up disabled APs in broadcast mode.
462 **/
463 VOID
464 WakeUpAP (
465   IN CPU_MP_DATA               *CpuMpData,
466   IN BOOLEAN                   Broadcast,
467   IN UINTN                     ProcessorNumber,
468   IN EFI_AP_PROCEDURE          Procedure,              OPTIONAL
469   IN VOID                      *ProcedureArgument,     OPTIONAL
470   IN BOOLEAN                   WakeUpDisabledAps       OPTIONAL
471   );
472 
473 /**
474   Initialize global data for MP support.
475 
476   @param[in] CpuMpData  The pointer to CPU MP Data structure.
477 **/
478 VOID
479 InitMpGlobalData (
480   IN CPU_MP_DATA               *CpuMpData
481   );
482 
483 /**
484   Worker function to execute a caller provided function on all enabled APs.
485 
486   @param[in]  Procedure               A pointer to the function to be run on
487                                       enabled APs of the system.
488   @param[in]  SingleThread            If TRUE, then all the enabled APs execute
489                                       the function specified by Procedure one by
490                                       one, in ascending order of processor handle
491                                       number.  If FALSE, then all the enabled APs
492                                       execute the function specified by Procedure
493                                       simultaneously.
494   @param[in]  ExcludeBsp              Whether let BSP also trig this task.
495   @param[in]  WaitEvent               The event created by the caller with CreateEvent()
496                                       service.
497   @param[in]  TimeoutInMicroseconds   Indicates the time limit in microseconds for
498                                       APs to return from Procedure, either for
499                                       blocking or non-blocking mode.
500   @param[in]  ProcedureArgument       The parameter passed into Procedure for
501                                       all APs.
502   @param[out] FailedCpuList           If all APs finish successfully, then its
503                                       content is set to NULL. If not all APs
504                                       finish before timeout expires, then its
505                                       content is set to address of the buffer
506                                       holding handle numbers of the failed APs.
507 
508   @retval EFI_SUCCESS             In blocking mode, all APs have finished before
509                                   the timeout expired.
510   @retval EFI_SUCCESS             In non-blocking mode, function has been dispatched
511                                   to all enabled APs.
512   @retval others                  Failed to Startup all APs.
513 
514 **/
515 EFI_STATUS
516 StartupAllCPUsWorker (
517   IN  EFI_AP_PROCEDURE          Procedure,
518   IN  BOOLEAN                   SingleThread,
519   IN  BOOLEAN                   ExcludeBsp,
520   IN  EFI_EVENT                 WaitEvent               OPTIONAL,
521   IN  UINTN                     TimeoutInMicroseconds,
522   IN  VOID                      *ProcedureArgument      OPTIONAL,
523   OUT UINTN                     **FailedCpuList         OPTIONAL
524   );
525 
526 /**
527   Worker function to let the caller get one enabled AP to execute a caller-provided
528   function.
529 
530   @param[in]  Procedure               A pointer to the function to be run on
531                                       enabled APs of the system.
532   @param[in]  ProcessorNumber         The handle number of the AP.
533   @param[in]  WaitEvent               The event created by the caller with CreateEvent()
534                                       service.
535   @param[in]  TimeoutInMicroseconds   Indicates the time limit in microseconds for
536                                       APs to return from Procedure, either for
537                                       blocking or non-blocking mode.
538   @param[in]  ProcedureArgument       The parameter passed into Procedure for
539                                       all APs.
540   @param[out] Finished                If AP returns from Procedure before the
541                                       timeout expires, its content is set to TRUE.
542                                       Otherwise, the value is set to FALSE.
543 
544   @retval EFI_SUCCESS             In blocking mode, specified AP finished before
545                                   the timeout expires.
546   @retval others                  Failed to Startup AP.
547 
548 **/
549 EFI_STATUS
550 StartupThisAPWorker (
551   IN  EFI_AP_PROCEDURE          Procedure,
552   IN  UINTN                     ProcessorNumber,
553   IN  EFI_EVENT                 WaitEvent               OPTIONAL,
554   IN  UINTN                     TimeoutInMicroseconds,
555   IN  VOID                      *ProcedureArgument      OPTIONAL,
556   OUT BOOLEAN                   *Finished               OPTIONAL
557   );
558 
559 /**
560   Worker function to switch the requested AP to be the BSP from that point onward.
561 
562   @param[in] ProcessorNumber   The handle number of AP that is to become the new BSP.
563   @param[in] EnableOldBSP      If TRUE, then the old BSP will be listed as an
564                                enabled AP. Otherwise, it will be disabled.
565 
566   @retval EFI_SUCCESS          BSP successfully switched.
567   @retval others               Failed to switch BSP.
568 
569 **/
570 EFI_STATUS
571 SwitchBSPWorker (
572   IN UINTN                     ProcessorNumber,
573   IN BOOLEAN                   EnableOldBSP
574   );
575 
576 /**
577   Worker function to let the caller enable or disable an AP from this point onward.
578   This service may only be called from the BSP.
579 
580   @param[in] ProcessorNumber   The handle number of AP.
581   @param[in] EnableAP          Specifies the new state for the processor for
582                                enabled, FALSE for disabled.
583   @param[in] HealthFlag        If not NULL, a pointer to a value that specifies
584                                the new health status of the AP.
585 
586   @retval EFI_SUCCESS          The specified AP was enabled or disabled successfully.
587   @retval others               Failed to Enable/Disable AP.
588 
589 **/
590 EFI_STATUS
591 EnableDisableApWorker (
592   IN  UINTN                     ProcessorNumber,
593   IN  BOOLEAN                   EnableAP,
594   IN  UINT32                    *HealthFlag OPTIONAL
595   );
596 
597 /**
598   Get pointer to CPU MP Data structure from GUIDed HOB.
599 
600   @return  The pointer to CPU MP Data structure.
601 **/
602 CPU_MP_DATA *
603 GetCpuMpDataFromGuidedHob (
604   VOID
605   );
606 
607 /** Checks status of specified AP.
608 
609   This function checks whether the specified AP has finished the task assigned
610   by StartupThisAP(), and whether timeout expires.
611 
612   @param[in]  ProcessorNumber       The handle number of processor.
613 
614   @retval EFI_SUCCESS           Specified AP has finished task assigned by StartupThisAPs().
615   @retval EFI_TIMEOUT           The timeout expires.
616   @retval EFI_NOT_READY         Specified AP has not finished task and timeout has not expired.
617 **/
618 EFI_STATUS
619 CheckThisAP (
620   IN UINTN        ProcessorNumber
621   );
622 
623 /**
624   Checks status of all APs.
625 
626   This function checks whether all APs have finished task assigned by StartupAllAPs(),
627   and whether timeout expires.
628 
629   @retval EFI_SUCCESS           All APs have finished task assigned by StartupAllAPs().
630   @retval EFI_TIMEOUT           The timeout expires.
631   @retval EFI_NOT_READY         APs have not finished task and timeout has not expired.
632 **/
633 EFI_STATUS
634 CheckAllAPs (
635   VOID
636   );
637 
638 /**
639   Checks APs status and updates APs status if needed.
640 
641 **/
642 VOID
643 CheckAndUpdateApsStatus (
644   VOID
645   );
646 
647 /**
648   Detect whether specified processor can find matching microcode patch and load it.
649 
650   @param[in]  CpuMpData        The pointer to CPU MP Data structure.
651   @param[in]  ProcessorNumber  The handle number of the processor. The range is
652                                from 0 to the total number of logical processors
653                                minus 1.
654 **/
655 VOID
656 MicrocodeDetect (
657   IN CPU_MP_DATA             *CpuMpData,
658   IN UINTN                   ProcessorNumber
659   );
660 
661 /**
662   Shadow the required microcode patches data into memory.
663 
664   @param[in, out]  CpuMpData    The pointer to CPU MP Data structure.
665 **/
666 VOID
667 ShadowMicrocodeUpdatePatch (
668   IN OUT CPU_MP_DATA             *CpuMpData
669   );
670 
671 /**
672   Get the cached microcode patch base address and size from the microcode patch
673   information cache HOB.
674 
675   @param[out] Address       Base address of the microcode patches data.
676                             It will be updated if the microcode patch
677                             information cache HOB is found.
678   @param[out] RegionSize    Size of the microcode patches data.
679                             It will be updated if the microcode patch
680                             information cache HOB is found.
681 
682   @retval  TRUE     The microcode patch information cache HOB is found.
683   @retval  FALSE    The microcode patch information cache HOB is not found.
684 
685 **/
686 BOOLEAN
687 GetMicrocodePatchInfoFromHob (
688   UINT64                         *Address,
689   UINT64                         *RegionSize
690   );
691 
692 /**
693   Detect whether Mwait-monitor feature is supported.
694 
695   @retval TRUE    Mwait-monitor feature is supported.
696   @retval FALSE   Mwait-monitor feature is not supported.
697 **/
698 BOOLEAN
699 IsMwaitSupport (
700   VOID
701   );
702 
703 /**
704   Enable Debug Agent to support source debugging on AP function.
705 
706 **/
707 VOID
708 EnableDebugAgent (
709   VOID
710   );
711 
712 /**
713   Find the current Processor number by APIC ID.
714 
715   @param[in]  CpuMpData         Pointer to PEI CPU MP Data
716   @param[out] ProcessorNumber   Return the pocessor number found
717 
718   @retval EFI_SUCCESS          ProcessorNumber is found and returned.
719   @retval EFI_NOT_FOUND        ProcessorNumber is not found.
720 **/
721 EFI_STATUS
722 GetProcessorNumber (
723   IN CPU_MP_DATA               *CpuMpData,
724   OUT UINTN                    *ProcessorNumber
725   );
726 
727 /**
728   This funtion will try to invoke platform specific microcode shadow logic to
729   relocate microcode update patches into memory.
730 
731   @param[in, out] CpuMpData  The pointer to CPU MP Data structure.
732 
733   @retval EFI_SUCCESS              Shadow microcode success.
734   @retval EFI_OUT_OF_RESOURCES     No enough resource to complete the operation.
735   @retval EFI_UNSUPPORTED          Can't find platform specific microcode shadow
736                                    PPI/Protocol.
737 **/
738 EFI_STATUS
739 PlatformShadowMicrocode (
740   IN OUT CPU_MP_DATA             *CpuMpData
741   );
742 
743 #endif
744 
745