Home | History | Annotate | Download | only in DxeRuntimeExtendedSalLib
      1 /** @file
      2   This library implements the Extended SAL Library Class for use in boot services and runtime.
      3 
      4   Copyright (c) 2006 - 2012, 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 #include <PiDxe.h>
     16 
     17 #include <Protocol/ExtendedSalBootService.h>
     18 #include <Protocol/ExtendedSalServiceClasses.h>
     19 #include <Guid/EventGroup.h>
     20 
     21 #include <Library/ExtendedSalLib.h>
     22 #include <Library/UefiBootServicesTableLib.h>
     23 #include <Library/UefiRuntimeServicesTableLib.h>
     24 #include <Library/UefiRuntimeLib.h>
     25 #include <Library/DebugLib.h>
     26 
     27 /**
     28   Stores the virtual plabel of ESAL entrypoint.
     29 
     30   This assembly function stores the virtual plabel of ESAL entrypoint
     31   where GetEsalEntryPoint() can easily retrieve.
     32 
     33   @param  EntryPoint  Virtual address of ESAL entrypoint
     34   @param  Gp          Virtual GP of ESAL entrypoint
     35 
     36   @return r8 = EFI_SAL_SUCCESS
     37 
     38 **/
     39 SAL_RETURN_REGS
     40 EFIAPI
     41 SetEsalVirtualEntryPoint (
     42   IN  UINT64  EntryPoint,
     43   IN  UINT64  Gp
     44   );
     45 
     46 /**
     47   Stores the physical plabel of ESAL entrypoint.
     48 
     49   This assembly function stores the physical plabel of ESAL entrypoint
     50   where GetEsalEntryPoint() can easily retrieve.
     51 
     52   @param  EntryPoint  Physical address of ESAL entrypoint
     53   @param  Gp          Physical GP of ESAL entrypoint
     54 
     55   @return r8 = EFI_SAL_SUCCESS
     56 
     57 **/
     58 SAL_RETURN_REGS
     59 EFIAPI
     60 SetEsalPhysicalEntryPoint (
     61   IN  UINT64  EntryPoint,
     62   IN  UINT64  Gp
     63   );
     64 
     65 /**
     66   Retrieves plabel of ESAL entrypoint.
     67 
     68   This function retrives plabel of ESAL entrypoint stored by
     69   SetEsalPhysicalEntryPoint().
     70 
     71   @return r8  = EFI_SAL_SUCCESS
     72           r9  = Physical Plabel
     73           r10 = Virtual Plabel
     74           r11 = PSR
     75 
     76 **/
     77 SAL_RETURN_REGS
     78 EFIAPI
     79 GetEsalEntryPoint (
     80   VOID
     81   );
     82 
     83 EXTENDED_SAL_BOOT_SERVICE_PROTOCOL  *mEsalBootService = NULL;
     84 EFI_PLABEL                          mPlabel;
     85 EFI_EVENT                           mEfiVirtualNotifyEvent;
     86 
     87 /**
     88   Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE to set virtual plabel of
     89   ESAL entrypoint.
     90 
     91   This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
     92   It converts physical plabel of ESAL entrypoint to virtual plabel and stores it where
     93   GetEsalEntryPoint() can easily retrieve.
     94 
     95   @param  Event        Event whose notification function is being invoked.
     96   @param  Context      Pointer to the notification function's context
     97 
     98 **/
     99 VOID
    100 EFIAPI
    101 ExtendedSalVirtualNotifyEvent (
    102   IN EFI_EVENT        Event,
    103   IN VOID             *Context
    104   )
    105 {
    106   UINT64  PhysicalEntryPoint;
    107 
    108   PhysicalEntryPoint = mPlabel.EntryPoint;
    109 
    110   gRT->ConvertPointer (0x0, (VOID **) &mPlabel.EntryPoint);
    111 
    112   mPlabel.GP += mPlabel.EntryPoint - PhysicalEntryPoint;
    113 
    114   SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
    115 }
    116 
    117 /**
    118   Gets Extended SAL Boot Service Protocol, and initializes physical plabel of
    119   ESAL entrypoint.
    120 
    121   This function first locates Extended SAL Boot Service Protocol and caches it in global variable.
    122   Then it initializes the physical plable of ESAL entrypoint, and stores
    123   it where GetEsalEntryPoint() can easily retrieve.
    124 
    125   @retval  EFI_SUCCESS  Plable of ESAL entrypoint successfully stored.
    126 
    127 **/
    128 EFI_STATUS
    129 DxeSalLibInitialize (
    130   VOID
    131   )
    132 {
    133   EFI_PLABEL  *Plabel;
    134   EFI_STATUS  Status;
    135 
    136   //
    137   // The protocol contains a function pointer, which is an indirect procedure call.
    138   // An indirect procedure call goes through a plabel, and pointer to a function is
    139   // a pointer to a plabel. To implement indirect procedure calls that can work in
    140   // both physical and virtual mode, two plabels are required (one physical and one
    141   // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it
    142   // away. We cache it in a module global, so we can register the vitrual version.
    143   //
    144   Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, (VOID **) &mEsalBootService);
    145   ASSERT_EFI_ERROR (Status);
    146 
    147   Plabel              = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;
    148   mPlabel.EntryPoint  = Plabel->EntryPoint;
    149   mPlabel.GP          = Plabel->GP;
    150   //
    151   // Stores the physical plabel of ESAL entrypoint where GetEsalEntryPoint() can easily retrieve.
    152   //
    153   SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
    154 
    155   return EFI_SUCCESS;
    156 }
    157 
    158 /**
    159   Constructor function to initializes physical plabel of ESAL entrypoint and register an event
    160   for initialization of virtual plabel of ESAL entrypoint.
    161 
    162   This is the library constructor function to call a function to initialize physical plabel of ESAL entrypoint
    163   and to register notification function for
    164   EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, which sets virtual plabel of ESAL entrypoint.
    165 
    166   @param  ImageHandle   The firmware allocated handle for the EFI image.
    167   @param  SystemTable   A pointer to the EFI System Table.
    168 
    169   @retval EFI_SUCCESS   Notification function successfully registered.
    170 
    171 **/
    172 EFI_STATUS
    173 EFIAPI
    174 DxeRuntimeExtendedSalLibConstruct (
    175   IN EFI_HANDLE           ImageHandle,
    176   IN EFI_SYSTEM_TABLE     *SystemTable
    177   )
    178 {
    179   EFI_STATUS  Status;
    180 
    181   //
    182   // Register notify function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
    183   //
    184   ASSERT (gBS != NULL);
    185 
    186   DxeSalLibInitialize ();
    187 
    188   Status = gBS->CreateEventEx (
    189                   EVT_NOTIFY_SIGNAL,
    190                   TPL_NOTIFY,
    191                   ExtendedSalVirtualNotifyEvent,
    192                   NULL,
    193                   &gEfiEventVirtualAddressChangeGuid,
    194                   &mEfiVirtualNotifyEvent
    195                   );
    196 
    197   ASSERT_EFI_ERROR (Status);
    198 
    199   return EFI_SUCCESS;
    200 }
    201 
    202 /**
    203   Destructor function to close the event created by the library constructor
    204 
    205   This is the library destructor function to close the event with type of
    206   EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, which is created by the library constructor.
    207 
    208   @param  ImageHandle   The firmware allocated handle for the EFI image.
    209   @param  SystemTable   A pointer to the EFI System Table.
    210 
    211   @retval EFI_SUCCESS   Event successfully closed.
    212 
    213 **/
    214 EFI_STATUS
    215 EFIAPI
    216 DxeRuntimeExtendedSalLibDeconstruct (
    217   IN EFI_HANDLE        ImageHandle,
    218   IN EFI_SYSTEM_TABLE  *SystemTable
    219   )
    220 {
    221   EFI_STATUS  Status;
    222 
    223   //
    224   // Close SetVirtualAddressMap () notify function
    225   //
    226   ASSERT (gBS != NULL);
    227   Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);
    228   ASSERT_EFI_ERROR (Status);
    229 
    230   return EFI_SUCCESS;
    231 }
    232 
    233 /**
    234   Registers function of ESAL class and it's associated global.
    235 
    236   This function registers function of ESAL class, together with its associated global.
    237   It is worker function for RegisterEsalClass().
    238   It is only for boot time.
    239 
    240   @param  FunctionId     ID of function to register
    241   @param  ClassGuidLo    GUID of ESAL class, lower 64-bits
    242   @param  ClassGuidHi    GUID of ESAL class, upper 64-bits
    243   @param  Function       Function to register with ClassGuid/FunctionId pair
    244   @param  ModuleGlobal   Module global for the function.
    245 
    246   @return Status returned by RegisterExtendedSalProc() of Extended SAL Boot Service Protocol
    247 
    248 **/
    249 EFI_STATUS
    250 RegisterEsalFunction (
    251   IN  UINT64                                    FunctionId,
    252   IN  UINT64                                    ClassGuidLo,
    253   IN  UINT64                                    ClassGuidHi,
    254   IN  SAL_INTERNAL_EXTENDED_SAL_PROC            Function,
    255   IN  VOID                                      *ModuleGlobal
    256   )
    257 {
    258   return mEsalBootService->RegisterExtendedSalProc (
    259                              mEsalBootService,
    260                              ClassGuidLo,
    261                              ClassGuidHi,
    262                              FunctionId,
    263                              Function,
    264                              ModuleGlobal
    265                              );
    266 }
    267 
    268 /**
    269   Registers ESAL Class and it's associated global.
    270 
    271   This function registers one or more Extended SAL services in a given
    272   class along with the associated global context.
    273   This function is only available prior to ExitBootServices().
    274 
    275   @param  ClassGuidLo          GUID of function class, lower 64-bits
    276   @param  ClassGuidHi          GUID of function class, upper 64-bits
    277   @param  ModuleGlobal         Module global for the class.
    278   @param  ...                  List of Function/FunctionId pairs, ended by NULL
    279 
    280   @retval EFI_SUCCESS          The Extended SAL services were registered.
    281   @retval EFI_UNSUPPORTED      This function was called after ExitBootServices().
    282   @retval EFI_OUT_OF_RESOURCES There are not enough resources available to register one or more of the specified services.
    283   @retval Other                ClassGuid could not be installed onto a new handle.
    284 
    285 **/
    286 EFI_STATUS
    287 EFIAPI
    288 RegisterEsalClass (
    289   IN  CONST UINT64    ClassGuidLo,
    290   IN  CONST UINT64    ClassGuidHi,
    291   IN  VOID            *ModuleGlobal,  OPTIONAL
    292   ...
    293   )
    294 {
    295   VA_LIST                         Args;
    296   EFI_STATUS                      Status;
    297   SAL_INTERNAL_EXTENDED_SAL_PROC  Function;
    298   UINT64                          FunctionId;
    299   EFI_HANDLE                      NewHandle;
    300   EFI_GUID                        ClassGuid;
    301 
    302   VA_START (Args, ModuleGlobal);
    303 
    304   //
    305   // Register all functions of the class to register.
    306   //
    307   Status = EFI_SUCCESS;
    308   while (!EFI_ERROR (Status)) {
    309     Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);
    310     //
    311     // NULL serves as the end mark of function list
    312     //
    313     if (Function == NULL) {
    314       break;
    315     }
    316 
    317     FunctionId  = VA_ARG (Args, UINT64);
    318 
    319     Status      = RegisterEsalFunction (FunctionId, ClassGuidLo, ClassGuidHi, Function, ModuleGlobal);
    320   }
    321 
    322   VA_END (Args);
    323 
    324   if (EFI_ERROR (Status)) {
    325     return Status;
    326   }
    327 
    328   NewHandle = NULL;
    329   *((UINT64 *)(&ClassGuid) + 0) = ClassGuidLo;
    330   *((UINT64 *)(&ClassGuid) + 1) = ClassGuidHi;
    331   return gBS->InstallProtocolInterface (
    332                 &NewHandle,
    333                 &ClassGuid,
    334                 EFI_NATIVE_INTERFACE,
    335                 NULL
    336                 );
    337 }
    338 
    339 /**
    340   Calls an Extended SAL Class service that was previously registered with RegisterEsalClass().
    341 
    342   This function gets the entrypoint of Extended SAL, and calls an Extended SAL Class service
    343   that was previously registered with RegisterEsalClass() through this entrypoint.
    344 
    345   @param  ClassGuidLo     GUID of function, lower 64-bits
    346   @param  ClassGuidHi     GUID of function, upper 64-bits
    347   @param  FunctionId      Function in ClassGuid to call
    348   @param  Arg2            Argument 2 ClassGuid/FunctionId defined
    349   @param  Arg3            Argument 3 ClassGuid/FunctionId defined
    350   @param  Arg4            Argument 4 ClassGuid/FunctionId defined
    351   @param  Arg5            Argument 5 ClassGuid/FunctionId defined
    352   @param  Arg6            Argument 6 ClassGuid/FunctionId defined
    353   @param  Arg7            Argument 7 ClassGuid/FunctionId defined
    354   @param  Arg8            Argument 8 ClassGuid/FunctionId defined
    355 
    356   @retval EFI_SAL_SUCCESS ESAL procedure successfully called.
    357   @retval EFI_SAL_ERROR   The address of ExtendedSalProc() can not be correctly
    358                           initialized.
    359   @retval Other           Status returned from ExtendedSalProc() service of
    360                           EXTENDED_SAL_BOOT_SERVICE_PROTOCOL.
    361 
    362 **/
    363 SAL_RETURN_REGS
    364 EFIAPI
    365 EsalCall (
    366   IN  UINT64    ClassGuidLo,
    367   IN  UINT64    ClassGuidHi,
    368   IN  UINT64    FunctionId,
    369   IN  UINT64    Arg2,
    370   IN  UINT64    Arg3,
    371   IN  UINT64    Arg4,
    372   IN  UINT64    Arg5,
    373   IN  UINT64    Arg6,
    374   IN  UINT64    Arg7,
    375   IN  UINT64    Arg8
    376   )
    377 {
    378   SAL_RETURN_REGS       ReturnReg;
    379   EXTENDED_SAL_PROC     EsalProc;
    380 
    381   //
    382   // Get the entrypoint of Extended SAL
    383   //
    384   ReturnReg = GetEsalEntryPoint ();
    385   if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) {
    386     //
    387     // The ESAL Entry Point could not be initialized
    388     //
    389     ReturnReg.Status = EFI_SAL_ERROR;
    390     return ReturnReg;
    391   }
    392 
    393   //
    394   // Test PSR.it which is BIT36
    395   //
    396   if ((ReturnReg.r11 & BIT36) != 0) {
    397     //
    398     // Virtual mode plabel to entry point
    399     //
    400     EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r10;
    401   } else {
    402     //
    403     // Physical mode plabel to entry point
    404     //
    405     EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r9;
    406   }
    407 
    408   return EsalProc (
    409            ClassGuidLo,
    410            ClassGuidHi,
    411            FunctionId,
    412            Arg2,
    413            Arg3,
    414            Arg4,
    415            Arg5,
    416            Arg6,
    417            Arg7,
    418            Arg8
    419            );
    420 }
    421 
    422 /**
    423   Wrapper for the EsalStallFunctionId service of Extended SAL Stall Services Class.
    424 
    425   This function is a wrapper for the EsalStallFunctionId service of Extended SAL
    426   Stall Services Class. See EsalStallFunctionId of Extended SAL Specification.
    427 
    428   @param  Microseconds         The number of microseconds to delay.
    429 
    430   @retval EFI_SAL_SUCCESS               Call completed without error.
    431   @retval EFI_SAL_INVALID_ARGUMENT      Invalid argument.
    432   @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR Virtual address not registered
    433 
    434 **/
    435 SAL_RETURN_REGS
    436 EFIAPI
    437 EsalStall (
    438   IN UINTN  Microseconds
    439   )
    440 {
    441   return EsalCall (
    442            EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_LO,
    443            EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_HI,
    444            StallFunctionId,
    445            Microseconds,
    446            0,
    447            0,
    448            0,
    449            0,
    450            0,
    451            0
    452            );
    453 }
    454 
    455 /**
    456   Wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.
    457 
    458   This function is a wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL
    459   PAL Services Services Class. See EsalSetNewPalEntryFunctionId of Extended SAL Specification.
    460 
    461   @param  PhysicalAddress        If TRUE, then PalEntryPoint is a physical address.
    462                                  If FALSE, then PalEntryPoint is a virtual address.
    463   @param  PalEntryPoint          The PAL Entry Point being set.
    464 
    465   @retval EFI_SAL_SUCCESS                The PAL Entry Point was set.
    466   @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before
    467                                          virtual mappings for the specified Extended SAL
    468                                          Procedure are available.
    469 
    470 **/
    471 SAL_RETURN_REGS
    472 EFIAPI
    473 EsalSetNewPalEntry (
    474   IN BOOLEAN  PhysicalAddress,
    475   IN UINT64   PalEntryPoint
    476   )
    477 {
    478   return EsalCall (
    479            EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,
    480            EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,
    481            SetNewPalEntryFunctionId,
    482            PhysicalAddress,
    483            PalEntryPoint,
    484            0,
    485            0,
    486            0,
    487            0,
    488            0
    489            );
    490 }
    491 
    492 /**
    493   Wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.
    494 
    495   This function is a wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL
    496   PAL Services Services Class. See EsalGetNewPalEntryFunctionId of Extended SAL Specification.
    497 
    498   @param  PhysicalAddress        If TRUE, then PalEntryPoint is a physical address.
    499                                  If FALSE, then PalEntryPoint is a virtual address.
    500 
    501   @retval EFI_SAL_SUCCESS                The PAL Entry Point was retrieved and returned in
    502                                          SAL_RETURN_REGS.r9.
    503   @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before
    504                                          virtual mappings for the specified Extended SAL
    505                                          Procedure are available.
    506   @return r9                             PAL entry point retrieved.
    507 
    508 **/
    509 SAL_RETURN_REGS
    510 EFIAPI
    511 EsalGetNewPalEntry (
    512   IN BOOLEAN  PhysicalAddress
    513   )
    514 {
    515   return EsalCall (
    516            EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,
    517            EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,
    518            GetNewPalEntryFunctionId,
    519            PhysicalAddress,
    520            0,
    521            0,
    522            0,
    523            0,
    524            0,
    525            0
    526            );
    527 }
    528 
    529 /**
    530   Wrapper for the EsalGetStateBufferFunctionId service of Extended SAL MCA Log Services Class.
    531 
    532   This function is a wrapper for the EsalGetStateBufferFunctionId service of Extended SAL
    533   MCA Log Services Class. See EsalGetStateBufferFunctionId of Extended SAL Specification.
    534 
    535   @param  McaType         See type parameter of SAL Procedure SAL_GET_STATE_INFO.
    536   @param  McaBuffer             A pointer to the base address of the returned buffer.
    537                                 Copied from SAL_RETURN_REGS.r9.
    538   @param  BufferSize            A pointer to the size, in bytes, of the returned buffer.
    539                                 Copied from SAL_RETURN_REGS.r10.
    540 
    541   @retval EFI_SAL_SUCCESS       The memory buffer to store error records was returned in r9 and r10.
    542   @retval EFI_OUT_OF_RESOURCES  A memory buffer for string error records in not available
    543   @return r9                    Base address of the returned buffer
    544   @return r10                   Size of the returned buffer in bytes
    545 
    546 **/
    547 SAL_RETURN_REGS
    548 EFIAPI
    549 EsalGetStateBuffer (
    550   IN  UINT64  McaType,
    551   OUT UINT8   **McaBuffer,
    552   OUT UINTN   *BufferSize
    553   )
    554 {
    555   SAL_RETURN_REGS Regs;
    556 
    557   Regs = EsalCall (
    558            EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,
    559            EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,
    560            EsalGetStateBufferFunctionId,
    561            McaType,
    562            0,
    563            0,
    564            0,
    565            0,
    566            0,
    567            0
    568            );
    569 
    570   *McaBuffer  = (UINT8 *) Regs.r9;
    571   *BufferSize = Regs.r10;
    572 
    573   return Regs;
    574 }
    575 
    576 /**
    577   Wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL MCA Log Services Class.
    578 
    579   This function is a wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL
    580   MCA Log Services Class. See EsalSaveStateBufferFunctionId of Extended SAL Specification.
    581 
    582   @param  McaType         See type parameter of SAL Procedure SAL_GET_STATE_INFO.
    583 
    584   @retval EFI_SUCCESS  The memory buffer containing the error record was written to nonvolatile storage.
    585 
    586 **/
    587 SAL_RETURN_REGS
    588 EFIAPI
    589 EsalSaveStateBuffer (
    590   IN  UINT64  McaType
    591   )
    592 {
    593   return EsalCall (
    594            EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,
    595            EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,
    596            EsalSaveStateBufferFunctionId,
    597            McaType,
    598            0,
    599            0,
    600            0,
    601            0,
    602            0,
    603            0
    604            );
    605 }
    606 
    607 /**
    608   Wrapper for the EsalGetVectorsFunctionId service of Extended SAL Base Services Class.
    609 
    610   This function is a wrapper for the EsalGetVectorsFunctionId service of Extended SAL
    611   Base Services Class. See EsalGetVectorsFunctionId of Extended SAL Specification.
    612 
    613   @param  VectorType         The vector type to retrieve.
    614                              0 - MCA, 1 - BSP INIT, 2 - BOOT_RENDEZ, 3 - AP INIT.
    615 
    616   @retval EFI_SAL_SUCCESS          Call completed without error.
    617   @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.
    618   @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered
    619                                    with the SAL Procedure SAL_SET_VECTORS.
    620 
    621 **/
    622 SAL_RETURN_REGS
    623 EFIAPI
    624 EsalGetVectors (
    625   IN  UINT64  VectorType
    626   )
    627 {
    628   return EsalCall (
    629            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,
    630            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,
    631            EsalGetVectorsFunctionId,
    632            VectorType,
    633            0,
    634            0,
    635            0,
    636            0,
    637            0,
    638            0
    639            );
    640 }
    641 
    642 /**
    643   Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.
    644 
    645   This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL
    646   Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.
    647 
    648   @param  ParamInfoType         The parameter type to retrieve.
    649                                 1 - rendezvous interrupt
    650                                 2 - wake up
    651                                 3 - Corrected Platform Error Vector.
    652 
    653   @retval EFI_SAL_SUCCESS          Call completed without error.
    654   @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.
    655   @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered
    656                                    with the SAL Procedure SAL_MC_SET_PARAMS.
    657 
    658 **/
    659 SAL_RETURN_REGS
    660 EFIAPI
    661 EsalMcGetParams (
    662   IN  UINT64  ParamInfoType
    663   )
    664 {
    665   return EsalCall (
    666            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,
    667            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,
    668            EsalMcGetParamsFunctionId,
    669            ParamInfoType,
    670            0,
    671            0,
    672            0,
    673            0,
    674            0,
    675            0
    676            );
    677 }
    678 
    679 /**
    680   Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.
    681 
    682   This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL
    683   Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.
    684 
    685   @retval EFI_SAL_SUCCESS          Call completed without error.
    686   @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered
    687                                    with the SAL Procedure SAL_MC_SET_PARAMS.
    688 
    689 **/
    690 SAL_RETURN_REGS
    691 EFIAPI
    692 EsalMcGetMcParams (
    693   VOID
    694   )
    695 {
    696   return EsalCall (
    697            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,
    698            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,
    699            EsalMcGetMcParamsFunctionId,
    700            0,
    701            0,
    702            0,
    703            0,
    704            0,
    705            0,
    706            0
    707            );
    708 }
    709 
    710 /**
    711   Wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL Base Services Class.
    712 
    713   This function is a wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL
    714   Base Services Class. See EsalGetMcCheckinFlagsFunctionId of Extended SAL Specification.
    715 
    716   @param  CpuIndex         The index of the CPU of set of enabled CPUs to check.
    717 
    718   @retval EFI_SAL_SUCCESS  The checkin status of the requested CPU was returned.
    719 
    720 **/
    721 SAL_RETURN_REGS
    722 EFIAPI
    723 EsalGetMcCheckinFlags (
    724   IN  UINT64  CpuIndex
    725   )
    726 {
    727   return EsalCall (
    728            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,
    729            EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,
    730            EsalGetMcCheckinFlagsFunctionId,
    731            CpuIndex,
    732            0,
    733            0,
    734            0,
    735            0,
    736            0,
    737            0
    738            );
    739 }
    740 
    741 /**
    742   Wrapper for the EsalAddCpuDataFunctionId service of Extended SAL MP Services Class.
    743 
    744   This function is a wrapper for the EsalAddCpuDataFunctionId service of Extended SAL
    745   MP Services Class. See EsalAddCpuDataFunctionId of Extended SAL Specification.
    746 
    747   @param  CpuGlobalId         The Global ID for the CPU being added.
    748   @param  Enabled             The enable flag for the CPU being added.
    749                               TRUE means the CPU is enabled.
    750                               FALSE means the CPU is disabled.
    751   @param  PalCompatibility    The PAL Compatibility value for the CPU being added.
    752 
    753   @retval EFI_SAL_SUCCESS             The CPU was added to the database.
    754   @retval EFI_SAL_NOT_ENOUGH_SCRATCH  There are not enough resource available to add the CPU.
    755 
    756 **/
    757 SAL_RETURN_REGS
    758 EFIAPI
    759 EsalAddCpuData (
    760   IN UINT64   CpuGlobalId,
    761   IN BOOLEAN  Enabled,
    762   IN UINT64   PalCompatibility
    763   )
    764 {
    765   return EsalCall (
    766            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
    767            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
    768            AddCpuDataFunctionId,
    769            CpuGlobalId,
    770            Enabled,
    771            PalCompatibility,
    772            0,
    773            0,
    774            0,
    775            0
    776            );
    777 }
    778 
    779 /**
    780   Wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL MP Services Class.
    781 
    782   This function is a wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL
    783   MP Services Class. See EsalRemoveCpuDataFunctionId of Extended SAL Specification.
    784 
    785   @param  CpuGlobalId         The Global ID for the CPU being removed.
    786 
    787   @retval EFI_SAL_SUCCESS         The CPU was removed from the database.
    788   @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.
    789 
    790 **/
    791 SAL_RETURN_REGS
    792 EFIAPI
    793 EsalRemoveCpuData (
    794   IN UINT64  CpuGlobalId
    795   )
    796 {
    797   return EsalCall (
    798            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
    799            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
    800            RemoveCpuDataFunctionId,
    801            CpuGlobalId,
    802            0,
    803            0,
    804            0,
    805            0,
    806            0,
    807            0
    808            );
    809 }
    810 
    811 /**
    812   Wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL MP Services Class.
    813 
    814   This function is a wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL
    815   MP Services Class. See EsalModifyCpuDataFunctionId of Extended SAL Specification.
    816 
    817   @param  CpuGlobalId         The Global ID for the CPU being modified.
    818   @param  Enabled             The enable flag for the CPU being modified.
    819                               TRUE means the CPU is enabled.
    820                               FALSE means the CPU is disabled.
    821   @param  PalCompatibility    The PAL Compatibility value for the CPU being modified.
    822 
    823   @retval EFI_SAL_SUCCESS         The CPU database was updated.
    824   @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.
    825 
    826 **/
    827 SAL_RETURN_REGS
    828 EFIAPI
    829 EsalModifyCpuData (
    830   IN UINT64   CpuGlobalId,
    831   IN BOOLEAN  Enabled,
    832   IN UINT64   PalCompatibility
    833   )
    834 {
    835   return EsalCall (
    836            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
    837            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
    838            ModifyCpuDataFunctionId,
    839            CpuGlobalId,
    840            Enabled,
    841            PalCompatibility,
    842            0,
    843            0,
    844            0,
    845            0
    846            );
    847 }
    848 
    849 /**
    850   Wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL MP Services Class.
    851 
    852   This function is a wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL
    853   MP Services Class. See EsalGetCpuDataByIdFunctionId of Extended SAL Specification.
    854 
    855   @param  CpuGlobalId         The Global ID for the CPU being looked up.
    856   @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.
    857                               If FALSE, then the index of set of all CPUs of database is returned.
    858 
    859   @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.
    860   @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.
    861 
    862 **/
    863 SAL_RETURN_REGS
    864 EFIAPI
    865 EsalGetCpuDataById (
    866   IN UINT64   CpuGlobalId,
    867   IN BOOLEAN  IndexByEnabledCpu
    868   )
    869 {
    870   return EsalCall (
    871            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
    872            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
    873            GetCpuDataByIDFunctionId,
    874            CpuGlobalId,
    875            IndexByEnabledCpu,
    876            0,
    877            0,
    878            0,
    879            0,
    880            0
    881            );
    882 }
    883 
    884 /**
    885   Wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL MP Services Class.
    886 
    887   This function is a wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL
    888   MP Services Class. See EsalGetCpuDataByIndexFunctionId of Extended SAL Specification.
    889 
    890   @param  Index               The Global ID for the CPU being modified.
    891   @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.
    892                               If FALSE, then the index of set of all CPUs of database is returned.
    893 
    894   @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.
    895   @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.
    896 
    897 **/
    898 SAL_RETURN_REGS
    899 EFIAPI
    900 EsalGetCpuDataByIndex (
    901   IN UINT64   Index,
    902   IN BOOLEAN  IndexByEnabledCpu
    903   )
    904 {
    905   return EsalCall (
    906            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
    907            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
    908            GetCpuDataByIndexFunctionId,
    909            Index,
    910            IndexByEnabledCpu,
    911            0,
    912            0,
    913            0,
    914            0,
    915            0
    916            );
    917 }
    918 
    919 /**
    920   Wrapper for the EsalWhoAmIFunctionId service of Extended SAL MP Services Class.
    921 
    922   This function is a wrapper for the EsalWhoAmIFunctionId service of Extended SAL
    923   MP Services Class. See EsalWhoAmIFunctionId of Extended SAL Specification.
    924 
    925   @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.
    926                               If FALSE, then the index of set of all CPUs of database is returned.
    927 
    928   @retval EFI_SAL_SUCCESS         The Global ID for the calling CPU was returned.
    929   @retval EFI_SAL_NO_INFORMATION  The calling CPU is not in the database.
    930 
    931 **/
    932 SAL_RETURN_REGS
    933 EFIAPI
    934 EsalWhoAmI (
    935   IN BOOLEAN  IndexByEnabledCpu
    936   )
    937 {
    938   return EsalCall (
    939            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
    940            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
    941            CurrentProcInfoFunctionId,
    942            IndexByEnabledCpu,
    943            0,
    944            0,
    945            0,
    946            0,
    947            0,
    948            0
    949            );
    950 }
    951 
    952 /**
    953   Wrapper for the EsalNumProcessors service of Extended SAL MP Services Class.
    954 
    955   This function is a wrapper for the EsalNumProcessors service of Extended SAL
    956   MP Services Class. See EsalNumProcessors of Extended SAL Specification.
    957 
    958   @retval EFI_SAL_SUCCESS    The information on the number of CPUs in the platform
    959                              was returned.
    960 
    961 **/
    962 SAL_RETURN_REGS
    963 EFIAPI
    964 EsalNumProcessors (
    965   VOID
    966   )
    967 {
    968   return EsalCall (
    969            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
    970            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
    971            NumProcessorsFunctionId,
    972            0,
    973            0,
    974            0,
    975            0,
    976            0,
    977            0,
    978            0
    979            );
    980 }
    981 
    982 /**
    983   Wrapper for the EsalSetMinStateFnctionId service of Extended SAL MP Services Class.
    984 
    985   This function is a wrapper for the EsalSetMinStateFnctionId service of Extended SAL
    986   MP Services Class. See EsalSetMinStateFnctionId of Extended SAL Specification.
    987 
    988   @param  CpuGlobalId       The Global ID for the CPU whose MINSTATE pointer is being set.
    989   @param  MinStatePointer          The physical address of the MINSTATE buffer for the CPU
    990                                    specified by CpuGlobalId.
    991 
    992   @retval EFI_SAL_SUCCESS          The MINSTATE pointer was set for the specified CPU.
    993   @retval EFI_SAL_NO_INFORMATION   The specified CPU is not in the database.
    994 
    995 **/
    996 SAL_RETURN_REGS
    997 EFIAPI
    998 EsalSetMinState (
    999   IN UINT64                CpuGlobalId,
   1000   IN EFI_PHYSICAL_ADDRESS  MinStatePointer
   1001   )
   1002 {
   1003   return EsalCall (
   1004            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
   1005            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
   1006            SetMinStateFunctionId,
   1007            CpuGlobalId,
   1008            MinStatePointer,
   1009            0,
   1010            0,
   1011            0,
   1012            0,
   1013            0
   1014            );
   1015 }
   1016 
   1017 /**
   1018   Wrapper for the EsalGetMinStateFunctionId service of Extended SAL MP Services Class.
   1019 
   1020   This function is a wrapper for the EsalGetMinStateFunctionId service of Extended SAL
   1021   MP Services Class. See EsalGetMinStateFunctionId of Extended SAL Specification.
   1022 
   1023   @param  CpuGlobalId   The Global ID for the CPU whose MINSTATE pointer is being retrieved.
   1024 
   1025   @retval EFI_SAL_SUCCESS        The MINSTATE pointer for the specified CPU was retrieved.
   1026   @retval EFI_SAL_NO_INFORMATION The specified CPU is not in the database.
   1027 
   1028 **/
   1029 SAL_RETURN_REGS
   1030 EFIAPI
   1031 EsalGetMinState (
   1032   IN UINT64  CpuGlobalId
   1033   )
   1034 {
   1035   return EsalCall (
   1036            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,
   1037            EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,
   1038            GetMinStateFunctionId,
   1039            CpuGlobalId,
   1040            0,
   1041            0,
   1042            0,
   1043            0,
   1044            0,
   1045            0
   1046            );
   1047 }
   1048 
   1049 /**
   1050   Wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL MCA Services Class.
   1051 
   1052   This function is a wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL
   1053   MCA Services Class. See EsalMcsGetStateInfoFunctionId of Extended SAL Specification.
   1054 
   1055   @param  CpuGlobalId               The Global ID for the CPU whose MCA state buffer is being retrieved.
   1056   @param  StateBufferPointer        A pointer to the returned MCA state buffer.
   1057   @param  RequiredStateBufferSize   A pointer to the size, in bytes, of the returned MCA state buffer.
   1058 
   1059   @retval EFI_SUCCESS               MINSTATE successfully got and size calculated.
   1060   @retval EFI_SAL_NO_INFORMATION    Fail to get MINSTATE.
   1061 
   1062 **/
   1063 SAL_RETURN_REGS
   1064 EFIAPI
   1065 EsalMcaGetStateInfo (
   1066   IN  UINT64                CpuGlobalId,
   1067   OUT EFI_PHYSICAL_ADDRESS  *StateBufferPointer,
   1068   OUT UINT64                *RequiredStateBufferSize
   1069   )
   1070 {
   1071   SAL_RETURN_REGS  Regs;
   1072 
   1073   Regs = EsalCall (
   1074            EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,
   1075            EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,
   1076            McaGetStateInfoFunctionId,
   1077            CpuGlobalId,
   1078            0,
   1079            0,
   1080            0,
   1081            0,
   1082            0,
   1083            0
   1084            );
   1085 
   1086   *StateBufferPointer      = (EFI_PHYSICAL_ADDRESS) Regs.r9;
   1087   *RequiredStateBufferSize = (UINT64) Regs.r10;
   1088 
   1089   return Regs;
   1090 }
   1091 
   1092 /**
   1093   Wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL MCA Services Class.
   1094 
   1095   This function is a wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL
   1096   MCA Services Class. See EsalMcaRegisterCpuFunctionId of Extended SAL Specification.
   1097 
   1098   @param  CpuGlobalId          The Global ID for the CPU whose MCA state buffer is being set.
   1099   @param  StateBufferPointer   A pointer to the MCA state buffer.
   1100 
   1101   @retval EFI_SAL_NO_INFORMATION   Cannot get the processor info with the CpuId
   1102   @retval EFI_SUCCESS              Save the processor's state info successfully
   1103 
   1104 **/
   1105 SAL_RETURN_REGS
   1106 EFIAPI
   1107 EsalMcaRegisterCpu (
   1108   IN UINT64                CpuGlobalId,
   1109   IN EFI_PHYSICAL_ADDRESS  StateBufferPointer
   1110   )
   1111 {
   1112   return EsalCall (
   1113            EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,
   1114            EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,
   1115            McaRegisterCpuFunctionId,
   1116            CpuGlobalId,
   1117            StateBufferPointer,
   1118            0,
   1119            0,
   1120            0,
   1121            0,
   1122            0
   1123            );
   1124 }
   1125