1 /** @file
2   When installed, the Framework MP Services Protocol produces a collection of
3   services that are needed for MP management, such as initialization and management
4   of application processors.
5 
6   @par Note:
7     This protocol has been deprecated and has been replaced by the MP Services
8     Protocol from the UEFI Platform Initialization Specification 1.2, Volume 2:
9     Driver Execution Environment Core Interface.
10 
11   The MP Services Protocol provides a generalized way of performing following tasks:
12     - Retrieving information of multi-processor environment and MP-related status of
13       specific processors.
14     - Dispatching user-provided function to APs.
15     - Maintain MP-related processor status.
16 
17   The MP Services Protocol must be produced on any system with more than one logical
18   processor.
19 
20   The Protocol is available only during boot time.
21 
22   MP Services Protocol is hardware-independent. Most of the logic of this protocol
23   is architecturally neutral. It abstracts the multi-processor environment and
24   status of processors, and provides interfaces to retrieve information, maintain,
25   and dispatch.
26 
27   MP Services Protocol may be consumed by ACPI module. The ACPI module may use this
28   protocol to retrieve data that are needed for an MP platform and report them to OS.
29   MP Services Protocol may also be used to program and configure processors, such
30   as MTRR synchronization for memory space attributes setting in DXE Services.
31   MP Services Protocol may be used by non-CPU DXE drivers to speed up platform boot
32   by taking advantage of the processing capabilities of the APs, for example, using
33   APs to help test system memory in parallel with other device initialization.
34   Diagnostics applications may also use this protocol for multi-processor.
35 
36 Copyright (c) 1999 - 2010, Intel Corporation. All rights reserved.<BR>
37 This program and the accompanying materials are licensed and made available under
38 the terms and conditions of the BSD License that accompanies this distribution.
39 The full text of the license may be found at
40 http://opensource.org/licenses/bsd-license.php.
41 
42 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
43 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
44 
45 **/
46 
47 #ifndef _FRAMEWORK_MP_SERVICE_PROTOCOL_H_
48 #define _FRAMEWORK_MP_SERVICE_PROTOCOL_H_
49 
50 #include <FrameworkDxe.h>
51 
52 ///
53 /// Global ID for the FRAMEWORK_EFI_MP_SERVICES_PROTOCOL.
54 ///
55 #define FRAMEWORK_EFI_MP_SERVICES_PROTOCOL_GUID \
56   { \
57     0xf33261e7, 0x23cb, 0x11d5, {0xbd, 0x5c, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} \
58   }
59 
60 ///
61 /// Forward declaration for the EFI_MP_SERVICES_PROTOCOL.
62 ///
63 typedef struct _FRAMEWORK_EFI_MP_SERVICES_PROTOCOL FRAMEWORK_EFI_MP_SERVICES_PROTOCOL;
64 
65 ///
66 /// Fixed delivery mode that may be used as the DeliveryMode parameter in SendIpi().
67 ///
68 #define DELIVERY_MODE_FIXED           0x0
69 
70 ///
71 /// Lowest priority delivery mode that may be used as the DeliveryMode parameter in SendIpi().
72 ///
73 #define DELIVERY_MODE_LOWEST_PRIORITY 0x1
74 
75 ///
76 /// SMI delivery mode that may be used as the DeliveryMode parameter in SendIpi().
77 ///
78 #define DELIVERY_MODE_SMI             0x2
79 
80 ///
81 /// Remote read delivery mode that may be used as the DeliveryMode parameter in SendIpi().
82 ///
83 #define DELIVERY_MODE_REMOTE_READ     0x3
84 
85 ///
86 /// NMI delivery mode that may be used as the DeliveryMode parameter in SendIpi().
87 ///
88 #define DELIVERY_MODE_NMI             0x4
89 
90 ///
91 /// INIT delivery mode that may be used as the DeliveryMode parameter in SendIpi().
92 ///
93 #define DELIVERY_MODE_INIT            0x5
94 
95 ///
96 /// Startup IPI delivery mode that may be used as the DeliveryMode parameter in SendIpi().
97 ///
98 #define DELIVERY_MODE_SIPI            0x6
99 
100 ///
101 /// The DeliveryMode parameter in SendIpi() must be less than this maximum value.
102 ///
103 #define DELIVERY_MODE_MAX             0x7
104 
105 ///
106 /// IPF specific value for the state field of the Self Test State Parameter.
107 ///
108 #define EFI_MP_HEALTH_FLAGS_STATUS_HEALTHY                  0x0
109 
110 ///
111 /// IPF specific value for the state field of the Self Test State Parameter.
112 ///
113 #define EFI_MP_HEALTH_FLAGS_STATUS_PERFORMANCE_RESTRICTED   0x1
114 
115 ///
116 /// IPF specific value for the state field of the Self Test State Parameter.
117 ///
118 #define EFI_MP_HEALTH_FLAGS_STATUS_FUNCTIONALLY_RESTRICTED  0x2
119 
120 typedef union {
121   ///
122   /// Bitfield structure for the IPF Self Test State Parameter.
123   ///
124   struct {
125     UINT32  Status:2;
126     UINT32  Tested:1;
127     UINT32  Reserved1:13;
128     UINT32  VirtualMemoryUnavailable:1;
129     UINT32  Ia32ExecutionUnavailable:1;
130     UINT32  FloatingPointUnavailable:1;
131     UINT32  MiscFeaturesUnavailable:1;
132     UINT32  Reserved2:12;
133   } Bits;
134   ///
135   /// IA32 and X64 BIST data of the processor.
136   ///
137   UINT32  Uint32;
138 } EFI_MP_HEALTH_FLAGS;
139 
140 typedef struct {
141   ///
142   /// @par IA32, X64:
143   ///   BIST (built-in self-test) data of the processor.
144   ///
145   /// @par IPF:
146   ///   Lower 32 bits of the self-test state parameter. For definition of self-test
147   ///   state parameter, please refer to Intel(R) Itanium(R) Architecture Software
148   ///   Developer's Manual, Volume 2: System Architecture.
149   ///
150   EFI_MP_HEALTH_FLAGS  Flags;
151   ///
152   /// @par IA32, X64:
153   ///   Not used.
154   ///
155   /// @par IPF:
156   ///   Higher 32 bits of self test state parameter.
157   ///
158   UINT32               TestStatus;
159 } EFI_MP_HEALTH;
160 
161 typedef enum {
162   EfiCpuAP                = 0,  ///< The CPU is an AP (Application Processor).
163   EfiCpuBSP,                    ///< The CPU is the BSP (Boot-Strap Processor).
164   EfiCpuDesignationMaximum
165 } EFI_CPU_DESIGNATION;
166 
167 typedef struct {
168   ///
169   /// @par IA32, X64:
170   ///   The lower 8 bits contains local APIC ID, and higher bits are reserved.
171   ///
172   /// @par IPF:
173   ///   The lower 16 bits contains id/eid as physical address of local SAPIC
174   ///   unit, and higher bits are reserved.
175   ///
176   UINT32               ApicID;
177   ///
178   /// This field indicates whether the processor is enabled.  If the value is
179   /// TRUE, then the processor is enabled. Otherwise, it is disabled.
180   ///
181   BOOLEAN              Enabled;
182   ///
183   /// This field indicates whether the processor is playing the role of BSP.
184   /// If the value is EfiCpuAP, then the processor is AP. If the value is
185   /// EfiCpuBSP, then the processor is BSP.
186   ///
187   EFI_CPU_DESIGNATION  Designation;
188   ///
189   /// @par IA32, X64:
190   ///   The Flags field of this EFI_MP_HEALTH data structure holds BIST (built-in
191   ///   self test) data of the processor. The TestStatus field is not used, and
192   ///   the value is always zero.
193   ///
194   /// @par IPF:
195   ///   Bit format of this field is the same as the definition of self-test state
196   ///   parameter, in Intel(R) Itanium(R) Architecture Software Developer's Manual,
197   ///   Volume 2: System Architecture.
198   ///
199   EFI_MP_HEALTH        Health;
200   ///
201   /// Zero-based physical package number that identifies the cartridge of the
202   /// processor.
203   ///
204   UINTN                PackageNumber;
205   ///
206   /// Zero-based physical core number within package of the processor.
207   ///
208   UINTN                NumberOfCores;
209   ///
210   /// Zero-based logical thread number within core of the processor.
211   ///
212   UINTN                NumberOfThreads;
213   ///
214   /// This field is reserved.
215   ///
216   UINT64               ProcessorPALCompatibilityFlags;
217   ///
218   /// @par IA32, X64:
219   ///   This field is not used, and the value is always zero.
220   ///
221   /// @par IPF:
222   ///   This field is a mask number that is handed off by the PAL about which
223   ///   processor tests are performed and which are masked.
224   ///
225   UINT64               ProcessorTestMask;
226 } EFI_MP_PROC_CONTEXT;
227 
228 /**
229   This service retrieves general information of multiprocessors in the system.
230 
231   This function is used to get the following information:
232     - Number of logical processors in system
233     - Maximal number of logical processors supported by system
234     - Number of enabled logical processors.
235     - Rendezvous interrupt number (IPF-specific)
236     - Length of the rendezvous procedure.
237 
238   @param[in]  This                   The pointer to the FRAMEWORK_EFI_MP_SERVICES_PROTOCOL
239                                      instance.
240   @param[out] NumberOfCPUs           The pointer to the total number of logical processors
241                                      in the system, including the BSP and disabled
242                                      APs.  If NULL, this parameter is ignored.
243   @param[out] MaximumNumberOfCPUs    Pointer to the maximum number of processors
244                                      supported by the system.  If NULL, this
245                                      parameter is ignored.
246   @param[out] NumberOfEnabledCPUs    The pointer to the number of enabled logical
247                                      processors that exist in system, including
248                                      the BSP.  If NULL, this parameter is ignored.
249   @param[out] RendezvousIntNumber    This parameter is only meaningful for IPF.
250                                      - IA32, X64: The returned value is zero.
251                                      If NULL, this parameter is ignored.
252                                      - IPF: Pointer to the rendezvous interrupt
253                                      number that is used for AP wake-up.
254   @param[out] RendezvousProcLength   The pointer to the length of rendezvous procedure.
255                                      - IA32, X64: The returned value is 0x1000.
256                                      If NULL, this parameter is ignored.
257                                      - IPF: The returned value is zero.
258 
259   @retval EFI_SUCCESS   Multiprocessor general information was successfully retrieved.
260 
261 **/
262 typedef
263 EFI_STATUS
264 (EFIAPI *EFI_MP_SERVICES_GET_GENERAL_MP_INFO)(
265   IN  FRAMEWORK_EFI_MP_SERVICES_PROTOCOL  *This,
266   OUT UINTN                               *NumberOfCPUs          OPTIONAL,
267   OUT UINTN                               *MaximumNumberOfCPUs   OPTIONAL,
268   OUT UINTN                               *NumberOfEnabledCPUs   OPTIONAL,
269   OUT UINTN                               *RendezvousIntNumber   OPTIONAL,
270   OUT UINTN                               *RendezvousProcLength  OPTIONAL
271   );
272 
273 /**
274   This service gets detailed MP-related information of the requested processor.
275 
276   This service gets detailed MP-related information of the requested processor
277   at the instant this call is made. Note the following:
278     - The processor information may change during the course of a boot session.
279     - The data of information presented here is entirely MP related.
280   Information regarding the number of caches and their sizes, frequency of operation,
281   slot numbers is all considered platform-related information and will not be
282   presented here.
283 
284   @param[in]  This                     The pointer to the FRAMEWORK_EFI_MP_SERVICES_PROTOCOL
285                                        instance.
286   @param[in]  ProcessorNumber          The handle number of the processor. The range
287                                        is from 0 to the total number of logical
288                                        processors minus 1. The total number of
289                                        logical processors can be retrieved by
290                                        GetGeneralMPInfo().
291   @param[in,out] BufferLength          On input, pointer to the size in bytes of
292                                        ProcessorContextBuffer.  On output, if the
293                                        size of ProcessorContextBuffer is not large
294                                        enough, the value pointed by this parameter
295                                        is updated to size in bytes that is needed.
296                                        If the size of ProcessorContextBuffer is
297                                        sufficient, the value is not changed from
298                                        input.
299   @param[out] ProcessorContextBuffer   The pointer to the buffer where the data of
300                                        requested processor will be deposited.
301                                        The buffer is allocated by caller.
302 
303   @retval EFI_SUCCESS             Processor information was successfully returned.
304   @retval EFI_BUFFER_TOO_SMALL    The size of ProcessorContextBuffer is too small.
305                                   The value pointed by BufferLength has been updated
306                                   to size in bytes that is needed.
307   @retval EFI_INVALID_PARAMETER   IA32, X64:BufferLength is NULL.
308   @retval EFI_INVALID_PARAMETER   IA32, X64:ProcessorContextBuffer is NULL.
309   @retval EFI_INVALID_PARAMETER   IA32, X64:Processor with the handle specified by
310                                   ProcessorNumber does not exist.
311   @retval EFI_NOT_FOUND           IPF: Processor with the handle specified by
312                                   ProcessorNumber does not exist.
313 
314 **/
315 typedef
316 EFI_STATUS
317 (EFIAPI *EFI_MP_SERVICES_GET_PROCESSOR_CONTEXT)(
318   IN     FRAMEWORK_EFI_MP_SERVICES_PROTOCOL  *This,
319   IN     UINTN                               ProcessorNumber,
320   IN OUT UINTN                               *BufferLength,
321   OUT    EFI_MP_PROC_CONTEXT                 *ProcessorContextBuffer
322   );
323 
324 /**
325   This function is used to dispatch all enabled APs to the function specified
326   by Procedure. APs can run either simultaneously or one by one. The caller can
327   also configure the BSP to either wait for APs or just proceed with the next
328   task.  It is the responsibility of the caller of the StartupAllAPs() to make
329   sure that the nature of the code that will be run on the BSP and the dispatched
330   APs is well controlled. The MP Services Protocol does not guarantee that the
331   function that either processor is executing is MP-safe. Hence, the tasks that
332   can be run in parallel are limited to certain independent tasks and well-
333   controlled exclusive code. EFI services and protocols may not be called by APs
334   unless otherwise specified.
335 
336   @param[in]  This                    The pointer to the FRAMEWORK_EFI_MP_SERVICES_PROTOCOL
337                                       instance.
338   @param[in]  Procedure               A pointer to the function to be run on enabled
339                                       APs of the system.
340   @param[in]  SingleThread            Flag that requests APs to execute one at a
341                                       time or simultaneously.
342                                       - IA32, X64:
343                                       If TRUE, then all the enabled APs execute
344                                       the function specified by Procedure one by
345                                       one, in ascending order of processor handle
346                                       number.  If FALSE, then all the enabled APs
347                                       execute the function specified by Procedure
348                                       simultaneously.
349                                       - IPF:
350                                       If TRUE, then all the enabled APs execute
351                                       the function specified by Procedure simultaneously.
352                                       If FALSE, then all the enabled APs execute the
353                                       function specified by Procedure one by one, in
354                                       ascending order of processor handle number. The
355                                       time interval of AP dispatching is determined
356                                       by WaitEvent and TimeoutInMicrosecs.
357   @param[in]  WaitEvent               Event to signal when APs have finished.
358                                       - IA32, X64:
359                                       If not NULL, when all APs finish after timeout
360                                       expires, the event will be signaled.  If NULL,
361                                       the parameter is ignored.
362                                       - IPF:
363                                       If SingleThread is TRUE, this parameter
364                                       is ignored.  If SingleThread is FALSE (i.e.
365                                       dispatch APs one by one), this parameter
366                                       determines whether the BSP waits after each
367                                       AP is dispatched. If it is NULL, the BSP
368                                       does not wait after each AP is dispatched.
369                                       If it is not NULL, the BSP waits after each
370                                       AP is dispatched, and the time interval is
371                                       determined by TimeoutInMicrosecs.  Type
372                                       EFI_EVENT is defined in CreateEvent() in
373                                       the Unified Extensible Firmware Interface
374                                       Specification.
375   @param[in]  TimeoutInMicrosecsond   Time to wait for APs to finish.
376                                       - IA32, X64:
377                                       If the value is zero, it means no timeout
378                                       limit. The BSP waits until all APs finish.
379                                       If the value is not zero, the BSP waits
380                                       until all APs finish or timeout expires.
381                                       If timeout expires, EFI_TIMEOUT is returned,
382                                       and the BSP will then check APs?status
383                                       periodically, with time interval of 16
384                                       microseconds.
385                                       - IPF:
386                                       If SingleThread is TRUE and FailedCPUList
387                                       is NULL, this parameter is ignored.  If
388                                       SingleThread is TRUE and FailedCPUList is
389                                       not NULL, this parameter determines whether
390                                       the BSP waits until all APs finish their
391                                       procedure. If it is zero, the BSP does not
392                                       wait for APs. If it is non-zero, it waits
393                                       until all APs finish.  If SingleThread is
394                                       FALSE and WaitEvent is NULL, this parameter
395                                       is ignored.  If SingleThread is FALSE and
396                                       WaitEvent is not NULL, the BSP waits after
397                                       each AP is dispatched and this value
398                                       determines time interval. If the value is
399                                       zero, the length of time interval is 10ms.
400                                       If the value is non-zero, the BSP waits
401                                       until dispatched AP finishes and then
402                                       dispatch the next.
403   @param[in]  ProcedureArgument       The pointer to the optional parameter of the
404                                       function specified by Procedure.
405   @param[out] FailedCPUList           List of APs that did not finish.
406                                       - IA32, X64:
407                                       If not NULL, it records handle numbers of
408                                       all logical processors that fail to accept
409                                       caller-provided function (busy or disabled).
410                                       If NULL, this parameter is ignored.
411                                       - IPF:
412                                       If not NULL, it records status of all
413                                       logical processors, with processor handle
414                                       number as index. If a logical processor
415                                       fails to accept caller-provided function
416                                       because it is busy, the status is EFI_NOT_READY.
417                                       If it fails to accept function due to other
418                                       reasons, the status is EFI_NOT_AVAILABLE_YET.
419                                       If timeout expires, the status is EFI_TIMEOUT.
420                                       Otherwise, the value is EFI_SUCCESS.  If NULL,
421                                       this parameter is ignored.
422 
423   @retval EFI_SUCCESS	            IA32, X64: All dispatched APs have finished
424                                   before the timeout expires.
425   @retval EFI_SUCCESS	            IA32, X64: Only 1 logical processor exists
426                                   in system.
427   @retval EFI_INVALID_PARAMETER	    IA32, X64: Procedure is NULL.
428   @retval EFI_TIMEOUT	            IA32, X64: The timeout expires before all
429                                   dispatched APs have finished.
430   @retval EFI_SUCCESS	            IPF: This function always returns EFI_SUCCESS.
431 
432 **/
433 typedef
434 EFI_STATUS
435 (EFIAPI *FRAMEWORK_EFI_MP_SERVICES_STARTUP_ALL_APS)(
436   IN  FRAMEWORK_EFI_MP_SERVICES_PROTOCOL  *This,
437   IN  FRAMEWORK_EFI_AP_PROCEDURE          Procedure,
438   IN  BOOLEAN                             SingleThread,
439   IN  EFI_EVENT                           WaitEvent           OPTIONAL,
440   IN  UINTN                               TimeoutInMicroSecs,
441   IN  VOID                                *ProcArguments      OPTIONAL,
442   OUT UINTN                               *FailedCPUList      OPTIONAL
443   );
444 
445 /**
446   This function is used to dispatch one enabled AP to the function provided by
447   the caller. The caller can request the BSP to either wait for the AP or just
448   proceed with the next task.
449 
450   @param[in] This                    The pointer to the FRAMEWORK_EFI_MP_SERVICES_PROTOCOL
451                                      instance.
452   @param[in] Procedure               A pointer to the function to be run on the
453                                      designated AP.
454   @param[in] ProcessorNumber         The handle number of AP. The range is from
455                                      0 to the total number of logical processors
456                                      minus 1.  The total number of logical
457                                      processors can be retrieved by GetGeneralMPInfo().
458   @param[in] WaitEvent               Event to signal when APs have finished.
459                                      - IA32, X64:
460                                      If not NULL, when the AP finishes after timeout
461                                      expires, the event will be signaled.  If NULL,
462                                      the parameter is ignored.
463                                      - IPF:
464                                      This parameter determines whether the BSP
465                                      waits after the AP is dispatched. If it is
466                                      NULL, the BSP does not wait after the AP
467                                      is dispatched. If it is not NULL, the BSP
468                                      waits after the AP is dispatched, and the
469                                      time interval is determined by TimeoutInMicrosecs.
470                                      Type EFI_EVENT is defined in CreateEvent()
471                                      in the Unified Extensible Firmware Interface
472                                      Specification.
473   @param[in] TimeoutInMicrosecsond   Time to wait for APs to finish.
474                                      - IA32, X64:
475                                      If the value is zero, it means no timeout
476                                      limit. The BSP waits until the AP finishes.
477                                      If the value is not zero, the BSP waits until
478                                      the AP finishes or timeout expires. If timeout
479                                      expires, EFI_TIMEOUT is returned, and the
480                                      BSP will then check the AP's status periodically,
481                                      with time interval of 16 microseconds.
482                                      - IPF:
483                                      If WaitEvent is NULL, this parameter is ignored.
484                                      If WaitEvent is not NULL, the BSP waits after
485                                      the AP is dispatched and this value determines
486                                      time interval. If the value is zero, the length
487                                      of time interval is 10ms. If the value is
488                                      non-zero, the BSP waits until the AP finishes.
489   @param[in] ProcedureArgument       The pointer to the optional parameter of the
490                                      function specified by Procedure.
491 
492   @retval EFI_SUCCESS             Specified AP has finished before the timeout
493                                   expires.
494   @retval EFI_TIMEOUT             The timeout expires before specified AP has
495                                   finished.
496   @retval EFI_INVALID_PARAMETER   IA32, X64: Processor with the handle specified
497                                   by ProcessorNumber does not exist.
498   @retval EFI_INVALID_PARAMETER   IA32, X64: Specified AP is busy or disabled.
499   @retval EFI_INVALID_PARAMETER   IA32, X64: Procedure is NULL.
500   @retval EFI_INVALID_PARAMETER   IA32, X64: ProcessorNumber specifies the BSP
501   @retval EFI_NOT_READY           IPF: Specified AP is busy
502   @retval EFI_NOT_AVAILABLE_YET   IPF: ProcessorNumber specifies the BSP
503   @retval EFI_NOT_AVAILABLE_YET   IPF: Specified AP is disabled.
504   @retval EFI_NOT_AVAILABLE_YET   IPF: Specified AP is unhealthy or untested.
505 
506 **/
507 typedef
508 EFI_STATUS
509 (EFIAPI *FRAMEWORK_EFI_MP_SERVICES_STARTUP_THIS_AP)(
510   IN FRAMEWORK_EFI_MP_SERVICES_PROTOCOL  *This,
511   IN FRAMEWORK_EFI_AP_PROCEDURE          Procedure,
512   IN UINTN                               ProcessorNumber,
513   IN EFI_EVENT                           WaitEvent            OPTIONAL,
514   IN UINTN                               TimeoutInMicroSecs,
515   IN OUT VOID                            *ProcArguments       OPTIONAL
516   );
517 
518 /**
519   This service switches the requested AP to be the BSP from that point onward.
520   The new BSP can take over the execution of the old BSP and continue seamlessly
521   from where the old one left off.  This call can only be performed by the
522   current BSP.
523 
524   @param[in] This              The pointer to the FRAMEWORK_EFI_MP_SERVICES_PROTOCOL
525                                instance.
526   @param[in] ProcessorNumber   The handle number of AP. The range is from 0 to
527                                the total number of logical processors minus 1.
528                                The total number of logical processors can be
529                                retrieved by GetGeneralMPInfo().
530   @param[in] EnableOldBSP      If TRUE, then the old BSP will be listed as an
531                                enabled AP. Otherwise, it will be disabled.
532 
533   @retval EFI_SUCCESS             BSP successfully switched.
534   @retval EFI_INVALID_PARAMETER   The processor with the handle specified by
535                                   ProcessorNumber does not exist.
536   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP.
537   @retval EFI_NOT_READY           IA32, X64: Specified AP is busy or disabled.
538   @retval EFI_INVALID_PARAMETER   IPF: Specified AP is disabled.
539   @retval EFI_INVALID_PARAMETER   IPF: Specified AP is unhealthy or untested.
540   @retval EFI_NOT_READY           IPF: Specified AP is busy.
541 
542 **/
543 typedef
544 EFI_STATUS
545 (EFIAPI *FRAMEWORK_EFI_MP_SERVICES_SWITCH_BSP)(
546   IN FRAMEWORK_EFI_MP_SERVICES_PROTOCOL  *This,
547   IN UINTN                               ProcessorNumber,
548   IN BOOLEAN                             EnableOldBSP
549   );
550 
551 /**
552   This service sends an IPI to a specified AP. Caller can specify vector number
553   and delivery mode of the interrupt.
554 
555   @param[in] This              The pointer to the FRAMEWORK_EFI_MP_SERVICES_PROTOCOL
556                                instance.
557   @param[in] ProcessorNumber   The handle number of AP. The range is from 0 to
558                                the total number of logical processors minus 1.
559                                The total number of logical processors can be
560                                retrieved by GetGeneralMPInfo().
561   @param[in] VectorNumber      The vector number of the interrupt.
562   @param[in] DeliveryMode      The delivery mode of the interrupt.
563 
564   @retval EFI_SUCCESS             IPI was successfully sent.
565   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP.
566   @retval EFI_INVALID_PARAMETER   IA32, X64: Processor with the handle specified
567                                   by ProcessorNumber does not exist.
568   @retval EFI_INVALID_PARAMETER   IA32, X64: VectorNumber is greater than 255.
569   @retval EFI_INVALID_PARAMETER   IA32, X64: DeliveryMode is greater than or equal
570                                   to DELIVERY_MODE_MAX.
571   @retval EFI_NOT_READY           IA32, X64: IPI is not accepted by the target
572                                   processor within 10 microseconds.
573   @retval EFI_INVALID_PARAMETER   IPF: Specified AP is disabled.
574   @retval EFI_INVALID_PARAMETER   IPF: Specified AP is unhealthy or untested.
575   @retval EFI_NOT_READY           IPF: Specified AP is busy.
576 
577 **/
578 typedef
579 EFI_STATUS
580 (EFIAPI *EFI_MP_SERVICES_SEND_IPI)(
581   IN FRAMEWORK_EFI_MP_SERVICES_PROTOCOL  *This,
582   IN UINTN                               ProcessorNumber,
583   IN UINTN                               VectorNumber,
584   IN UINTN                               DeliveryMode
585   );
586 
587 /**
588   This service lets the caller enable or disable an AP.  The caller can optionally
589   specify the health status of the AP by Health. It is usually used to update the
590   health status of the processor after some processor test.
591 
592   @param[in] This              The pointer to the FRAMEWORK_EFI_MP_SERVICES_PROTOCOL
593                                instance.
594   @param[in] ProcessorNumber   The handle number of AP. The range is from 0 to
595                                the total number of logical processors minus 1.
596                                The total number of logical processors can be
597                                retrieved by GetGeneralMPInfo().
598   @param[in] NewAPState        Indicates whether the new, desired state of the
599                                AP is enabled or disabled. TRUE for enabling,
600                                FALSE otherwise.
601   @param[in] HealthState       If not NULL, it points to the value that specifies
602                                the new health status of the AP.  If it is NULL,
603                                this parameter is ignored.
604 
605   @retval EFI_SUCCESS             AP successfully enabled or disabled.
606   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP.
607   @retval EFI_INVALID_PARAMETER   IA32, X64: Processor with the handle specified
608                                   by ProcessorNumber does not exist.
609   @retval EFI_INVALID_PARAMETER   IPF: If an unhealthy or untested AP is to be
610                                   enabled.
611 
612 **/
613 typedef
614 EFI_STATUS
615 (EFIAPI *FRAMEWORK_EFI_MP_SERVICES_ENABLEDISABLEAP)(
616   IN FRAMEWORK_EFI_MP_SERVICES_PROTOCOL  *This,
617   IN UINTN                               ProcessorNumber,
618   IN BOOLEAN                             NewAPState,
619   IN EFI_MP_HEALTH                       *HealthState  OPTIONAL
620   );
621 
622 /**
623   This service lets the caller processor get its handle number, with which any
624   processor in the system can be uniquely identified. The range is from 0 to the
625   total number of logical processors minus 1. The total number of logical
626   processors can be retrieved by GetGeneralMPInfo(). This service may be called
627   from the BSP and APs.
628 
629   @param[in]  This              The pointer to the FRAMEWORK_EFI_MP_SERVICES_PROTOCOL
630                                 instance.
631   @param[out] ProcessorNumber   A pointer to the handle number of AP. The range is
632                                 from 0 to the total number of logical processors
633                                 minus 1. The total number of logical processors
634                                 can be retrieved by GetGeneralMPInfo().
635 
636 @retval EFI_SUCCESS   This function always returns EFI_SUCCESS.
637 
638 **/
639 typedef
640 EFI_STATUS
641 (EFIAPI *FRAMEWORK_EFI_MP_SERVICES_WHOAMI)(
642   IN  FRAMEWORK_EFI_MP_SERVICES_PROTOCOL  *This,
643   OUT UINTN                               *ProcessorNumber
644   );
645 
646 ///
647 /// Framework MP Services Protocol structure.
648 ///
649 struct _FRAMEWORK_EFI_MP_SERVICES_PROTOCOL {
650   EFI_MP_SERVICES_GET_GENERAL_MP_INFO              GetGeneralMPInfo;
651   EFI_MP_SERVICES_GET_PROCESSOR_CONTEXT            GetProcessorContext;
652   FRAMEWORK_EFI_MP_SERVICES_STARTUP_ALL_APS        StartupAllAPs;
653   FRAMEWORK_EFI_MP_SERVICES_STARTUP_THIS_AP        StartupThisAP;
654   FRAMEWORK_EFI_MP_SERVICES_SWITCH_BSP             SwitchBSP;
655   EFI_MP_SERVICES_SEND_IPI                         SendIPI;
656   FRAMEWORK_EFI_MP_SERVICES_ENABLEDISABLEAP        EnableDisableAP;
657   FRAMEWORK_EFI_MP_SERVICES_WHOAMI                 WhoAmI;
658 };
659 
660 extern EFI_GUID gFrameworkEfiMpServiceProtocolGuid;
661 
662 #endif
663