Home | History | Annotate | Download | only in CpuDxe
      1 /** @file
      2   CPU DXE MP support
      3 
      4   Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #ifndef _CPU_MP_H_
     16 #define _CPU_MP_H_
     17 
     18 #include <Ppi/SecPlatformInformation.h>
     19 #include <Ppi/SecPlatformInformation2.h>
     20 #include <Protocol/MpService.h>
     21 #include <Library/SynchronizationLib.h>
     22 #include <Library/HobLib.h>
     23 #include <Library/ReportStatusCodeLib.h>
     24 
     25 /**
     26   Initialize Multi-processor support.
     27 
     28 **/
     29 VOID
     30 InitializeMpSupport (
     31   VOID
     32   );
     33 
     34 typedef
     35 VOID
     36 (EFIAPI *STACKLESS_AP_ENTRY_POINT)(
     37   VOID
     38   );
     39 
     40 /**
     41   Starts the Application Processors and directs them to jump to the
     42   specified routine.
     43 
     44   The processor jumps to this code in flat mode, but the processor's
     45   stack is not initialized.
     46 
     47   @retval EFI_SUCCESS           The APs were started
     48 
     49 **/
     50 EFI_STATUS
     51 StartApsStackless (
     52   VOID
     53   );
     54 
     55 /**
     56   The AP entry point that the Startup-IPI target code will jump to.
     57 
     58   The processor jumps to this code in flat mode, but the processor's
     59   stack is not initialized.
     60 
     61 **/
     62 VOID
     63 EFIAPI
     64 AsmApEntryPoint (
     65   VOID
     66   );
     67 
     68 /**
     69   Releases the lock preventing other APs from using the shared AP
     70   stack.
     71 
     72   Once the AP has transitioned to using a new stack, it can call this
     73   function to allow another AP to proceed with using the shared stack.
     74 
     75 **/
     76 VOID
     77 EFIAPI
     78 AsmApDoneWithCommonStack (
     79   VOID
     80   );
     81 
     82 typedef enum {
     83   CpuStateIdle,
     84   CpuStateBlocked,
     85   CpuStateReady,
     86   CpuStateBusy,
     87   CpuStateFinished,
     88   CpuStateSleeping
     89 } CPU_STATE;
     90 
     91 /**
     92   Define Individual Processor Data block.
     93 
     94 **/
     95 typedef struct {
     96   EFI_PROCESSOR_INFORMATION      Info;
     97   SPIN_LOCK                      CpuDataLock;
     98   INTN                           LockSelf;
     99   volatile CPU_STATE             State;
    100 
    101   volatile EFI_AP_PROCEDURE      Procedure;
    102   volatile VOID*                 Parameter;
    103   BOOLEAN                        *Finished;
    104   INTN                           Timeout;
    105   EFI_EVENT                      WaitEvent;
    106   BOOLEAN                        TimeoutActive;
    107   EFI_EVENT                      CheckThisAPEvent;
    108   VOID                           *TopOfStack;
    109 } CPU_DATA_BLOCK;
    110 
    111 /**
    112   Define MP data block which consumes individual processor block.
    113 
    114 **/
    115 typedef struct {
    116   CPU_DATA_BLOCK              *CpuDatas;
    117   UINTN                       NumberOfProcessors;
    118   UINTN                       NumberOfEnabledProcessors;
    119 
    120   EFI_AP_PROCEDURE            Procedure;
    121   VOID                        *ProcedureArgument;
    122   UINTN                       StartCount;
    123   UINTN                       FinishCount;
    124   BOOLEAN                     SingleThread;
    125   UINTN                       **FailedList;
    126   UINTN                       FailedListIndex;
    127   INTN                        Timeout;
    128   EFI_EVENT                   WaitEvent;
    129   BOOLEAN                     TimeoutActive;
    130   EFI_EVENT                   CheckAllAPsEvent;
    131 } MP_SYSTEM_DATA;
    132 
    133 /**
    134   This function is called by all processors (both BSP and AP) once and collects MP related data.
    135 
    136   @param Bsp             TRUE if the CPU is BSP
    137   @param ProcessorNumber The specific processor number
    138 
    139   @retval EFI_SUCCESS    Data for the processor collected and filled in
    140 
    141 **/
    142 EFI_STATUS
    143 FillInProcessorInformation (
    144   IN     BOOLEAN              Bsp,
    145   IN     UINTN                ProcessorNumber
    146   );
    147 
    148 /**
    149   This service retrieves the number of logical processor in the platform
    150   and the number of those logical processors that are enabled on this boot.
    151   This service may only be called from the BSP.
    152 
    153   This function is used to retrieve the following information:
    154     - The number of logical processors that are present in the system.
    155     - The number of enabled logical processors in the system at the instant
    156       this call is made.
    157 
    158   Because MP Service Protocol provides services to enable and disable processors
    159   dynamically, the number of enabled logical processors may vary during the
    160   course of a boot session.
    161 
    162   If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
    163   If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
    164   EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
    165   is returned in NumberOfProcessors, the number of currently enabled processor
    166   is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
    167 
    168   @param[in]  This                        A pointer to the EFI_MP_SERVICES_PROTOCOL
    169                                           instance.
    170   @param[out] NumberOfProcessors          Pointer to the total number of logical
    171                                           processors in the system, including the BSP
    172                                           and disabled APs.
    173   @param[out] NumberOfEnabledProcessors   Pointer to the number of enabled logical
    174                                           processors that exist in system, including
    175                                           the BSP.
    176 
    177   @retval EFI_SUCCESS             The number of logical processors and enabled
    178                                   logical processors was retrieved.
    179   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
    180   @retval EFI_INVALID_PARAMETER   NumberOfProcessors is NULL.
    181   @retval EFI_INVALID_PARAMETER   NumberOfEnabledProcessors is NULL.
    182 
    183 **/
    184 EFI_STATUS
    185 EFIAPI
    186 GetNumberOfProcessors (
    187   IN  EFI_MP_SERVICES_PROTOCOL  *This,
    188   OUT UINTN                     *NumberOfProcessors,
    189   OUT UINTN                     *NumberOfEnabledProcessors
    190   );
    191 
    192 /**
    193   Gets detailed MP-related information on the requested processor at the
    194   instant this call is made. This service may only be called from the BSP.
    195 
    196   This service retrieves detailed MP-related information about any processor
    197   on the platform. Note the following:
    198     - The processor information may change during the course of a boot session.
    199     - The information presented here is entirely MP related.
    200 
    201   Information regarding the number of caches and their sizes, frequency of operation,
    202   slot numbers is all considered platform-related information and is not provided
    203   by this service.
    204 
    205   @param[in]  This                  A pointer to the EFI_MP_SERVICES_PROTOCOL
    206                                     instance.
    207   @param[in]  ProcessorNumber       The handle number of processor.
    208   @param[out] ProcessorInfoBuffer   A pointer to the buffer where information for
    209                                     the requested processor is deposited.
    210 
    211   @retval EFI_SUCCESS             Processor information was returned.
    212   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
    213   @retval EFI_INVALID_PARAMETER   ProcessorInfoBuffer is NULL.
    214   @retval EFI_NOT_FOUND           The processor with the handle specified by
    215                                   ProcessorNumber does not exist in the platform.
    216 
    217 **/
    218 EFI_STATUS
    219 EFIAPI
    220 GetProcessorInfo (
    221   IN  EFI_MP_SERVICES_PROTOCOL   *This,
    222   IN  UINTN                      ProcessorNumber,
    223   OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer
    224   );
    225 
    226 /**
    227   This service executes a caller provided function on all enabled APs. APs can
    228   run either simultaneously or one at a time in sequence. This service supports
    229   both blocking and non-blocking requests. The non-blocking requests use EFI
    230   events so the BSP can detect when the APs have finished. This service may only
    231   be called from the BSP.
    232 
    233   This function is used to dispatch all the enabled APs to the function specified
    234   by Procedure.  If any enabled AP is busy, then EFI_NOT_READY is returned
    235   immediately and Procedure is not started on any AP.
    236 
    237   If SingleThread is TRUE, all the enabled APs execute the function specified by
    238   Procedure one by one, in ascending order of processor handle number. Otherwise,
    239   all the enabled APs execute the function specified by Procedure simultaneously.
    240 
    241   If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
    242   APs finish or TimeoutInMicroseconds expires. Otherwise, execution is in non-blocking
    243   mode, and the BSP returns from this service without waiting for APs. If a
    244   non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
    245   is signaled, then EFI_UNSUPPORTED must be returned.
    246 
    247   If the timeout specified by TimeoutInMicroseconds expires before all APs return
    248   from Procedure, then Procedure on the failed APs is terminated. All enabled APs
    249   are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
    250   and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
    251   content points to the list of processor handle numbers in which Procedure was
    252   terminated.
    253 
    254   Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
    255   to make sure that the nature of the code that is executed on the BSP and the
    256   dispatched APs is well controlled. The MP Services Protocol does not guarantee
    257   that the Procedure function is MP-safe. Hence, the tasks that can be run in
    258   parallel are limited to certain independent tasks and well-controlled exclusive
    259   code. EFI services and protocols may not be called by APs unless otherwise
    260   specified.
    261 
    262   In blocking execution mode, BSP waits until all APs finish or
    263   TimeoutInMicroseconds expires.
    264 
    265   In non-blocking execution mode, BSP is freed to return to the caller and then
    266   proceed to the next task without having to wait for APs. The following
    267   sequence needs to occur in a non-blocking execution mode:
    268 
    269     -# The caller that intends to use this MP Services Protocol in non-blocking
    270        mode creates WaitEvent by calling the EFI CreateEvent() service.  The caller
    271        invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent
    272        is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests
    273        the function specified by Procedure to be started on all the enabled APs,
    274        and releases the BSP to continue with other tasks.
    275     -# The caller can use the CheckEvent() and WaitForEvent() services to check
    276        the state of the WaitEvent created in step 1.
    277     -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP
    278        Service signals WaitEvent by calling the EFI SignalEvent() function. If
    279        FailedCpuList is not NULL, its content is available when WaitEvent is
    280        signaled. If all APs returned from Procedure prior to the timeout, then
    281        FailedCpuList is set to NULL. If not all APs return from Procedure before
    282        the timeout, then FailedCpuList is filled in with the list of the failed
    283        APs. The buffer is allocated by MP Service Protocol using AllocatePool().
    284        It is the caller's responsibility to free the buffer with FreePool() service.
    285     -# This invocation of SignalEvent() function informs the caller that invoked
    286        EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed
    287        the specified task or a timeout occurred. The contents of FailedCpuList
    288        can be examined to determine which APs did not complete the specified task
    289        prior to the timeout.
    290 
    291   @param[in]  This                    A pointer to the EFI_MP_SERVICES_PROTOCOL
    292                                       instance.
    293   @param[in]  Procedure               A pointer to the function to be run on
    294                                       enabled APs of the system. See type
    295                                       EFI_AP_PROCEDURE.
    296   @param[in]  SingleThread            If TRUE, then all the enabled APs execute
    297                                       the function specified by Procedure one by
    298                                       one, in ascending order of processor handle
    299                                       number.  If FALSE, then all the enabled APs
    300                                       execute the function specified by Procedure
    301                                       simultaneously.
    302   @param[in]  WaitEvent               The event created by the caller with CreateEvent()
    303                                       service.  If it is NULL, then execute in
    304                                       blocking mode. BSP waits until all APs finish
    305                                       or TimeoutInMicroseconds expires.  If it's
    306                                       not NULL, then execute in non-blocking mode.
    307                                       BSP requests the function specified by
    308                                       Procedure to be started on all the enabled
    309                                       APs, and go on executing immediately. If
    310                                       all return from Procedure, or TimeoutInMicroseconds
    311                                       expires, this event is signaled. The BSP
    312                                       can use the CheckEvent() or WaitForEvent()
    313                                       services to check the state of event.  Type
    314                                       EFI_EVENT is defined in CreateEvent() in
    315                                       the Unified Extensible Firmware Interface
    316                                       Specification.
    317   @param[in]  TimeoutInMicroseconds   Indicates the time limit in microseconds for
    318                                       APs to return from Procedure, either for
    319                                       blocking or non-blocking mode. Zero means
    320                                       infinity.  If the timeout expires before
    321                                       all APs return from Procedure, then Procedure
    322                                       on the failed APs is terminated. All enabled
    323                                       APs are available for next function assigned
    324                                       by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
    325                                       or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
    326                                       If the timeout expires in blocking mode,
    327                                       BSP returns EFI_TIMEOUT.  If the timeout
    328                                       expires in non-blocking mode, WaitEvent
    329                                       is signaled with SignalEvent().
    330   @param[in]  ProcedureArgument       The parameter passed into Procedure for
    331                                       all APs.
    332   @param[out] FailedCpuList           If NULL, this parameter is ignored. Otherwise,
    333                                       if all APs finish successfully, then its
    334                                       content is set to NULL. If not all APs
    335                                       finish before timeout expires, then its
    336                                       content is set to address of the buffer
    337                                       holding handle numbers of the failed APs.
    338                                       The buffer is allocated by MP Service Protocol,
    339                                       and it's the caller's responsibility to
    340                                       free the buffer with FreePool() service.
    341                                       In blocking mode, it is ready for consumption
    342                                       when the call returns. In non-blocking mode,
    343                                       it is ready when WaitEvent is signaled.  The
    344                                       list of failed CPU is terminated by
    345                                       END_OF_CPU_LIST.
    346 
    347   @retval EFI_SUCCESS             In blocking mode, all APs have finished before
    348                                   the timeout expired.
    349   @retval EFI_SUCCESS             In non-blocking mode, function has been dispatched
    350                                   to all enabled APs.
    351   @retval EFI_UNSUPPORTED         A non-blocking mode request was made after the
    352                                   UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
    353                                   signaled.
    354   @retval EFI_DEVICE_ERROR        Caller processor is AP.
    355   @retval EFI_NOT_STARTED         No enabled APs exist in the system.
    356   @retval EFI_NOT_READY           Any enabled APs are busy.
    357   @retval EFI_TIMEOUT             In blocking mode, the timeout expired before
    358                                   all enabled APs have finished.
    359   @retval EFI_INVALID_PARAMETER   Procedure is NULL.
    360 
    361 **/
    362 EFI_STATUS
    363 EFIAPI
    364 StartupAllAPs (
    365   IN  EFI_MP_SERVICES_PROTOCOL  *This,
    366   IN  EFI_AP_PROCEDURE          Procedure,
    367   IN  BOOLEAN                   SingleThread,
    368   IN  EFI_EVENT                 WaitEvent               OPTIONAL,
    369   IN  UINTN                     TimeoutInMicroseconds,
    370   IN  VOID                      *ProcedureArgument      OPTIONAL,
    371   OUT UINTN                     **FailedCpuList         OPTIONAL
    372   );
    373 
    374 /**
    375   This service lets the caller get one enabled AP to execute a caller-provided
    376   function. The caller can request the BSP to either wait for the completion
    377   of the AP or just proceed with the next task by using the EFI event mechanism.
    378   See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
    379   execution support.  This service may only be called from the BSP.
    380 
    381   This function is used to dispatch one enabled AP to the function specified by
    382   Procedure passing in the argument specified by ProcedureArgument.  If WaitEvent
    383   is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
    384   TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
    385   BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
    386   is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
    387   then EFI_UNSUPPORTED must be returned.
    388 
    389   If the timeout specified by TimeoutInMicroseconds expires before the AP returns
    390   from Procedure, then execution of Procedure by the AP is terminated. The AP is
    391   available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
    392   EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
    393 
    394   @param[in]  This                    A pointer to the EFI_MP_SERVICES_PROTOCOL
    395                                       instance.
    396   @param[in]  Procedure               A pointer to the function to be run on
    397                                       enabled APs of the system. See type
    398                                       EFI_AP_PROCEDURE.
    399   @param[in]  ProcessorNumber         The handle number of the AP. The range is
    400                                       from 0 to the total number of logical
    401                                       processors minus 1. The total number of
    402                                       logical processors can be retrieved by
    403                                       EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
    404   @param[in]  WaitEvent               The event created by the caller with CreateEvent()
    405                                       service.  If it is NULL, then execute in
    406                                       blocking mode. BSP waits until all APs finish
    407                                       or TimeoutInMicroseconds expires.  If it's
    408                                       not NULL, then execute in non-blocking mode.
    409                                       BSP requests the function specified by
    410                                       Procedure to be started on all the enabled
    411                                       APs, and go on executing immediately. If
    412                                       all return from Procedure or TimeoutInMicroseconds
    413                                       expires, this event is signaled. The BSP
    414                                       can use the CheckEvent() or WaitForEvent()
    415                                       services to check the state of event.  Type
    416                                       EFI_EVENT is defined in CreateEvent() in
    417                                       the Unified Extensible Firmware Interface
    418                                       Specification.
    419   @param[in]  TimeoutInMicroseconds   Indicates the time limit in microseconds for
    420                                       APs to return from Procedure, either for
    421                                       blocking or non-blocking mode. Zero means
    422                                       infinity.  If the timeout expires before
    423                                       all APs return from Procedure, then Procedure
    424                                       on the failed APs is terminated. All enabled
    425                                       APs are available for next function assigned
    426                                       by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
    427                                       or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
    428                                       If the timeout expires in blocking mode,
    429                                       BSP returns EFI_TIMEOUT.  If the timeout
    430                                       expires in non-blocking mode, WaitEvent
    431                                       is signaled with SignalEvent().
    432   @param[in]  ProcedureArgument       The parameter passed into Procedure for
    433                                       all APs.
    434   @param[out] Finished                If NULL, this parameter is ignored.  In
    435                                       blocking mode, this parameter is ignored.
    436                                       In non-blocking mode, if AP returns from
    437                                       Procedure before the timeout expires, its
    438                                       content is set to TRUE. Otherwise, the
    439                                       value is set to FALSE. The caller can
    440                                       determine if the AP returned from Procedure
    441                                       by evaluating this value.
    442 
    443   @retval EFI_SUCCESS             In blocking mode, specified AP finished before
    444                                   the timeout expires.
    445   @retval EFI_SUCCESS             In non-blocking mode, the function has been
    446                                   dispatched to specified AP.
    447   @retval EFI_UNSUPPORTED         A non-blocking mode request was made after the
    448                                   UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
    449                                   signaled.
    450   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
    451   @retval EFI_TIMEOUT             In blocking mode, the timeout expired before
    452                                   the specified AP has finished.
    453   @retval EFI_NOT_READY           The specified AP is busy.
    454   @retval EFI_NOT_FOUND           The processor with the handle specified by
    455                                   ProcessorNumber does not exist.
    456   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP or disabled AP.
    457   @retval EFI_INVALID_PARAMETER   Procedure is NULL.
    458 
    459 **/
    460 EFI_STATUS
    461 EFIAPI
    462 StartupThisAP (
    463   IN  EFI_MP_SERVICES_PROTOCOL  *This,
    464   IN  EFI_AP_PROCEDURE          Procedure,
    465   IN  UINTN                     ProcessorNumber,
    466   IN  EFI_EVENT                 WaitEvent               OPTIONAL,
    467   IN  UINTN                     TimeoutInMicroseconds,
    468   IN  VOID                      *ProcedureArgument      OPTIONAL,
    469   OUT BOOLEAN                   *Finished               OPTIONAL
    470   );
    471 
    472 /**
    473   This service switches the requested AP to be the BSP from that point onward.
    474   This service changes the BSP for all purposes.   This call can only be performed
    475   by the current BSP.
    476 
    477   This service switches the requested AP to be the BSP from that point onward.
    478   This service changes the BSP for all purposes. The new BSP can take over the
    479   execution of the old BSP and continue seamlessly from where the old one left
    480   off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
    481   is signaled.
    482 
    483   If the BSP cannot be switched prior to the return from this service, then
    484   EFI_UNSUPPORTED must be returned.
    485 
    486   @param[in] This              A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
    487   @param[in] ProcessorNumber   The handle number of AP that is to become the new
    488                                BSP. The range is from 0 to the total number of
    489                                logical processors minus 1. The total number of
    490                                logical processors can be retrieved by
    491                                EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
    492   @param[in] EnableOldBSP      If TRUE, then the old BSP will be listed as an
    493                                enabled AP. Otherwise, it will be disabled.
    494 
    495   @retval EFI_SUCCESS             BSP successfully switched.
    496   @retval EFI_UNSUPPORTED         Switching the BSP cannot be completed prior to
    497                                   this service returning.
    498   @retval EFI_UNSUPPORTED         Switching the BSP is not supported.
    499   @retval EFI_SUCCESS             The calling processor is an AP.
    500   @retval EFI_NOT_FOUND           The processor with the handle specified by
    501                                   ProcessorNumber does not exist.
    502   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the current BSP or
    503                                   a disabled AP.
    504   @retval EFI_NOT_READY           The specified AP is busy.
    505 
    506 **/
    507 EFI_STATUS
    508 EFIAPI
    509 SwitchBSP (
    510   IN EFI_MP_SERVICES_PROTOCOL  *This,
    511   IN  UINTN                    ProcessorNumber,
    512   IN  BOOLEAN                  EnableOldBSP
    513   );
    514 
    515 /**
    516   This service lets the caller enable or disable an AP from this point onward.
    517   This service may only be called from the BSP.
    518 
    519   This service allows the caller enable or disable an AP from this point onward.
    520   The caller can optionally specify the health status of the AP by Health. If
    521   an AP is being disabled, then the state of the disabled AP is implementation
    522   dependent. If an AP is enabled, then the implementation must guarantee that a
    523   complete initialization sequence is performed on the AP, so the AP is in a state
    524   that is compatible with an MP operating system. This service may not be supported
    525   after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.
    526 
    527   If the enable or disable AP operation cannot be completed prior to the return
    528   from this service, then EFI_UNSUPPORTED must be returned.
    529 
    530   @param[in] This              A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
    531   @param[in] ProcessorNumber   The handle number of AP that is to become the new
    532                                BSP. The range is from 0 to the total number of
    533                                logical processors minus 1. The total number of
    534                                logical processors can be retrieved by
    535                                EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
    536   @param[in] EnableAP          Specifies the new state for the processor for
    537                                enabled, FALSE for disabled.
    538   @param[in] HealthFlag        If not NULL, a pointer to a value that specifies
    539                                the new health status of the AP. This flag
    540                                corresponds to StatusFlag defined in
    541                                EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
    542                                the PROCESSOR_HEALTH_STATUS_BIT is used. All other
    543                                bits are ignored.  If it is NULL, this parameter
    544                                is ignored.
    545 
    546   @retval EFI_SUCCESS             The specified AP was enabled or disabled successfully.
    547   @retval EFI_UNSUPPORTED         Enabling or disabling an AP cannot be completed
    548                                   prior to this service returning.
    549   @retval EFI_UNSUPPORTED         Enabling or disabling an AP is not supported.
    550   @retval EFI_DEVICE_ERROR        The calling processor is an AP.
    551   @retval EFI_NOT_FOUND           Processor with the handle specified by ProcessorNumber
    552                                   does not exist.
    553   @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP.
    554 
    555 **/
    556 EFI_STATUS
    557 EFIAPI
    558 EnableDisableAP (
    559   IN  EFI_MP_SERVICES_PROTOCOL  *This,
    560   IN  UINTN                     ProcessorNumber,
    561   IN  BOOLEAN                   EnableAP,
    562   IN  UINT32                    *HealthFlag OPTIONAL
    563   );
    564 
    565 /**
    566   This return the handle number for the calling processor.  This service may be
    567   called from the BSP and APs.
    568 
    569   This service returns the processor handle number for the calling processor.
    570   The returned value is in the range from 0 to the total number of logical
    571   processors minus 1. The total number of logical processors can be retrieved
    572   with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
    573   called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
    574   is returned. Otherwise, the current processors handle number is returned in
    575   ProcessorNumber, and EFI_SUCCESS is returned.
    576 
    577   @param[in]  This             A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
    578   @param[out] ProcessorNumber  The handle number of AP that is to become the new
    579                                BSP. The range is from 0 to the total number of
    580                                logical processors minus 1. The total number of
    581                                logical processors can be retrieved by
    582                                EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
    583 
    584   @retval EFI_SUCCESS             The current processor handle number was returned
    585                                   in ProcessorNumber.
    586   @retval EFI_INVALID_PARAMETER   ProcessorNumber is NULL.
    587 
    588 **/
    589 EFI_STATUS
    590 EFIAPI
    591 WhoAmI (
    592   IN EFI_MP_SERVICES_PROTOCOL  *This,
    593   OUT UINTN                    *ProcessorNumber
    594   );
    595 
    596 /**
    597   Terminate AP's task and set it to idle state.
    598 
    599   This function terminates AP's task due to timeout by sending INIT-SIPI,
    600   and sends it to idle state.
    601 
    602   @param CpuData           the pointer to CPU_DATA_BLOCK of specified AP
    603 
    604 **/
    605 VOID
    606 ResetProcessorToIdleState (
    607   IN CPU_DATA_BLOCK  *CpuData
    608   );
    609 
    610 /**
    611   Prepares Startup Code for APs.
    612   This function prepares Startup Code for APs.
    613 
    614   @retval EFI_SUCCESS           The APs were started
    615   @retval EFI_OUT_OF_RESOURCES  Cannot allocate memory to start APs
    616 
    617 **/
    618 EFI_STATUS
    619 PrepareAPStartupCode (
    620   VOID
    621   );
    622 
    623 /**
    624   Free the code buffer of startup AP.
    625 
    626 **/
    627 VOID
    628 FreeApStartupCode (
    629   VOID
    630   );
    631 
    632 /**
    633   Resets the Application Processor and directs it to jump to the
    634   specified routine.
    635 
    636   The processor jumps to this code in flat mode, but the processor's
    637   stack is not initialized.
    638 
    639   @param ProcessorId           the AP of ProcessorId was reset
    640 **/
    641 VOID
    642 ResetApStackless (
    643   IN UINT32 ProcessorId
    644   );
    645 
    646 /**
    647   A minimal wrapper function that allows MtrrSetAllMtrrs() to be passed to
    648   EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() as Procedure.
    649 
    650   @param[in] Buffer  Pointer to an MTRR_SETTINGS object, to be passed to
    651                      MtrrSetAllMtrrs().
    652 **/
    653 VOID
    654 EFIAPI
    655 SetMtrrsFromBuffer (
    656   IN VOID *Buffer
    657   );
    658 
    659 #endif // _CPU_MP_H_
    660 
    661