3 Copyright (c) 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.
20 #include <Ipf/IpfDefines.h>
22 EXTENDED_SAL_BOOT_SERVICE_PROTOCOL
*mEsalBootService
= NULL
;
35 if (mEsalBootService
!= NULL
) {
40 // The protocol contains a function pointer, which is an indirect procedure call.
41 // An indirect procedure call goes through a plabel, and pointer to a function is
42 // a pointer to a plabel. To implement indirect procedure calls that can work in
43 // both physical and virtual mode, two plabels are required (one physical and one
44 // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it
45 // away. We cache it in a module global, so we can register the vitrual version.
47 Status
= gBS
->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid
, NULL
, (VOID
**) &mEsalBootService
);
48 if (EFI_ERROR (Status
)) {
49 mEsalBootService
= NULL
;
53 Plabel
= (EFI_PLABEL
*) (UINTN
) mEsalBootService
->ExtendedSalProc
;
55 mPlabel
.EntryPoint
= Plabel
->EntryPoint
;
56 mPlabel
.GP
= Plabel
->GP
;
57 SetEsalPhysicalEntryPoint (mPlabel
.EntryPoint
, mPlabel
.GP
);
64 DxeSalVirtualNotifyEvent (
72 Fixup virtual address pointer of label.
76 Event - The Event that is being processed
78 Context - Event Context
86 EfiConvertPointer (0x0, (VOID
**) &mPlabel
.EntryPoint
);
87 EfiConvertPointer (EFI_IPF_GP_POINTER
, (VOID
**) &mPlabel
.GP
);
89 SetEsalVirtualEntryPoint (mPlabel
.EntryPoint
, mPlabel
.GP
);
94 RegisterEsalFunction (
96 IN EFI_GUID
*ClassGuid
,
97 IN SAL_INTERNAL_EXTENDED_SAL_PROC Function
,
104 Register ESAL Class Function and it's asociated global.
105 This function is boot service only!
108 FunctionId - ID of function to register
109 ClassGuid - GUID of function class
110 Function - Function to register under ClassGuid/FunctionId pair
111 ModuleGlobal - Module global for Function.
114 EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.
118 DxeSalLibInitialize ();
119 return mEsalBootService
->AddExtendedSalProc (
131 IN EFI_GUID
*ClassGuid
,
132 IN VOID
*ModuleGlobal
,
139 Register ESAL Class and it's asociated global.
140 This function is boot service only!
143 ClassGuid - GUID of function class
144 ModuleGlobal - Module global for Function.
145 ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL
146 indicates the end of the list.
149 EFI_SUCCESS - All members of ClassGuid registered
155 SAL_INTERNAL_EXTENDED_SAL_PROC Function
;
157 EFI_HANDLE NewHandle
;
159 VA_START (Args
, ModuleGlobal
);
161 Status
= EFI_SUCCESS
;
162 while (!EFI_ERROR (Status
)) {
163 Function
= (SAL_INTERNAL_EXTENDED_SAL_PROC
) VA_ARG (Args
, SAL_INTERNAL_EXTENDED_SAL_PROC
);
164 if (Function
== NULL
) {
168 FunctionId
= VA_ARG (Args
, UINT64
);
170 Status
= RegisterEsalFunction (FunctionId
, ClassGuid
, Function
, ModuleGlobal
);
173 if (EFI_ERROR (Status
)) {
178 return gBS
->InstallProtocolInterface (
181 EFI_NATIVE_INTERFACE
,
189 IN EFI_GUID
*ClassGuid
,
190 IN UINT64 FunctionId
,
203 Call module that is not linked direclty to this module. This code is IP
204 relative and hides the binding issues of virtual or physical calling. The
205 function that gets dispatched has extra arguments that include the registered
206 module global and a boolean flag to indicate if the system is in virutal mode.
209 ClassGuid - GUID of function
210 FunctionId - Function in ClassGuid to call
211 Arg2 - Argument 2 ClassGuid/FunctionId defined
212 Arg3 - Argument 3 ClassGuid/FunctionId defined
213 Arg4 - Argument 4 ClassGuid/FunctionId defined
214 Arg5 - Argument 5 ClassGuid/FunctionId defined
215 Arg6 - Argument 6 ClassGuid/FunctionId defined
216 Arg7 - Argument 7 ClassGuid/FunctionId defined
217 Arg8 - Argument 8 ClassGuid/FunctionId defined
220 Status of ClassGuid/FuncitonId
224 SAL_RETURN_REGS ReturnReg
;
225 SAL_EXTENDED_SAL_PROC EsalProc
;
227 ReturnReg
= GetEsalEntryPoint ();
228 if (ReturnReg
.Status
!= EFI_SAL_SUCCESS
) {
233 // Look at the physical mode ESAL entry point to determine of the ESAL entry point has been initialized
235 if (*(UINT64
*)ReturnReg
.r9
== 0 && *(UINT64
*)(ReturnReg
.r9
+ 8) == 0) {
237 // Both the function ponter and the GP value are zero, so attempt to initialize the ESAL Entry Point
239 DxeSalLibInitialize ();
240 ReturnReg
= GetEsalEntryPoint ();
241 if (ReturnReg
.Status
!= EFI_SAL_SUCCESS
) {
244 if (*(UINT64
*)ReturnReg
.r9
== 0 && *(UINT64
*)(ReturnReg
.r9
+ 8) == 0) {
246 // The ESAL Entry Point could not be initialized
248 ReturnReg
.Status
= EFI_SAL_ERROR
;
253 if (ReturnReg
.r11
& PSR_IT_MASK
) {
255 // Virtual mode plabel to entry point
257 EsalProc
= (SAL_EXTENDED_SAL_PROC
) ReturnReg
.r10
;
260 // Physical mode plabel to entry point
262 EsalProc
= (SAL_EXTENDED_SAL_PROC
) ReturnReg
.r9
;