+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation\r
-All rights reserved. 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
-Module Name:\r
-\r
- EsalServiceLib.c\r
-\r
-Abstract:\r
-\r
---*/\r
-\r
-#include <Ipf/IpfDefines.h>\r
-\r
-EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService = NULL;\r
-EFI_PLABEL mPlabel;\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-DxeSalLibInitialize (\r
- VOID\r
- )\r
-{\r
- EFI_PLABEL *Plabel;\r
- EFI_STATUS Status;\r
-\r
- if (mEsalBootService != NULL) {\r
- return EFI_SUCCESS;\r
- }\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
- if (EFI_ERROR (Status)) {\r
- mEsalBootService = NULL;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Plabel = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;\r
-\r
- mPlabel.EntryPoint = Plabel->EntryPoint;\r
- mPlabel.GP = Plabel->GP;\r
- SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RegisterEsalFunction (\r
- IN UINT64 FunctionId,\r
- IN EFI_GUID *ClassGuid,\r
- IN SAL_INTERNAL_EXTENDED_SAL_PROC Function,\r
- IN VOID *ModuleGlobal\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Register ESAL Class Function and it's asociated global.\r
- This function is boot service only!\r
-\r
-Arguments:\r
- FunctionId - ID of function to register\r
- ClassGuid - GUID of function class\r
- Function - Function to register under ClassGuid/FunctionId pair\r
- ModuleGlobal - Module global for Function.\r
-\r
-Returns:\r
- EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.\r
-\r
---*/\r
-{\r
- DxeSalLibInitialize ();\r
- return mEsalBootService->AddExtendedSalProc (\r
- mEsalBootService,\r
- ClassGuid,\r
- FunctionId,\r
- Function,\r
- ModuleGlobal\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RegisterEsalClass (\r
- IN EFI_GUID *ClassGuid,\r
- IN VOID *ModuleGlobal,\r
- ...\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Register ESAL Class and it's asociated global.\r
- This function is boot service only!\r
-\r
-Arguments:\r
- ClassGuid - GUID of function class\r
- ModuleGlobal - Module global for Function.\r
- ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL\r
- indicates the end of the list.\r
-\r
-Returns:\r
- EFI_SUCCESS - All members of ClassGuid registered\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
-\r
- VA_START (Args, ModuleGlobal);\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
- if (Function == NULL) {\r
- break;\r
- }\r
-\r
- FunctionId = VA_ARG (Args, UINT64);\r
-\r
- Status = RegisterEsalFunction (FunctionId, ClassGuid, Function, ModuleGlobal);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- NewHandle = NULL;\r
- return gBS->InstallProtocolInterface (\r
- &NewHandle,\r
- ClassGuid,\r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
-}\r
-\r
-SAL_RETURN_REGS\r
-EFIAPI\r
-EfiCallEsalService (\r
- IN EFI_GUID *ClassGuid,\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
-\r
-Routine Description:\r
-\r
- Call module that is not linked direclty to this module. This code is IP\r
- relative and hides the binding issues of virtual or physical calling. The\r
- function that gets dispatched has extra arguments that include the registered\r
- module global and a boolean flag to indicate if the system is in virutal mode.\r
-\r
-Arguments:\r
- ClassGuid - GUID of function\r
- FunctionId - Function in ClassGuid to call\r
- Arg2 - Argument 2 ClassGuid/FunctionId defined\r
- Arg3 - Argument 3 ClassGuid/FunctionId defined\r
- Arg4 - Argument 4 ClassGuid/FunctionId defined\r
- Arg5 - Argument 5 ClassGuid/FunctionId defined\r
- Arg6 - Argument 6 ClassGuid/FunctionId defined\r
- Arg7 - Argument 7 ClassGuid/FunctionId defined\r
- Arg8 - Argument 8 ClassGuid/FunctionId defined\r
-\r
-Returns:\r
- Status of ClassGuid/FuncitonId\r
-\r
---*/\r
-{\r
- SAL_RETURN_REGS ReturnReg;\r
- SAL_EXTENDED_SAL_PROC EsalProc;\r
-\r
- ReturnReg = GetEsalEntryPoint ();\r
- if (ReturnReg.Status != EFI_SAL_SUCCESS) {\r
- return ReturnReg;\r
- }\r
-\r
- //\r
- // Look at the physical mode ESAL entry point to determine of the ESAL entry point has been initialized\r
- //\r
- if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) {\r
- //\r
- // Both the function ponter and the GP value are zero, so attempt to initialize the ESAL Entry Point\r
- //\r
- DxeSalLibInitialize ();\r
- ReturnReg = GetEsalEntryPoint ();\r
- if (ReturnReg.Status != EFI_SAL_SUCCESS) {\r
- return ReturnReg;\r
- }\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
- if (ReturnReg.r11 & PSR_IT_MASK) {\r
- //\r
- // Virtual mode plabel to entry point\r
- //\r
- EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r10;\r
- } else {\r
- //\r
- // Physical mode plabel to entry point\r
- //\r
- EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r9;\r
- }\r
-\r
- return EsalProc (\r
- ClassGuid,\r
- FunctionId,\r
- Arg2,\r
- Arg3,\r
- Arg4,\r
- Arg5,\r
- Arg6,\r
- Arg7,\r
- Arg8\r
- );\r
-}\r