1 /** @file
2   When installed, the MP Services Protocol produces a collection of services
3   that are needed for MP management.
4 
5   The MP Services Protocol provides a generalized way of performing following tasks:
6     - Retrieving information of multi-processor environment and MP-related status of
7       specific processors.
8     - Dispatching user-provided function to APs.
9     - Maintain MP-related processor status.
10 
11   The MP Services Protocol must be produced on any system with more than one logical
12   processor.
13 
14   The Protocol is available only during boot time.
15 
16   MP Services Protocol is hardware-independent. Most of the logic of this protocol
17   is architecturally neutral. It abstracts the multi-processor environment and
18   status of processors, and provides interfaces to retrieve information, maintain,
19   and dispatch.
20 
21   MP Services Protocol may be consumed by ACPI module. The ACPI module may use this
22   protocol to retrieve data that are needed for an MP platform and report them to OS.
23   MP Services Protocol may also be used to program and configure processors, such
24   as MTRR synchronization for memory space attributes setting in DXE Services.
25   MP Services Protocol may be used by non-CPU DXE drivers to speed up platform boot
26   by taking advantage of the processing capabilities of the APs, for example, using
27   APs to help test system memory in parallel with other device initialization.
28   Diagnostics applications may also use this protocol for multi-processor.
29 
30 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
31 SPDX-License-Identifier: BSD-2-Clause-Patent
32 
33   @par Revision Reference:
34   This Protocol is defined in the UEFI Platform Initialization Specification 1.2,
35   Volume 2:Driver Execution Environment Core Interface.
36 
37 **/
38 
39 #ifndef _MP_SERVICE_PROTOCOL_H_
40 #define _MP_SERVICE_PROTOCOL_H_
41 
42 ///
43 /// Global ID for the EFI_MP_SERVICES_PROTOCOL.
44 ///
45 #define EFI_MP_SERVICES_PROTOCOL_GUID \
46   { \
47     0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08} \
48   }
49 
50 ///
51 /// Value used in the NumberProcessors parameter of the GetProcessorInfo function
52 ///
53 #define CPU_V2_EXTENDED_TOPOLOGY  BIT24
54 
55 ///
56 /// Forward declaration for the EFI_MP_SERVICES_PROTOCOL.
57 ///
58 typedef struct _EFI_MP_SERVICES_PROTOCOL EFI_MP_SERVICES_PROTOCOL;
59 
60 ///
61 /// Terminator for a list of failed CPUs returned by StartAllAPs().
62 ///
63 #define END_OF_CPU_LIST  0xffffffff
64 
65 ///
66 /// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
67 /// indicates whether the processor is playing the role of BSP. If the bit is 1,
68 /// then the processor is BSP. Otherwise, it is AP.
69 ///
70 #define PROCESSOR_AS_BSP_BIT  0x00000001
71 
72 ///
73 /// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
74 /// indicates whether the processor is enabled. If the bit is 1, then the
75 /// processor is enabled. Otherwise, it is disabled.
76 ///
77 #define PROCESSOR_ENABLED_BIT  0x00000002
78 
79 ///
80 /// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
81 /// indicates whether the processor is healthy. If the bit is 1, then the
82 /// processor is healthy. Otherwise, some fault has been detected for the processor.
83 ///
84 #define PROCESSOR_HEALTH_STATUS_BIT  0x00000004
85 
86 ///
87 /// Structure that describes the pyhiscal location of a logical CPU.
88 ///
89 typedef struct {
90   ///
91   /// Zero-based physical package number that identifies the cartridge of the processor.
92   ///
93   UINT32    Package;
94   ///
95   /// Zero-based physical core number within package of the processor.
96   ///
97   UINT32    Core;
98   ///
99   /// Zero-based logical thread number within core of the processor.
100   ///
101   UINT32    Thread;
102 } EFI_CPU_PHYSICAL_LOCATION;
103 
104 ///
105 ///  Structure that defines the 6-level physical location of the processor
106 ///
107 typedef struct {
108   ///
109   ///    Package     Zero-based physical package number that identifies the cartridge of the processor.
110   ///
111   UINT32    Package;
112   ///
113   ///    Module      Zero-based physical module number within package of the processor.
114   ///
115   UINT32    Module;
116   ///
117   ///    Tile        Zero-based physical tile number within module of the processor.
118   ///
119   UINT32    Tile;
120   ///
121   ///    Die         Zero-based physical die number within tile of the processor.
122   ///
123   UINT32    Die;
124   ///
125   ///     Core        Zero-based physical core number within die of the processor.
126   ///
127   UINT32    Core;
128   ///
129   ///     Thread      Zero-based logical thread number within core of the processor.
130   ///
131   UINT32    Thread;
132 } EFI_CPU_PHYSICAL_LOCATION2;
133 
134 typedef union {
135   /// The 6-level physical location of the processor, including the
136   /// physical package number that identifies the cartridge, the physical
137   /// module number within package, the physical tile number within the module,
138   /// the physical die number within the tile, the physical core number within
139   /// package, and logical thread number within core.
140   EFI_CPU_PHYSICAL_LOCATION2    Location2;
141 } EXTENDED_PROCESSOR_INFORMATION;
142 
143 ///
144 /// Structure that describes information about a logical CPU.
145 ///
146 typedef struct {
147   ///
148   /// The unique processor ID determined by system hardware.  For IA32 and X64,
149   /// the processor ID is the same as the Local APIC ID. Only the lower 8 bits
150   /// are used, and higher bits are reserved.  For IPF, the lower 16 bits contains
151   /// id/eid, and higher bits are reserved.
152   ///
153   UINT64    ProcessorId;
154   ///
155   /// Flags indicating if the processor is BSP or AP, if the processor is enabled
156   /// or disabled, and if the processor is healthy. Bits 3..31 are reserved and
157   /// must be 0.
158   ///
159   /// <pre>
160   /// BSP  ENABLED  HEALTH  Description
161   /// ===  =======  ======  ===================================================
162   ///  0      0       0     Unhealthy Disabled AP.
163   ///  0      0       1     Healthy Disabled AP.
164   ///  0      1       0     Unhealthy Enabled AP.
165   ///  0      1       1     Healthy Enabled AP.
166   ///  1      0       0     Invalid. The BSP can never be in the disabled state.
167   ///  1      0       1     Invalid. The BSP can never be in the disabled state.
168   ///  1      1       0     Unhealthy Enabled BSP.
169   ///  1      1       1     Healthy Enabled BSP.
170   /// </pre>
171   ///
172   UINT32                            StatusFlag;
173   ///
174   /// The physical location of the processor, including the physical package number
175   /// that identifies the cartridge, the physical core number within package, and
176   /// logical thread number within core.
177   ///
178   EFI_CPU_PHYSICAL_LOCATION         Location;
179   ///
180   /// The extended information of the processor. This field is filled only when
181   /// CPU_V2_EXTENDED_TOPOLOGY is set in parameter ProcessorNumber.
182   EXTENDED_PROCESSOR_INFORMATION    ExtendedInformation;
183 } EFI_PROCESSOR_INFORMATION;
184 
185 /**
186   This service retrieves the number of logical processor in the platform
187   and the number of those logical processors that are enabled on this boot.
188   This service may only be called from the BSP.
189 
190   This function is used to retrieve the following information:
191     - The number of logical processors that are present in the system.
192     - The number of enabled logical processors in the system at the instant
193       this call is made.
194 
195   Because MP Service Protocol provides services to enable and disable processors
196   dynamically, the number of enabled logical processors may vary during the
197   course of a boot session.
198 
199   If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
200   If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
201   EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
202   is returned in NumberOfProcessors, the number of currently enabled processor
203   is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
204 
205   @param[in]  This                        A pointer to the EFI_MP_SERVICES_PROTOCOL
206                                           instance.
207   @param[out] NumberOfProcessors          Pointer to the total number of logical
208                                           processors in the system, including the BSP
209                                           and disabled APs.
210   @param[out] NumberOfEnabledProcessors   Pointer to the number of enabled logical
211                                           processors that exist in system, including
212                                           the BSP.
213 
214   @retval EFI_SUCCESS             The number of logical processors and enabled
215                                   logical processors was retrieved.
216   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
217   @retval EFI_INVALID_PARAMETER   NumberOfProcessors is NULL.
218   @retval EFI_INVALID_PARAMETER   NumberOfEnabledProcessors is NULL.
219 
220 **/
221 typedef
222 EFI_STATUS
223 (EFIAPI *EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS)(
224   IN  EFI_MP_SERVICES_PROTOCOL  *This,
225   OUT UINTN                     *NumberOfProcessors,
226   OUT UINTN                     *NumberOfEnabledProcessors
227   );
228 
229 /**
230   Gets detailed MP-related information on the requested processor at the
231   instant this call is made. This service may only be called from the BSP.
232 
233   This service retrieves detailed MP-related information about any processor
234   on the platform. Note the following:
235     - The processor information may change during the course of a boot session.
236     - The information presented here is entirely MP related.
237 
238   Information regarding the number of caches and their sizes, frequency of operation,
239   slot numbers is all considered platform-related information and is not provided
240   by this service.
241 
242   @param[in]  This                  A pointer to the EFI_MP_SERVICES_PROTOCOL
243                                     instance.
244   @param[in]  ProcessorNumber       The handle number of processor.
245   @param[out] ProcessorInfoBuffer   A pointer to the buffer where information for
246                                     the requested processor is deposited.
247 
248   @retval EFI_SUCCESS             Processor information was returned.
249   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
250   @retval EFI_INVALID_PARAMETER   ProcessorInfoBuffer is NULL.
251   @retval EFI_NOT_FOUND           The processor with the handle specified by
252                                   ProcessorNumber does not exist in the platform.
253 
254 **/
255 typedef
256 EFI_STATUS
257 (EFIAPI *EFI_MP_SERVICES_GET_PROCESSOR_INFO)(
258   IN  EFI_MP_SERVICES_PROTOCOL   *This,
259   IN  UINTN                      ProcessorNumber,
260   OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer
261   );
262 
263 /**
264   This service executes a caller provided function on all enabled APs. APs can
265   run either simultaneously or one at a time in sequence. This service supports
266   both blocking and non-blocking requests. The non-blocking requests use EFI
267   events so the BSP can detect when the APs have finished. This service may only
268   be called from the BSP.
269 
270   This function is used to dispatch all the enabled APs to the function specified
271   by Procedure.  If any enabled AP is busy, then EFI_NOT_READY is returned
272   immediately and Procedure is not started on any AP.
273 
274   If SingleThread is TRUE, all the enabled APs execute the function specified by
275   Procedure one by one, in ascending order of processor handle number. Otherwise,
276   all the enabled APs execute the function specified by Procedure simultaneously.
277 
278   If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
279   APs finish or TimeoutInMicroSecs expires. Otherwise, execution is in non-blocking
280   mode, and the BSP returns from this service without waiting for APs. If a
281   non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
282   is signaled, then EFI_UNSUPPORTED must be returned.
283 
284   If the timeout specified by TimeoutInMicroseconds expires before all APs return
285   from Procedure, then Procedure on the failed APs is terminated. All enabled APs
286   are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
287   and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
288   content points to the list of processor handle numbers in which Procedure was
289   terminated.
290 
291   Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
292   to make sure that the nature of the code that is executed on the BSP and the
293   dispatched APs is well controlled. The MP Services Protocol does not guarantee
294   that the Procedure function is MP-safe. Hence, the tasks that can be run in
295   parallel are limited to certain independent tasks and well-controlled exclusive
296   code. EFI services and protocols may not be called by APs unless otherwise
297   specified.
298 
299   In blocking execution mode, BSP waits until all APs finish or
300   TimeoutInMicroSeconds expires.
301 
302   In non-blocking execution mode, BSP is freed to return to the caller and then
303   proceed to the next task without having to wait for APs. The following
304   sequence needs to occur in a non-blocking execution mode:
305 
306     -# The caller that intends to use this MP Services Protocol in non-blocking
307        mode creates WaitEvent by calling the EFI CreateEvent() service.  The caller
308        invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent
309        is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests
310        the function specified by Procedure to be started on all the enabled APs,
311        and releases the BSP to continue with other tasks.
312     -# The caller can use the CheckEvent() and WaitForEvent() services to check
313        the state of the WaitEvent created in step 1.
314     -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP
315        Service signals WaitEvent by calling the EFI SignalEvent() function. If
316        FailedCpuList is not NULL, its content is available when WaitEvent is
317        signaled. If all APs returned from Procedure prior to the timeout, then
318        FailedCpuList is set to NULL. If not all APs return from Procedure before
319        the timeout, then FailedCpuList is filled in with the list of the failed
320        APs. The buffer is allocated by MP Service Protocol using AllocatePool().
321        It is the caller's responsibility to free the buffer with FreePool() service.
322     -# This invocation of SignalEvent() function informs the caller that invoked
323        EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed
324        the specified task or a timeout occurred. The contents of FailedCpuList
325        can be examined to determine which APs did not complete the specified task
326        prior to the timeout.
327 
328   @param[in]  This                    A pointer to the EFI_MP_SERVICES_PROTOCOL
329                                       instance.
330   @param[in]  Procedure               A pointer to the function to be run on
331                                       enabled APs of the system. See type
332                                       EFI_AP_PROCEDURE.
333   @param[in]  SingleThread            If TRUE, then all the enabled APs execute
334                                       the function specified by Procedure one by
335                                       one, in ascending order of processor handle
336                                       number.  If FALSE, then all the enabled APs
337                                       execute the function specified by Procedure
338                                       simultaneously.
339   @param[in]  WaitEvent               The event created by the caller with CreateEvent()
340                                       service.  If it is NULL, then execute in
341                                       blocking mode. BSP waits until all APs finish
342                                       or TimeoutInMicroSeconds expires.  If it's
343                                       not NULL, then execute in non-blocking mode.
344                                       BSP requests the function specified by
345                                       Procedure to be started on all the enabled
346                                       APs, and go on executing immediately. If
347                                       all return from Procedure, or TimeoutInMicroSeconds
348                                       expires, this event is signaled. The BSP
349                                       can use the CheckEvent() or WaitForEvent()
350                                       services to check the state of event.  Type
351                                       EFI_EVENT is defined in CreateEvent() in
352                                       the Unified Extensible Firmware Interface
353                                       Specification.
354   @param[in]  TimeoutInMicrosecsond   Indicates the time limit in microseconds for
355                                       APs to return from Procedure, either for
356                                       blocking or non-blocking mode. Zero means
357                                       infinity.  If the timeout expires before
358                                       all APs return from Procedure, then Procedure
359                                       on the failed APs is terminated. All enabled
360                                       APs are available for next function assigned
361                                       by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
362                                       or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
363                                       If the timeout expires in blocking mode,
364                                       BSP returns EFI_TIMEOUT.  If the timeout
365                                       expires in non-blocking mode, WaitEvent
366                                       is signaled with SignalEvent().
367   @param[in]  ProcedureArgument       The parameter passed into Procedure for
368                                       all APs.
369   @param[out] FailedCpuList           If NULL, this parameter is ignored. Otherwise,
370                                       if all APs finish successfully, then its
371                                       content is set to NULL. If not all APs
372                                       finish before timeout expires, then its
373                                       content is set to address of the buffer
374                                       holding handle numbers of the failed APs.
375                                       The buffer is allocated by MP Service Protocol,
376                                       and it's the caller's responsibility to
377                                       free the buffer with FreePool() service.
378                                       In blocking mode, it is ready for consumption
379                                       when the call returns. In non-blocking mode,
380                                       it is ready when WaitEvent is signaled.  The
381                                       list of failed CPU is terminated by
382                                       END_OF_CPU_LIST.
383 
384   @retval EFI_SUCCESS             In blocking mode, all APs have finished before
385                                   the timeout expired.
386   @retval EFI_SUCCESS             In non-blocking mode, function has been dispatched
387                                   to all enabled APs.
388   @retval EFI_UNSUPPORTED         A non-blocking mode request was made after the
389                                   UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
390                                   signaled.
391   @retval EFI_DEVICE_ERROR        Caller processor is AP.
392   @retval EFI_NOT_STARTED         No enabled APs exist in the system.
393   @retval EFI_NOT_READY           Any enabled APs are busy.
394   @retval EFI_TIMEOUT             In blocking mode, the timeout expired before
395                                   all enabled APs have finished.
396   @retval EFI_INVALID_PARAMETER   Procedure is NULL.
397 
398 **/
399 typedef
400 EFI_STATUS
401 (EFIAPI *EFI_MP_SERVICES_STARTUP_ALL_APS)(
402   IN  EFI_MP_SERVICES_PROTOCOL  *This,
403   IN  EFI_AP_PROCEDURE          Procedure,
404   IN  BOOLEAN                   SingleThread,
405   IN  EFI_EVENT                 WaitEvent               OPTIONAL,
406   IN  UINTN                     TimeoutInMicroSeconds,
407   IN  VOID                      *ProcedureArgument      OPTIONAL,
408   OUT UINTN                     **FailedCpuList         OPTIONAL
409   );
410 
411 /**
412   This service lets the caller get one enabled AP to execute a caller-provided
413   function. The caller can request the BSP to either wait for the completion
414   of the AP or just proceed with the next task by using the EFI event mechanism.
415   See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
416   execution support.  This service may only be called from the BSP.
417 
418   This function is used to dispatch one enabled AP to the function specified by
419   Procedure passing in the argument specified by ProcedureArgument.  If WaitEvent
420   is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
421   TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
422   BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
423   is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
424   then EFI_UNSUPPORTED must be returned.
425 
426   If the timeout specified by TimeoutInMicroseconds expires before the AP returns
427   from Procedure, then execution of Procedure by the AP is terminated. The AP is
428   available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
429   EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
430 
431   @param[in]  This                    A pointer to the EFI_MP_SERVICES_PROTOCOL
432                                       instance.
433   @param[in]  Procedure               A pointer to the function to be run on the
434                                       designated AP of the system. See type
435                                       EFI_AP_PROCEDURE.
436   @param[in]  ProcessorNumber         The handle number of the AP. The range is
437                                       from 0 to the total number of logical
438                                       processors minus 1. The total number of
439                                       logical processors can be retrieved by
440                                       EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
441   @param[in]  WaitEvent               The event created by the caller with CreateEvent()
442                                       service.  If it is NULL, then execute in
443                                       blocking mode. BSP waits until this AP finish
444                                       or TimeoutInMicroSeconds expires.  If it's
445                                       not NULL, then execute in non-blocking mode.
446                                       BSP requests the function specified by
447                                       Procedure to be started on this AP,
448                                       and go on executing immediately. If this AP
449                                       return from Procedure or TimeoutInMicroSeconds
450                                       expires, this event is signaled. The BSP
451                                       can use the CheckEvent() or WaitForEvent()
452                                       services to check the state of event.  Type
453                                       EFI_EVENT is defined in CreateEvent() in
454                                       the Unified Extensible Firmware Interface
455                                       Specification.
456   @param[in]  TimeoutInMicrosecsond   Indicates the time limit in microseconds for
457                                       this AP to finish this Procedure, either for
458                                       blocking or non-blocking mode. Zero means
459                                       infinity.  If the timeout expires before
460                                       this AP returns from Procedure, then Procedure
461                                       on the AP is terminated. The
462                                       AP is available for next function assigned
463                                       by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
464                                       or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
465                                       If the timeout expires in blocking mode,
466                                       BSP returns EFI_TIMEOUT.  If the timeout
467                                       expires in non-blocking mode, WaitEvent
468                                       is signaled with SignalEvent().
469   @param[in]  ProcedureArgument       The parameter passed into Procedure on the
470                                       specified AP.
471   @param[out] Finished                If NULL, this parameter is ignored.  In
472                                       blocking mode, this parameter is ignored.
473                                       In non-blocking mode, if AP returns from
474                                       Procedure before the timeout expires, its
475                                       content is set to TRUE. Otherwise, the
476                                       value is set to FALSE. The caller can
477                                       determine if the AP returned from Procedure
478                                       by evaluating this value.
479 
480   @retval EFI_SUCCESS             In blocking mode, specified AP finished before
481                                   the timeout expires.
482   @retval EFI_SUCCESS             In non-blocking mode, the function has been
483                                   dispatched to specified AP.
484   @retval EFI_UNSUPPORTED         A non-blocking mode request was made after the
485                                   UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
486                                   signaled.
487   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
488   @retval EFI_TIMEOUT             In blocking mode, the timeout expired before
489                                   the specified AP has finished.
490   @retval EFI_NOT_READY           The specified AP is busy.
491   @retval EFI_NOT_FOUND           The processor with the handle specified by
492                                   ProcessorNumber does not exist.
493   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP or disabled AP.
494   @retval EFI_INVALID_PARAMETER   Procedure is NULL.
495 
496 **/
497 typedef
498 EFI_STATUS
499 (EFIAPI *EFI_MP_SERVICES_STARTUP_THIS_AP)(
500   IN  EFI_MP_SERVICES_PROTOCOL  *This,
501   IN  EFI_AP_PROCEDURE          Procedure,
502   IN  UINTN                     ProcessorNumber,
503   IN  EFI_EVENT                 WaitEvent               OPTIONAL,
504   IN  UINTN                     TimeoutInMicroseconds,
505   IN  VOID                      *ProcedureArgument      OPTIONAL,
506   OUT BOOLEAN                   *Finished               OPTIONAL
507   );
508 
509 /**
510   This service switches the requested AP to be the BSP from that point onward.
511   This service changes the BSP for all purposes.   This call can only be performed
512   by the current BSP.
513 
514   This service switches the requested AP to be the BSP from that point onward.
515   This service changes the BSP for all purposes. The new BSP can take over the
516   execution of the old BSP and continue seamlessly from where the old one left
517   off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
518   is signaled.
519 
520   If the BSP cannot be switched prior to the return from this service, then
521   EFI_UNSUPPORTED must be returned.
522 
523   @param[in] This              A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
524   @param[in] ProcessorNumber   The handle number of AP that is to become the new
525                                BSP. The range is from 0 to the total number of
526                                logical processors minus 1. The total number of
527                                logical processors can be retrieved by
528                                EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
529   @param[in] EnableOldBSP      If TRUE, then the old BSP will be listed as an
530                                enabled AP. Otherwise, it will be disabled.
531 
532   @retval EFI_SUCCESS             BSP successfully switched.
533   @retval EFI_UNSUPPORTED         Switching the BSP cannot be completed prior to
534                                   this service returning.
535   @retval EFI_UNSUPPORTED         Switching the BSP is not supported.
536   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
537   @retval EFI_NOT_FOUND           The processor with the handle specified by
538                                   ProcessorNumber does not exist.
539   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the current BSP or
540                                   a disabled AP.
541   @retval EFI_NOT_READY           The specified AP is busy.
542 
543 **/
544 typedef
545 EFI_STATUS
546 (EFIAPI *EFI_MP_SERVICES_SWITCH_BSP)(
547   IN EFI_MP_SERVICES_PROTOCOL  *This,
548   IN  UINTN                    ProcessorNumber,
549   IN  BOOLEAN                  EnableOldBSP
550   );
551 
552 /**
553   This service lets the caller enable or disable an AP from this point onward.
554   This service may only be called from the BSP.
555 
556   This service allows the caller enable or disable an AP from this point onward.
557   The caller can optionally specify the health status of the AP by Health. If
558   an AP is being disabled, then the state of the disabled AP is implementation
559   dependent. If an AP is enabled, then the implementation must guarantee that a
560   complete initialization sequence is performed on the AP, so the AP is in a state
561   that is compatible with an MP operating system. This service may not be supported
562   after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.
563 
564   If the enable or disable AP operation cannot be completed prior to the return
565   from this service, then EFI_UNSUPPORTED must be returned.
566 
567   @param[in] This              A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
568   @param[in] ProcessorNumber   The handle number of AP.
569                                The range is from 0 to the total number of
570                                logical processors minus 1. The total number of
571                                logical processors can be retrieved by
572                                EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
573   @param[in] EnableAP          Specifies the new state for the processor for
574                                enabled, FALSE for disabled.
575   @param[in] HealthFlag        If not NULL, a pointer to a value that specifies
576                                the new health status of the AP. This flag
577                                corresponds to StatusFlag defined in
578                                EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
579                                the PROCESSOR_HEALTH_STATUS_BIT is used. All other
580                                bits are ignored.  If it is NULL, this parameter
581                                is ignored.
582 
583   @retval EFI_SUCCESS             The specified AP was enabled or disabled successfully.
584   @retval EFI_UNSUPPORTED         Enabling or disabling an AP cannot be completed
585                                   prior to this service returning.
586   @retval EFI_UNSUPPORTED         Enabling or disabling an AP is not supported.
587   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
588   @retval EFI_NOT_FOUND           Processor with the handle specified by ProcessorNumber
589                                   does not exist.
590   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP.
591 
592 **/
593 typedef
594 EFI_STATUS
595 (EFIAPI *EFI_MP_SERVICES_ENABLEDISABLEAP)(
596   IN  EFI_MP_SERVICES_PROTOCOL  *This,
597   IN  UINTN                     ProcessorNumber,
598   IN  BOOLEAN                   EnableAP,
599   IN  UINT32                    *HealthFlag OPTIONAL
600   );
601 
602 /**
603   This return the handle number for the calling processor.  This service may be
604   called from the BSP and APs.
605 
606   This service returns the processor handle number for the calling processor.
607   The returned value is in the range from 0 to the total number of logical
608   processors minus 1. The total number of logical processors can be retrieved
609   with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
610   called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
611   is returned. Otherwise, the current processors handle number is returned in
612   ProcessorNumber, and EFI_SUCCESS is returned.
613 
614   @param[in] This              A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
615   @param[in] ProcessorNumber   Pointer to the handle number of AP.
616                                The range is from 0 to the total number of
617                                logical processors minus 1. The total number of
618                                logical processors can be retrieved by
619                                EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
620 
621   @retval EFI_SUCCESS             The current processor handle number was returned
622                                   in ProcessorNumber.
623   @retval EFI_INVALID_PARAMETER   ProcessorNumber is NULL.
624 
625 **/
626 typedef
627 EFI_STATUS
628 (EFIAPI *EFI_MP_SERVICES_WHOAMI)(
629   IN EFI_MP_SERVICES_PROTOCOL  *This,
630   OUT UINTN                    *ProcessorNumber
631   );
632 
633 ///
634 /// When installed, the MP Services Protocol produces a collection of services
635 /// that are needed for MP management.
636 ///
637 /// Before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the module
638 /// that produces this protocol is required to place all APs into an idle state
639 /// whenever the APs are disabled or the APs are not executing code as requested
640 /// through the StartupAllAPs() or StartupThisAP() services. The idle state of
641 /// an AP before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled is
642 /// implementation dependent.
643 ///
644 /// After the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, all the APs
645 /// must be placed in the OS compatible CPU state as defined by the UEFI
646 /// Specification. Implementations of this protocol may use the UEFI event
647 /// EFI_EVENT_GROUP_READY_TO_BOOT to force APs into the OS compatible state as
648 /// defined by the UEFI Specification. Modules that use this protocol must
649 /// guarantee that all non-blocking mode requests on all APs have been completed
650 /// before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. Since the
651 /// order that event notification functions in the same event group are executed
652 /// is not deterministic, an event of type EFI_EVENT_GROUP_READY_TO_BOOT cannot
653 /// be used to guarantee that APs have completed their non-blocking mode requests.
654 ///
655 /// When the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the StartAllAPs()
656 /// and StartupThisAp() services must no longer support non-blocking mode requests.
657 /// The support for SwitchBSP() and EnableDisableAP() may no longer be supported
658 /// after this event is signaled. Since UEFI Applications and UEFI OS Loaders
659 /// execute after the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, these
660 /// UEFI images must be aware that the functionality of this protocol may be reduced.
661 ///
662 struct _EFI_MP_SERVICES_PROTOCOL {
663   EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS    GetNumberOfProcessors;
664   EFI_MP_SERVICES_GET_PROCESSOR_INFO          GetProcessorInfo;
665   EFI_MP_SERVICES_STARTUP_ALL_APS             StartupAllAPs;
666   EFI_MP_SERVICES_STARTUP_THIS_AP             StartupThisAP;
667   EFI_MP_SERVICES_SWITCH_BSP                  SwitchBSP;
668   EFI_MP_SERVICES_ENABLEDISABLEAP             EnableDisableAP;
669   EFI_MP_SERVICES_WHOAMI                      WhoAmI;
670 };
671 
672 extern EFI_GUID  gEfiMpServiceProtocolGuid;
673 
674 #endif
675