3 Copyright (c) 2004 - 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 #include <Ipf/IpfDefines.h>
23 #include "EdkIIGlueDxe.h"
25 EXTENDED_SAL_BOOT_SERVICE_PROTOCOL
*mEsalBootService
= NULL
;
37 if (mEsalBootService
!= NULL
) {
42 // The protocol contains a function pointer, which is an indirect procedure call.
43 // An indirect procedure call goes through a plabel, and pointer to a function is
44 // a pointer to a plabel. To implement indirect procedure calls that can work in
45 // both physical and virtual mode, two plabels are required (one physical and one
46 // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it
47 // away. We cache it in a module global, so we can register the vitrual version.
49 Status
= gBS
->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid
, NULL
, &mEsalBootService
);
50 if (EFI_ERROR (Status
)) {
51 mEsalBootService
= NULL
;
55 Plabel
= (EFI_PLABEL
*) (UINTN
) mEsalBootService
->ExtendedSalProc
;
57 mPlabel
.EntryPoint
= Plabel
->EntryPoint
;
58 mPlabel
.GP
= Plabel
->GP
;
59 SetEsalPhysicalEntryPoint (mPlabel
.EntryPoint
, mPlabel
.GP
);
66 DxeSalLibConstructor (
67 IN EFI_HANDLE ImageHandle
,
68 IN EFI_SYSTEM_TABLE
*SystemTable
71 return DxeSalLibInitialize ();
76 DxeSalVirtualNotifyEvent (
84 Fixup virtual address pointer of label.
88 Event - The Event that is being processed
90 Context - Event Context
98 EfiConvertPointer (0x0, (VOID
**) &mPlabel
.EntryPoint
);
99 EfiConvertPointer (EFI_IPF_GP_POINTER
, (VOID
**) &mPlabel
.GP
);
101 SetEsalVirtualEntryPoint (mPlabel
.EntryPoint
, mPlabel
.GP
);
106 RegisterEsalFunction (
107 IN UINT64 FunctionId
,
108 IN EFI_GUID
*ClassGuid
,
109 IN SAL_INTERNAL_EXTENDED_SAL_PROC Function
,
110 IN VOID
*ModuleGlobal
116 Register ESAL Class Function and it's asociated global.
117 This function is boot service only!
120 FunctionId - ID of function to register
121 ClassGuid - GUID of function class
122 Function - Function to register under ClassGuid/FunctionId pair
123 ModuleGlobal - Module global for Function.
126 EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.
130 DxeSalLibInitialize ();
131 return mEsalBootService
->AddExtendedSalProc (
143 IN EFI_GUID
*ClassGuid
,
144 IN VOID
*ModuleGlobal
,
151 Register ESAL Class and it's asociated global.
152 This function is boot service only!
155 ClassGuid - GUID of function class
156 ModuleGlobal - Module global for Function.
157 ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL
158 indicates the end of the list.
161 EFI_SUCCESS - All members of ClassGuid registered
167 SAL_INTERNAL_EXTENDED_SAL_PROC Function
;
169 EFI_HANDLE NewHandle
;
171 VA_START (Args
, ModuleGlobal
);
173 Status
= EFI_SUCCESS
;
174 while (!EFI_ERROR (Status
)) {
175 Function
= (SAL_INTERNAL_EXTENDED_SAL_PROC
) VA_ARG (Args
, SAL_INTERNAL_EXTENDED_SAL_PROC
);
176 if (Function
== NULL
) {
180 FunctionId
= VA_ARG (Args
, UINT64
);
182 Status
= RegisterEsalFunction (FunctionId
, ClassGuid
, Function
, ModuleGlobal
);
185 if (EFI_ERROR (Status
)) {
190 return gBS
->InstallProtocolInterface (
193 EFI_NATIVE_INTERFACE
,
201 IN EFI_GUID
*ClassGuid
,
202 IN UINT64 FunctionId
,
215 Call module that is not linked direclty to this module. This code is IP
216 relative and hides the binding issues of virtual or physical calling. The
217 function that gets dispatched has extra arguments that include the registered
218 module global and a boolean flag to indicate if the system is in virutal mode.
221 ClassGuid - GUID of function
222 FunctionId - Function in ClassGuid to call
223 Arg2 - Argument 2 ClassGuid/FunctionId defined
224 Arg3 - Argument 3 ClassGuid/FunctionId defined
225 Arg4 - Argument 4 ClassGuid/FunctionId defined
226 Arg5 - Argument 5 ClassGuid/FunctionId defined
227 Arg6 - Argument 6 ClassGuid/FunctionId defined
228 Arg7 - Argument 7 ClassGuid/FunctionId defined
229 Arg8 - Argument 8 ClassGuid/FunctionId defined
232 Status of ClassGuid/FuncitonId
236 SAL_RETURN_REGS ReturnReg
;
237 SAL_EXTENDED_SAL_PROC EsalProc
;
239 ReturnReg
= GetEsalEntryPoint ();
240 if (ReturnReg
.Status
!= EFI_SAL_SUCCESS
) {
245 // Look at the physical mode ESAL entry point to determine of the ESAL entry point has been initialized
247 if (*(UINT64
*)ReturnReg
.r9
== 0 && *(UINT64
*)(ReturnReg
.r9
+ 8) == 0) {
249 // Both the function ponter and the GP value are zero, so attempt to initialize the ESAL Entry Point
251 DxeSalLibInitialize ();
252 ReturnReg
= GetEsalEntryPoint ();
253 if (ReturnReg
.Status
!= EFI_SAL_SUCCESS
) {
256 if (*(UINT64
*)ReturnReg
.r9
== 0 && *(UINT64
*)(ReturnReg
.r9
+ 8) == 0) {
258 // The ESAL Entry Point could not be initialized
260 ReturnReg
.Status
= EFI_SAL_ERROR
;
265 if (ReturnReg
.r11
& PSR_IT_MASK
) {
267 // Virtual mode plabel to entry point
269 EsalProc
= (SAL_EXTENDED_SAL_PROC
) ReturnReg
.r10
;
272 // Physical mode plabel to entry point
274 EsalProc
= (SAL_EXTENDED_SAL_PROC
) ReturnReg
.r9
;