]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/DxeExtendedSalLib/ExtendedSalLib.c
Add ESAL support libraries to MdePkg
[mirror_edk2.git] / MdePkg / Library / DxeExtendedSalLib / ExtendedSalLib.c
diff --git a/MdePkg/Library/DxeExtendedSalLib/ExtendedSalLib.c b/MdePkg/Library/DxeExtendedSalLib/ExtendedSalLib.c
new file mode 100644 (file)
index 0000000..82266f5
--- /dev/null
@@ -0,0 +1,999 @@
+/** @file\r
+  The library implements the Extended SAL Library Class for boot service only modules.\r
+\r
+  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/ExtendedSalBootService.h>\r
+#include <Protocol/ExtendedSalServiceClasses.h>\r
+\r
+#include <Library/ExtendedSalLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+/**\r
+  Stores the physical plabel of ESAL entrypoint.\r
+\r
+  This assembly function stores the physical plabel of ESAL entrypoint\r
+  where GetEsalEntryPoint() can easily retrieve.\r
+\r
+  @param  EntryPoint  Physical address of ESAL entrypoint\r
+  @param  Gp          Physical GP of ESAL entrypoint\r
+\r
+  @return r8 = EFI_SAL_SUCCESS\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+SetEsalPhysicalEntryPoint (\r
+  IN  UINT64  EntryPoint,\r
+  IN  UINT64  Gp\r
+  );\r
+\r
+/**\r
+  Retrieves plabel of ESAL entrypoint.\r
+\r
+  This function retrives plabel of ESAL entrypoint stored by\r
+  SetEsalPhysicalEntryPoint().\r
+\r
+  @return r8  = EFI_SAL_SUCCESS\r
+          r9  = Physical Plabel\r
+          r10 = Virtual Plabel\r
+          r11 = PSR\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+GetEsalEntryPoint (\r
+  VOID\r
+  );\r
+\r
+EXTENDED_SAL_BOOT_SERVICE_PROTOCOL  *mEsalBootService = NULL;\r
+EFI_PLABEL                          mPlabel;\r
+\r
+/**\r
+  Constructor function to get Extended SAL Boot Service Protocol, and initializes\r
+  physical plabel of ESAL entrypoint.\r
+  \r
+  This function first locates Extended SAL Boot Service Protocol and caches it in global variable.\r
+  Then it initializes the physical plable of ESAL entrypoint, and stores\r
+  it where GetEsalEntryPoint() can easily retrieve.\r
+\r
+  @param  ImageHandle   The firmware allocated handle for the EFI image.\r
+  @param  SystemTable   A pointer to the EFI System Table.\r
+\r
+  @retval  EFI_SUCCESS  Plable of ESAL entrypoint successfully stored.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeExtendedSalLibConstruct (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_PLABEL  *Plabel;\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // The protocol contains a function pointer, which is an indirect procedure call.\r
+  // An indirect procedure call goes through a plabel, and pointer to a function is\r
+  // a pointer to a plabel. To implement indirect procedure calls that can work in\r
+  // both physical and virtual mode, two plabels are required (one physical and one\r
+  // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it\r
+  // away. We cache it in a module global, so we can register the vitrual version.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, (VOID **) &mEsalBootService);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Plabel              = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;\r
+  mPlabel.EntryPoint  = Plabel->EntryPoint;\r
+  mPlabel.GP          = Plabel->GP;\r
+  //\r
+  // Stores the physical plabel of ESAL entrypoint where GetEsalEntryPoint() can easily retrieve.\r
+  //\r
+  SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Registers function of ESAL class and it's associated global.\r
+  \r
+  This function registers function of ESAL class, together with its associated global.\r
+  It is worker function for RegisterEsalClass().\r
+  It is only for boot time.\r
+\r
+  @param  FunctionId     ID of function to register\r
+  @param  ClassGuidLo    GUID of ESAL class, lower 64-bits\r
+  @param  ClassGuidHi    GUID of ESAL class, upper 64-bits\r
+  @param  Function       Function to register with ClassGuid/FunctionId pair\r
+  @param  ModuleGlobal   Module global for the function.\r
+\r
+  @return Status returned by RegisterExtendedSalProc() of Extended SAL Boot Service Protocol\r
+\r
+**/\r
+EFI_STATUS\r
+RegisterEsalFunction (\r
+  IN  UINT64                                    FunctionId,\r
+  IN  UINT64                                    ClassGuidLo,\r
+  IN  UINT64                                    ClassGuidHi,\r
+  IN  SAL_INTERNAL_EXTENDED_SAL_PROC            Function,\r
+  IN  VOID                                      *ModuleGlobal\r
+  )\r
+{\r
+  return mEsalBootService->RegisterExtendedSalProc (\r
+                             mEsalBootService,\r
+                             ClassGuidLo,\r
+                             ClassGuidHi,\r
+                             FunctionId,\r
+                             Function,\r
+                             ModuleGlobal\r
+                             );\r
+}\r
+\r
+/**\r
+  Registers ESAL Class and it's associated global.\r
+  \r
+  This function registers one or more Extended SAL services in a given\r
+  class along with the associated global context.\r
+  This function is only available prior to ExitBootServices().\r
+\r
+  @param  ClassGuidLo          GUID of function class, lower 64-bits\r
+  @param  ClassGuidHi          GUID of function class, upper 64-bits\r
+  @param  ModuleGlobal         Module global for the class.\r
+  @param  ...                  List of Function/FunctionId pairs, ended by NULL\r
+  \r
+  @retval EFI_SUCCESS          The Extended SAL services were registered.\r
+  @retval EFI_UNSUPPORTED      This function was called after ExitBootServices().\r
+  @retval EFI_OUT_OF_RESOURCES There are not enough resources available to register one or more of the specified services.\r
+  @retval Other                ClassGuid could not be installed onto a new handle.  \r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterEsalClass (\r
+  IN  CONST UINT64    ClassGuidLo,\r
+  IN  CONST UINT64    ClassGuidHi,\r
+  IN  VOID            *ModuleGlobal,  OPTIONAL\r
+  ...\r
+  )\r
+{\r
+  VA_LIST                         Args;\r
+  EFI_STATUS                      Status;\r
+  SAL_INTERNAL_EXTENDED_SAL_PROC  Function;\r
+  UINT64                          FunctionId;\r
+  EFI_HANDLE                      NewHandle;\r
+  EFI_GUID                        ClassGuid;\r
+\r
+  VA_START (Args, ModuleGlobal);\r
+\r
+  //\r
+  // Register all functions of the class to register.\r
+  //\r
+  Status = EFI_SUCCESS;\r
+  while (!EFI_ERROR (Status)) {\r
+    Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);\r
+    //\r
+    // NULL serves as the end mark of function list\r
+    //\r
+    if (Function == NULL) {\r
+      break;\r
+    }\r
+\r
+    FunctionId = VA_ARG (Args, UINT64);\r
+\r
+    Status = RegisterEsalFunction (FunctionId, ClassGuidLo, ClassGuidHi, Function, ModuleGlobal);\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  NewHandle = NULL;\r
+  *((UINT64 *)(&ClassGuid) + 0) = ClassGuidLo;\r
+  *((UINT64 *)(&ClassGuid) + 1) = ClassGuidHi;\r
+  return gBS->InstallProtocolInterface (\r
+                &NewHandle,\r
+                &ClassGuid,\r
+                EFI_NATIVE_INTERFACE,\r
+                NULL\r
+                );\r
+}\r
+\r
+/**\r
+  Calls an Extended SAL Class service that was previously registered with RegisterEsalClass().\r
+  \r
+  This function gets the entrypoint of Extended SAL, and calls an Extended SAL Class service\r
+  that was previously registered with RegisterEsalClass() through this entrypoint.\r
+\r
+  @param  ClassGuidLo     GUID of function, lower 64-bits\r
+  @param  ClassGuidHi     GUID of function, upper 64-bits\r
+  @param  FunctionId      Function in ClassGuid to call\r
+  @param  Arg2            Argument 2 ClassGuid/FunctionId defined\r
+  @param  Arg3            Argument 3 ClassGuid/FunctionId defined\r
+  @param  Arg4            Argument 4 ClassGuid/FunctionId defined\r
+  @param  Arg5            Argument 5 ClassGuid/FunctionId defined\r
+  @param  Arg6            Argument 6 ClassGuid/FunctionId defined\r
+  @param  Arg7            Argument 7 ClassGuid/FunctionId defined\r
+  @param  Arg8            Argument 8 ClassGuid/FunctionId defined\r
+  \r
+  @retval EFI_SAL_SUCCESS ESAL procedure successfully called.\r
+  @retval EFI_SAL_ERROR   The address of ExtendedSalProc() can not be correctly\r
+                          initialized.\r
+  @retval Other           Status returned from ExtendedSalProc() service of\r
+                          EXTENDED_SAL_BOOT_SERVICE_PROTOCOL.  \r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalCall (\r
+  IN UINT64  ClassGuidLo,\r
+  IN UINT64  ClassGuidHi,\r
+  IN UINT64  FunctionId,\r
+  IN UINT64  Arg2,\r
+  IN UINT64  Arg3,\r
+  IN UINT64  Arg4,\r
+  IN UINT64  Arg5,\r
+  IN UINT64  Arg6,\r
+  IN UINT64  Arg7,\r
+  IN UINT64  Arg8\r
+  )\r
+{\r
+  SAL_RETURN_REGS       ReturnReg;\r
+  EXTENDED_SAL_PROC     EsalProc;\r
+\r
+  //\r
+  // Get the entrypoint of Extended SAL\r
+  //\r
+  ReturnReg = GetEsalEntryPoint ();\r
+  if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) {\r
+    //\r
+    // The ESAL Entry Point could not be initialized\r
+    //\r
+    ReturnReg.Status = EFI_SAL_ERROR;\r
+    return ReturnReg;\r
+  }\r
+\r
+  //\r
+  // Test PSR.it which is BIT36\r
+  //\r
+  if ((ReturnReg.r11 & BIT36) != 0) {\r
+    //\r
+    // Virtual mode plabel to entry point\r
+    //\r
+    EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r10;\r
+  } else {\r
+    //\r
+    // Physical mode plabel to entry point\r
+    //\r
+    EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r9;\r
+  }\r
+\r
+  return EsalProc (\r
+           ClassGuidLo,\r
+           ClassGuidHi,\r
+           FunctionId,\r
+           Arg2,\r
+           Arg3,\r
+           Arg4,\r
+           Arg5,\r
+           Arg6,\r
+           Arg7,\r
+           Arg8\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalStallFunctionId service of Extended SAL Stall Services Class.\r
+  \r
+  This function is a wrapper for the EsalStallFunctionId service of Extended SAL\r
+  Stall Services Class. See EsalStallFunctionId of Extended SAL Specification.\r
+\r
+  @param  Microseconds                  The number of microseconds to delay.\r
+\r
+  @retval EFI_SAL_SUCCESS               Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT      Invalid argument.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR Virtual address not registered\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalStall (\r
+  IN UINTN  Microseconds\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_LO, \r
+           EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_HI, \r
+           StallFunctionId, \r
+           Microseconds, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.\r
+  \r
+  This function is a wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL\r
+  PAL Services Services Class. See EsalSetNewPalEntryFunctionId of Extended SAL Specification.\r
+\r
+  @param  PhysicalAddress                If TRUE, then PalEntryPoint is a physical address.\r
+                                         If FALSE, then PalEntryPoint is a virtual address.\r
+  @param  PalEntryPoint                  The PAL Entry Point being set.\r
+\r
+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was set.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before\r
+                                         virtual mappings for the specified Extended SAL\r
+                                         Procedure are available.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSetNewPalEntry (\r
+  IN BOOLEAN  PhysicalAddress,\r
+  IN UINT64   PalEntryPoint\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO, \r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,\r
+           SetNewPalEntryFunctionId, \r
+           PhysicalAddress, \r
+           PalEntryPoint, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL\r
+  PAL Services Services Class. See EsalGetNewPalEntryFunctionId of Extended SAL Specification.\r
+\r
+  @param  PhysicalAddress                If TRUE, then PalEntryPoint is a physical address.\r
+                                         If FALSE, then PalEntryPoint is a virtual address.\r
+\r
+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was retrieved and returned in\r
+                                         SAL_RETURN_REGS.r9.\r
+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before\r
+                                         virtual mappings for the specified Extended SAL\r
+                                         Procedure are available.\r
+  @return r9                             PAL entry point retrieved.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetNewPalEntry (\r
+  IN BOOLEAN  PhysicalAddress\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,\r
+           GetNewPalEntryFunctionId, \r
+           PhysicalAddress, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetStateBufferFunctionId service of Extended SAL MCA Log Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetStateBufferFunctionId service of Extended SAL\r
+  MCA Log Services Class. See EsalGetStateBufferFunctionId of Extended SAL Specification.\r
+\r
+  @param  McaType               See type parameter of SAL Procedure SAL_GET_STATE_INFO.\r
+  @param  McaBuffer             A pointer to the base address of the returned buffer.\r
+                                Copied from SAL_RETURN_REGS.r9.\r
+  @param  BufferSize            A pointer to the size, in bytes, of the returned buffer.\r
+                                Copied from SAL_RETURN_REGS.r10.\r
+\r
+  @retval EFI_SAL_SUCCESS       The memory buffer to store error records was returned in r9 and r10.\r
+  @retval EFI_OUT_OF_RESOURCES  A memory buffer for string error records in not available\r
+  @return r9                    Base address of the returned buffer\r
+  @return r10                   Size of the returned buffer in bytes\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetStateBuffer (\r
+  IN  UINT64  McaType,\r
+  OUT UINT8   **McaBuffer,\r
+  OUT UINTN   *BufferSize\r
+  )\r
+{\r
+  SAL_RETURN_REGS Regs;\r
+\r
+  Regs = EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalGetStateBufferFunctionId, \r
+           McaType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+\r
+  *McaBuffer  = (UINT8 *) Regs.r9;\r
+  *BufferSize = Regs.r10;\r
+\r
+  return Regs;\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL MCA Log Services Class.\r
+  \r
+  This function is a wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL\r
+  MCA Log Services Class. See EsalSaveStateBufferFunctionId of Extended SAL Specification.\r
+\r
+  @param  McaType      See type parameter of SAL Procedure SAL_GET_STATE_INFO.\r
+\r
+  @retval EFI_SUCCESS  The memory buffer containing the error record was written to nonvolatile storage.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSaveStateBuffer (\r
+  IN  UINT64  McaType\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalSaveStateBufferFunctionId, \r
+           McaType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetVectorsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetVectorsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalGetVectorsFunctionId of Extended SAL Specification.\r
+\r
+  @param  VectorType               The vector type to retrieve.\r
+                                   0 - MCA, 1 - BSP INIT, 2 - BOOT_RENDEZ, 3 - AP INIT.\r
+\r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_SET_VECTORS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetVectors (\r
+  IN  UINT64  VectorType\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalGetVectorsFunctionId, \r
+           VectorType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.\r
+\r
+  @param  ParamInfoType            The parameter type to retrieve.\r
+                                   1 - rendezvous interrupt\r
+                                   2 - wake up\r
+                                   3 - Corrected Platform Error Vector.\r
+\r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_MC_SET_PARAMS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcGetParams (\r
+  IN  UINT64  ParamInfoType\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalMcGetParamsFunctionId, \r
+           ParamInfoType, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.\r
+\r
+  @retval EFI_SAL_SUCCESS          Call completed without error.\r
+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered\r
+                                   with the SAL Procedure SAL_MC_SET_PARAMS.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcGetMcParams (\r
+  VOID\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalMcGetMcParamsFunctionId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL Base Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL\r
+  Base Services Class. See EsalGetMcCheckinFlagsFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuIndex         The index of the CPU of set of enabled CPUs to check.\r
+\r
+  @retval EFI_SAL_SUCCESS  The checkin status of the requested CPU was returned.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetMcCheckinFlags (\r
+  IN  UINT64  CpuIndex\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,\r
+           EsalGetMcCheckinFlagsFunctionId, \r
+           CpuIndex, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalAddCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalAddCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalAddCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId                 The Global ID for the CPU being added.\r
+  @param  Enabled                     The enable flag for the CPU being added.\r
+                                      TRUE means the CPU is enabled.\r
+                                      FALSE means the CPU is disabled.\r
+  @param  PalCompatibility            The PAL Compatibility value for the CPU being added.\r
+\r
+  @retval EFI_SAL_SUCCESS             The CPU was added to the database.\r
+  @retval EFI_SAL_NOT_ENOUGH_SCRATCH  There are not enough resource available to add the CPU.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalAddCpuData (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  Enabled,\r
+  IN UINT64   PalCompatibility\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           AddCpuDataFunctionId, \r
+           CpuGlobalId, \r
+           Enabled, \r
+           PalCompatibility, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalRemoveCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId             The Global ID for the CPU being removed.\r
+\r
+  @retval EFI_SAL_SUCCESS         The CPU was removed from the database.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalRemoveCpuData (\r
+  IN UINT64  CpuGlobalId\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           RemoveCpuDataFunctionId, \r
+           CpuGlobalId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL\r
+  MP Services Class. See EsalModifyCpuDataFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId             The Global ID for the CPU being modified.\r
+  @param  Enabled                 The enable flag for the CPU being modified.\r
+                                  TRUE means the CPU is enabled.\r
+                                  FALSE means the CPU is disabled.\r
+  @param  PalCompatibility        The PAL Compatibility value for the CPU being modified.\r
+\r
+  @retval EFI_SAL_SUCCESS         The CPU database was updated.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalModifyCpuData (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  Enabled,\r
+  IN UINT64   PalCompatibility\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           ModifyCpuDataFunctionId, \r
+           CpuGlobalId, \r
+           Enabled, \r
+           PalCompatibility, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetCpuDataByIdFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId             The Global ID for the CPU being looked up.\r
+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                                  If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetCpuDataById (\r
+  IN UINT64   CpuGlobalId,\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           GetCpuDataByIDFunctionId, \r
+           CpuGlobalId, \r
+           IndexByEnabledCpu, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetCpuDataByIndexFunctionId of Extended SAL Specification.\r
+\r
+  @param  Index                   The Global ID for the CPU being modified.\r
+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                                  If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetCpuDataByIndex (\r
+  IN UINT64   Index,\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           GetCpuDataByIndexFunctionId, \r
+           Index, \r
+           IndexByEnabledCpu, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalWhoAmIFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalWhoAmIFunctionId service of Extended SAL\r
+  MP Services Class. See EsalWhoAmIFunctionId of Extended SAL Specification.\r
+\r
+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.\r
+                                  If FALSE, then the index of set of all CPUs of database is returned.\r
+\r
+  @retval EFI_SAL_SUCCESS         The Global ID for the calling CPU was returned.\r
+  @retval EFI_SAL_NO_INFORMATION  The calling CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalWhoAmI (\r
+  IN BOOLEAN  IndexByEnabledCpu\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           CurrentProcInfoFunctionId, \r
+           IndexByEnabledCpu, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalNumProcessors service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalNumProcessors service of Extended SAL\r
+  MP Services Class. See EsalNumProcessors of Extended SAL Specification.\r
+\r
+  @retval EFI_SAL_SUCCESS    The information on the number of CPUs in the platform\r
+                             was returned.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalNumProcessors (\r
+  VOID\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           NumProcessorsFunctionId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalSetMinStateFnctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalSetMinStateFnctionId service of Extended SAL\r
+  MP Services Class. See EsalSetMinStateFnctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId              The Global ID for the CPU whose MINSTATE pointer is being set.\r
+  @param  MinStatePointer          The physical address of the MINSTATE buffer for the CPU\r
+                                   specified by CpuGlobalId.\r
+\r
+  @retval EFI_SAL_SUCCESS          The MINSTATE pointer was set for the specified CPU.\r
+  @retval EFI_SAL_NO_INFORMATION   The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalSetMinState (\r
+  IN UINT64                CpuGlobalId,\r
+  IN EFI_PHYSICAL_ADDRESS  MinStatePointer\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           SetMinStateFunctionId, \r
+           CpuGlobalId, \r
+           MinStatePointer, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalGetMinStateFunctionId service of Extended SAL MP Services Class.\r
+  \r
+  This function is a wrapper for the EsalGetMinStateFunctionId service of Extended SAL\r
+  MP Services Class. See EsalGetMinStateFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId            The Global ID for the CPU whose MINSTATE pointer is being retrieved.\r
+\r
+  @retval EFI_SAL_SUCCESS        The MINSTATE pointer for the specified CPU was retrieved.\r
+  @retval EFI_SAL_NO_INFORMATION The specified CPU is not in the database.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalGetMinState (\r
+  IN UINT64  CpuGlobalId\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,\r
+           GetMinStateFunctionId, \r
+           CpuGlobalId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL MCA Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL\r
+  MCA Services Class. See EsalMcsGetStateInfoFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId               The Global ID for the CPU whose MCA state buffer is being retrieved.\r
+  @param  StateBufferPointer        A pointer to the returned MCA state buffer.\r
+  @param  RequiredStateBufferSize   A pointer to the size, in bytes, of the returned MCA state buffer.\r
+\r
+  @retval EFI_SUCCESS               MINSTATE successfully got and size calculated.\r
+  @retval EFI_SAL_NO_INFORMATION    Fail to get MINSTATE.\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcaGetStateInfo (\r
+  IN  UINT64                CpuGlobalId,\r
+  OUT EFI_PHYSICAL_ADDRESS  *StateBufferPointer,\r
+  OUT UINT64                *RequiredStateBufferSize\r
+  )\r
+{\r
+  SAL_RETURN_REGS  Regs;\r
+\r
+  Regs = EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,\r
+           McaGetStateInfoFunctionId, \r
+           CpuGlobalId, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+\r
+  *StateBufferPointer      = (EFI_PHYSICAL_ADDRESS) Regs.r9;\r
+  *RequiredStateBufferSize = (UINT64) Regs.r10;\r
+\r
+  return Regs;\r
+}\r
+\r
+/**\r
+  Wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL MCA Services Class.\r
+  \r
+  This function is a wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL\r
+  MCA Services Class. See EsalMcaRegisterCpuFunctionId of Extended SAL Specification.\r
+\r
+  @param  CpuGlobalId              The Global ID for the CPU whose MCA state buffer is being set.\r
+  @param  StateBufferPointer       A pointer to the MCA state buffer.\r
+\r
+  @retval EFI_SAL_NO_INFORMATION   Cannot get the processor info with the CpuId\r
+  @retval EFI_SUCCESS              Save the processor's state info successfully\r
+\r
+**/\r
+SAL_RETURN_REGS\r
+EFIAPI\r
+EsalMcaRegisterCpu (\r
+  IN UINT64                CpuGlobalId,\r
+  IN EFI_PHYSICAL_ADDRESS  StateBufferPointer\r
+  )\r
+{\r
+  return EsalCall (\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,\r
+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,\r
+           McaRegisterCpuFunctionId, \r
+           CpuGlobalId, \r
+           StateBufferPointer, \r
+           0, \r
+           0, \r
+           0, \r
+           0, \r
+           0\r
+           );\r
+}\r