Home | History | Annotate | Download | only in Protocol
      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