Home | History | Annotate | Download | only in MpServicesOnFrameworkMpServicesThunk
      1 /** @file
      2 Include file for PI MP Services Protocol Thunk.
      3 
      4 Copyright (c) 2009 - 2010, 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 Module Name:
     13 
     14 **/
     15 
     16 #ifndef _MP_SERVICES_ON_FRAMEWORK_MP_SERVICES_THUNK_
     17 #define _MP_SERVICES_ON_FRAMEWORK_MP_SERVICES_THUNK_
     18 
     19 #include <Protocol/MpService.h>
     20 #include <Protocol/FrameworkMpService.h>
     21 #include <Protocol/GenericMemoryTest.h>
     22 
     23 #include <Library/BaseLib.h>
     24 #include <Library/SynchronizationLib.h>
     25 #include <Library/DebugLib.h>
     26 #include <Library/UefiLib.h>
     27 #include <Library/BaseMemoryLib.h>
     28 #include <Library/UefiDriverEntryPoint.h>
     29 #include <Library/MemoryAllocationLib.h>
     30 #include <Library/UefiBootServicesTableLib.h>
     31 #include <Library/DxeServicesTableLib.h>
     32 #include <Library/IoLib.h>
     33 #include <Library/TimerLib.h>
     34 #include <Library/DebugAgentLib.h>
     35 #include <Library/LocalApicLib.h>
     36 
     37 #define AP_STACK_SIZE                         0x8000
     38 #define MAX_CPU_NUMBER                        256
     39 
     40 //
     41 // Bit definition for IPI
     42 //
     43 #define BROADCAST_MODE_ALL_EXCLUDING_SELF_BIT  0xC0000
     44 #define SPECIFY_CPU_MODE_BIT                   0x00000
     45 #define TRIGGER_MODE_LEVEL_BIT                 0x08000
     46 #define ASSERT_BIT                             0x04000
     47 
     48 //
     49 // Local APIC register definition for IPI.
     50 //
     51 #define APIC_REGISTER_SPURIOUS_VECTOR_OFFSET  0xF0
     52 #define APIC_REGISTER_ICR_LOW_OFFSET          0x300
     53 #define APIC_REGISTER_ICR_HIGH_OFFSET         0x310
     54 #define APIC_REGISTER_LVT_TIMER               0x320
     55 #define APIC_REGISTER_TIMER_INIT_COUNT        0x380
     56 #define APIC_REGISTER_LINT0_VECTOR_OFFSET     0x350
     57 #define APIC_REGISTER_LINT1_VECTOR_OFFSET     0x360
     58 #define APIC_REGISTER_TIMER_COUNT             0x390
     59 #define APIC_REGISTER_TIMER_DIVIDE            0x3E0
     60 
     61 //
     62 // Definition for MSR address
     63 //
     64 #define MSR_IA32_TIME_STAMP_COUNTER           0x10
     65 #define MSR_IA32_APIC_BASE                    0x1B
     66 
     67 typedef struct {
     68   UINTN             Lock;
     69   VOID              *StackStart;
     70   UINTN             StackSize;
     71   VOID              *ApFunction;
     72   IA32_DESCRIPTOR   GdtrProfile;
     73   IA32_DESCRIPTOR   IdtrProfile;
     74   UINT32            BufferStart;
     75   UINT32            Cr3;
     76   UINT32            ProcessorNumber[MAX_CPU_NUMBER];
     77 } MP_CPU_EXCHANGE_INFO;
     78 
     79 typedef struct {
     80   UINT8 *RendezvousFunnelAddress;
     81   UINTN PModeEntryOffset;
     82   UINTN FlatJumpOffset;
     83   UINTN LModeEntryOffset;
     84   UINTN LongJumpOffset;
     85   UINTN Size;
     86 } MP_ASSEMBLY_ADDRESS_MAP;
     87 
     88 typedef enum {
     89   CpuStateIdle,
     90   CpuStateReady,
     91   CpuStateBusy,
     92   CpuStateFinished,
     93   CpuStateDisabled
     94 } CPU_STATE;
     95 
     96 //
     97 // Define Individual Processor Data block.
     98 //
     99 typedef struct {
    100   EFI_AP_PROCEDURE volatile      Procedure;
    101   VOID* volatile                 Parameter;
    102 
    103   EFI_EVENT                      WaitEvent;
    104   BOOLEAN                        *Finished;
    105   UINT64                         ExpectedTime;
    106   UINT64                         CurrentTime;
    107   UINT64                         TotalTime;
    108 
    109   SPIN_LOCK                      CpuDataLock;
    110   CPU_STATE volatile             State;
    111 
    112 } CPU_DATA_BLOCK;
    113 
    114 //
    115 // Define MP data block which consumes individual processor block.
    116 //
    117 typedef struct {
    118   SPIN_LOCK                   APSerializeLock;
    119 
    120   EFI_EVENT                   CheckAPsEvent;
    121 
    122   UINTN                       FinishCount;
    123   UINTN                       StartCount;
    124 
    125   BOOLEAN                     CpuList[MAX_CPU_NUMBER];
    126 
    127   EFI_AP_PROCEDURE            Procedure;
    128   VOID                        *ProcArguments;
    129   BOOLEAN                     SingleThread;
    130   EFI_EVENT                   WaitEvent;
    131   UINTN                       **FailedCpuList;
    132   UINT64                      ExpectedTime;
    133   UINT64                      CurrentTime;
    134   UINT64                      TotalTime;
    135 
    136   CPU_DATA_BLOCK              CpuData[MAX_CPU_NUMBER];
    137 } MP_SYSTEM_DATA;
    138 
    139 /**
    140   Implementation of GetNumberOfProcessors() service of MP Services Protocol.
    141 
    142   This service retrieves the number of logical processor in the platform
    143   and the number of those logical processors that are enabled on this boot.
    144   This service may only be called from the BSP.
    145 
    146   @param  This                       A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
    147   @param  NumberOfProcessors         Pointer to the total number of logical processors in the system,
    148                                      including the BSP and disabled APs.
    149   @param  NumberOfEnabledProcessors  Pointer to the number of enabled logical processors that exist
    150                                      in system, including the BSP.
    151 
    152   @retval EFI_SUCCESS	             Number of logical processors and enabled logical processors retrieved..
    153   @retval EFI_DEVICE_ERROR           Caller processor is AP.
    154   @retval EFI_INVALID_PARAMETER      NumberOfProcessors is NULL
    155   @retval EFI_INVALID_PARAMETER      NumberOfEnabledProcessors is NULL
    156 
    157 **/
    158 EFI_STATUS
    159 EFIAPI
    160 GetNumberOfProcessors (
    161   IN  EFI_MP_SERVICES_PROTOCOL     *This,
    162   OUT UINTN                        *NumberOfProcessors,
    163   OUT UINTN                        *NumberOfEnabledProcessors
    164   );
    165 
    166 /**
    167   Implementation of GetNumberOfProcessors() service of MP Services Protocol.
    168 
    169   Gets detailed MP-related information on the requested processor at the
    170   instant this call is made. This service may only be called from the BSP.
    171 
    172   @param  This                  A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
    173   @param  ProcessorNumber       The handle number of processor.
    174   @param  ProcessorInfoBuffer   A pointer to the buffer where information for the requested processor is deposited.
    175 
    176   @retval EFI_SUCCESS           Processor information successfully returned.
    177   @retval EFI_DEVICE_ERROR      Caller processor is AP.
    178   @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL
    179   @retval EFI_NOT_FOUND         Processor with the handle specified by ProcessorNumber does not exist.
    180 
    181 **/
    182 EFI_STATUS
    183 EFIAPI
    184 GetProcessorInfo (
    185   IN       EFI_MP_SERVICES_PROTOCOL     *This,
    186   IN       UINTN                        ProcessorNumber,
    187   OUT      EFI_PROCESSOR_INFORMATION    *ProcessorInfoBuffer
    188   );
    189 
    190 /**
    191   Implementation of StartupAllAPs() service of MP Services Protocol.
    192 
    193   This service lets the caller get all enabled APs to execute a caller-provided function.
    194   This service may only be called from the BSP.
    195 
    196   @param  This                  A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
    197   @param  Procedure             A pointer to the function to be run on enabled APs of the system.
    198   @param  SingleThread          Indicates whether to execute the function simultaneously or one by one..
    199   @param  WaitEvent             The event created by the caller.
    200                                 If it is NULL, then execute in blocking mode.
    201                                 If it is not NULL, then execute in non-blocking mode.
    202   @param  TimeoutInMicroSeconds The time limit in microseconds for this AP to finish the function.
    203                                 Zero means infinity.
    204   @param  ProcedureArgument     Pointer to the optional parameter of the assigned function.
    205   @param  FailedCpuList         The list of processor numbers that fail to finish the function before
    206                                 TimeoutInMicrosecsond expires.
    207 
    208   @retval EFI_SUCCESS           In blocking mode, all APs have finished before the timeout expired.
    209   @retval EFI_SUCCESS           In non-blocking mode, function has been dispatched to all enabled APs.
    210   @retval EFI_DEVICE_ERROR      Caller processor is AP.
    211   @retval EFI_NOT_STARTED       No enabled AP exists in the system.
    212   @retval EFI_NOT_READY         Any enabled AP is busy.
    213   @retval EFI_TIMEOUT           In blocking mode, The timeout expired before all enabled APs have finished.
    214   @retval EFI_INVALID_PARAMETER Procedure is NULL.
    215 
    216 **/
    217 EFI_STATUS
    218 EFIAPI
    219 StartupAllAPs (
    220   IN  EFI_MP_SERVICES_PROTOCOL   *This,
    221   IN  EFI_AP_PROCEDURE           Procedure,
    222   IN  BOOLEAN                    SingleThread,
    223   IN  EFI_EVENT                  WaitEvent             OPTIONAL,
    224   IN  UINTN                      TimeoutInMicroSeconds,
    225   IN  VOID                       *ProcedureArgument    OPTIONAL,
    226   OUT UINTN                      **FailedCpuList       OPTIONAL
    227   );
    228 
    229 /**
    230   Implementation of StartupThisAP() service of MP Services Protocol.
    231 
    232   This service lets the caller get one enabled AP to execute a caller-provided function.
    233   This service may only be called from the BSP.
    234 
    235   @param  This                  A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
    236   @param  Procedure             A pointer to the function to be run on the designated AP.
    237   @param  ProcessorNumber       The handle number of AP..
    238   @param  WaitEvent             The event created by the caller.
    239                                 If it is NULL, then execute in blocking mode.
    240                                 If it is not NULL, then execute in non-blocking mode.
    241   @param  TimeoutInMicroseconds The time limit in microseconds for this AP to finish the function.
    242                                 Zero means infinity.
    243   @param  ProcedureArgument     Pointer to the optional parameter of the assigned function.
    244   @param  Finished              Indicates whether AP has finished assigned function.
    245                                 In blocking mode, it is ignored.
    246 
    247   @retval EFI_SUCCESS           In blocking mode, specified AP has finished before the timeout expires.
    248   @retval EFI_SUCCESS           In non-blocking mode, function has been dispatched to specified AP.
    249   @retval EFI_DEVICE_ERROR      Caller processor is AP.
    250   @retval EFI_TIMEOUT           In blocking mode, the timeout expires before specified AP has finished.
    251   @retval EFI_NOT_READY         Specified AP is busy.
    252   @retval EFI_NOT_FOUND         Processor with the handle specified by ProcessorNumber does not exist.
    253   @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
    254   @retval EFI_INVALID_PARAMETER Procedure is NULL.
    255 
    256 **/
    257 EFI_STATUS
    258 EFIAPI
    259 StartupThisAP (
    260   IN  EFI_MP_SERVICES_PROTOCOL   *This,
    261   IN  EFI_AP_PROCEDURE           Procedure,
    262   IN  UINTN                      ProcessorNumber,
    263   IN  EFI_EVENT                  WaitEvent OPTIONAL,
    264   IN  UINTN                      TimeoutInMicroseconds,
    265   IN  VOID                       *ProcedureArgument OPTIONAL,
    266   OUT BOOLEAN                    *Finished OPTIONAL
    267   );
    268 
    269 /**
    270   Implementation of SwitchBSP() service of MP Services Protocol.
    271 
    272   This service switches the requested AP to be the BSP from that point onward.
    273   This service may only be called from the current BSP.
    274 
    275   @param  This                  A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
    276   @param  ProcessorNumber       The handle number of processor.
    277   @param  EnableOldBSP          Whether to enable or disable the original BSP.
    278 
    279   @retval EFI_SUCCESS           BSP successfully switched.
    280   @retval EFI_DEVICE_ERROR      Caller processor is AP.
    281   @retval EFI_NOT_FOUND         Processor with the handle specified by ProcessorNumber does not exist.
    282   @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
    283   @retval EFI_NOT_READY         Specified AP is busy.
    284 
    285 **/
    286 EFI_STATUS
    287 EFIAPI
    288 SwitchBSP (
    289   IN  EFI_MP_SERVICES_PROTOCOL            *This,
    290   IN  UINTN                               ProcessorNumber,
    291   IN  BOOLEAN                             EnableOldBSP
    292   );
    293 
    294 /**
    295   Implementation of EnableDisableAP() service of MP Services Protocol.
    296 
    297   This service lets the caller enable or disable an AP.
    298   This service may only be called from the BSP.
    299 
    300   @param  This                   A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
    301   @param  ProcessorNumber        The handle number of processor.
    302   @param  EnableAP               Indicates whether the newstate of the AP is enabled or disabled.
    303   @param  HealthFlag             Indicates new health state of the AP..
    304 
    305   @retval EFI_SUCCESS            AP successfully enabled or disabled.
    306   @retval EFI_DEVICE_ERROR       Caller processor is AP.
    307   @retval EFI_NOT_FOUND          Processor with the handle specified by ProcessorNumber does not exist.
    308   @retval EFI_INVALID_PARAMETERS ProcessorNumber specifies the BSP.
    309 
    310 **/
    311 EFI_STATUS
    312 EFIAPI
    313 EnableDisableAP (
    314   IN  EFI_MP_SERVICES_PROTOCOL            *This,
    315   IN  UINTN                               ProcessorNumber,
    316   IN  BOOLEAN                             EnableAP,
    317   IN  UINT32                              *HealthFlag OPTIONAL
    318   );
    319 
    320 /**
    321   Implementation of WhoAmI() service of MP Services Protocol.
    322 
    323   This service lets the caller processor get its handle number.
    324   This service may be called from the BSP and APs.
    325 
    326   @param  This                  A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
    327   @param  ProcessorNumber       Pointer to the handle number of AP.
    328 
    329   @retval EFI_SUCCESS           Processor number successfully returned.
    330   @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL
    331 
    332 **/
    333 EFI_STATUS
    334 EFIAPI
    335 WhoAmI (
    336   IN  EFI_MP_SERVICES_PROTOCOL            *This,
    337   OUT UINTN                               *ProcessorNumber
    338   );
    339 
    340 /**
    341   Checks APs' status periodically.
    342 
    343   This function is triggerred by timer perodically to check the
    344   state of APs for StartupAllAPs() and StartupThisAP() executed
    345   in non-blocking mode.
    346 
    347   @param  Event    Event triggered.
    348   @param  Context  Parameter passed with the event.
    349 
    350 **/
    351 VOID
    352 EFIAPI
    353 CheckAPsStatus (
    354   IN  EFI_EVENT                           Event,
    355   IN  VOID                                *Context
    356   );
    357 
    358 /**
    359   Checks status of all APs.
    360 
    361   This function checks whether all APs have finished task assigned by StartupAllAPs(),
    362   and whether timeout expires.
    363 
    364   @retval EFI_SUCCESS           All APs have finished task assigned by StartupAllAPs().
    365   @retval EFI_TIMEOUT           The timeout expires.
    366   @retval EFI_NOT_READY         APs have not finished task and timeout has not expired.
    367 
    368 **/
    369 EFI_STATUS
    370 CheckAllAPs (
    371   VOID
    372   );
    373 
    374 /**
    375   Checks status of specified AP.
    376 
    377   This function checks whether specified AP has finished task assigned by StartupThisAP(),
    378   and whether timeout expires.
    379 
    380   @param  ProcessorNumber       The handle number of processor.
    381 
    382   @retval EFI_SUCCESS           Specified AP has finished task assigned by StartupThisAPs().
    383   @retval EFI_TIMEOUT           The timeout expires.
    384   @retval EFI_NOT_READY         Specified AP has not finished task and timeout has not expired.
    385 
    386 **/
    387 EFI_STATUS
    388 CheckThisAP (
    389   UINTN  ProcessorNumber
    390   );
    391 
    392 /**
    393   Calculate timeout value and return the current performance counter value.
    394 
    395   Calculate the number of performance counter ticks required for a timeout.
    396   If TimeoutInMicroseconds is 0, return value is also 0, which is recognized
    397   as infinity.
    398 
    399   @param  TimeoutInMicroseconds   Timeout value in microseconds.
    400   @param  CurrentTime             Returns the current value of the performance counter.
    401 
    402   @return Expected timestamp counter for timeout.
    403           If TimeoutInMicroseconds is 0, return value is also 0, which is recognized
    404           as infinity.
    405 
    406 **/
    407 UINT64
    408 CalculateTimeout (
    409   IN  UINTN   TimeoutInMicroseconds,
    410   OUT UINT64  *CurrentTime
    411   );
    412 
    413 /**
    414   Checks whether timeout expires.
    415 
    416   Check whether the number of ellapsed performance counter ticks required for a timeout condition
    417   has been reached.  If Timeout is zero, which means infinity, return value is always FALSE.
    418 
    419   @param  PreviousTime         On input, the value of the performance counter when it was last read.
    420                                On output, the current value of the performance counter
    421   @param  TotalTime            The total amount of ellapsed time in performance counter ticks.
    422   @param  Timeout              The number of performance counter ticks required to reach a timeout condition.
    423 
    424   @retval TRUE                 A timeout condition has been reached.
    425   @retval FALSE                A timeout condition has not been reached.
    426 
    427 **/
    428 BOOLEAN
    429 CheckTimeout (
    430   IN OUT UINT64  *PreviousTime,
    431   IN     UINT64  *TotalTime,
    432   IN     UINT64  Timeout
    433   );
    434 
    435 /**
    436   Searches for the next waiting AP.
    437 
    438   Search for the next AP that is put in waiting state by single-threaded StartupAllAPs().
    439 
    440   @param  NextProcessorNumber  Pointer to the processor number of the next waiting AP.
    441 
    442   @retval EFI_SUCCESS          The next waiting AP has been found.
    443   @retval EFI_NOT_FOUND        No waiting AP exists.
    444 
    445 **/
    446 EFI_STATUS
    447 GetNextWaitingProcessorNumber (
    448   OUT UINTN                               *NextProcessorNumber
    449   );
    450 
    451 /**
    452   Wrapper function for all procedures assigned to AP.
    453 
    454   Wrapper function for all procedures assigned to AP via MP service protocol.
    455   It controls states of AP and invokes assigned precedure.
    456 
    457 **/
    458 VOID
    459 ApProcWrapper (
    460   VOID
    461   );
    462 
    463 /**
    464   Function to wake up a specified AP and assign procedure to it.
    465 
    466   @param  ProcessorNumber  Handle number of the specified processor.
    467   @param  Procedure        Procedure to assign.
    468   @param  ProcArguments    Argument for Procedure.
    469 
    470 **/
    471 VOID
    472 WakeUpAp (
    473   IN   UINTN                 ProcessorNumber,
    474   IN   EFI_AP_PROCEDURE      Procedure,
    475   IN   VOID                  *ProcArguments
    476   );
    477 
    478 /**
    479   Terminate AP's task and set it to idle state.
    480 
    481   This function terminates AP's task due to timeout by sending INIT-SIPI,
    482   and sends it to idle state.
    483 
    484   @param  ProcessorNumber  Handle number of the specified processor.
    485 
    486 **/
    487 VOID
    488 ResetProcessorToIdleState (
    489   UINTN      ProcessorNumber
    490   );
    491 
    492 /**
    493   Worker function of EnableDisableAP ()
    494 
    495   Worker function of EnableDisableAP (). Changes state of specified processor.
    496 
    497   @param  ProcessorNumber Processor number of specified AP.
    498   @param  NewState        Desired state of the specified AP.
    499 
    500   @retval EFI_SUCCESS     AP's state successfully changed.
    501 
    502 **/
    503 EFI_STATUS
    504 ChangeCpuState (
    505   IN     UINTN                      ProcessorNumber,
    506   IN     BOOLEAN                    NewState
    507   );
    508 
    509 /**
    510   Gets the processor number of BSP.
    511 
    512   @return  The processor number of BSP.
    513 
    514 **/
    515 UINTN
    516 GetBspNumber (
    517   VOID
    518   );
    519 
    520 /**
    521   Get address map of RendezvousFunnelProc.
    522 
    523   This function gets address map of RendezvousFunnelProc.
    524 
    525   @param  AddressMap   Output buffer for address map information
    526 
    527 **/
    528 VOID
    529 AsmGetAddressMap (
    530   OUT MP_ASSEMBLY_ADDRESS_MAP    *AddressMap
    531   );
    532 
    533 #endif
    534