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 UINT64 PhysicalEntryPoint
;
88 PhysicalEntryPoint
= mPlabel
.EntryPoint
;
90 EfiConvertPointer (0x0, (VOID
**) &mPlabel
.EntryPoint
);
91 mPlabel
.GP
+= mPlabel
.EntryPoint
- PhysicalEntryPoint
;
93 SetEsalVirtualEntryPoint (mPlabel
.EntryPoint
, mPlabel
.GP
);
98 RegisterEsalFunction (
100 IN EFI_GUID
*ClassGuid
,
101 IN SAL_INTERNAL_EXTENDED_SAL_PROC Function
,
102 IN VOID
*ModuleGlobal
108 Register ESAL Class Function and it's asociated global.
109 This function is boot service only!
112 FunctionId - ID of function to register
113 ClassGuid - GUID of function class
114 Function - Function to register under ClassGuid/FunctionId pair
115 ModuleGlobal - Module global for Function.
118 EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.
122 DxeSalLibInitialize ();
123 return mEsalBootService
->AddExtendedSalProc (
135 IN EFI_GUID
*ClassGuid
,
136 IN VOID
*ModuleGlobal
,
143 Register ESAL Class and it's asociated global.
144 This function is boot service only!
147 ClassGuid - GUID of function class
148 ModuleGlobal - Module global for Function.
149 ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL
150 indicates the end of the list.
153 EFI_SUCCESS - All members of ClassGuid registered
159 SAL_INTERNAL_EXTENDED_SAL_PROC Function
;
161 EFI_HANDLE NewHandle
;
163 VA_START (Args
, ModuleGlobal
);
165 Status
= EFI_SUCCESS
;
166 while (!EFI_ERROR (Status
)) {
167 Function
= (SAL_INTERNAL_EXTENDED_SAL_PROC
) VA_ARG (Args
, SAL_INTERNAL_EXTENDED_SAL_PROC
);
168 if (Function
== NULL
) {
172 FunctionId
= VA_ARG (Args
, UINT64
);
174 Status
= RegisterEsalFunction (FunctionId
, ClassGuid
, Function
, ModuleGlobal
);
177 if (EFI_ERROR (Status
)) {
182 return gBS
->InstallProtocolInterface (
185 EFI_NATIVE_INTERFACE
,
193 IN EFI_GUID
*ClassGuid
,
194 IN UINT64 FunctionId
,
207 Call module that is not linked direclty to this module. This code is IP
208 relative and hides the binding issues of virtual or physical calling. The
209 function that gets dispatched has extra arguments that include the registered
210 module global and a boolean flag to indicate if the system is in virutal mode.
213 ClassGuid - GUID of function
214 FunctionId - Function in ClassGuid to call
215 Arg2 - Argument 2 ClassGuid/FunctionId defined
216 Arg3 - Argument 3 ClassGuid/FunctionId defined
217 Arg4 - Argument 4 ClassGuid/FunctionId defined
218 Arg5 - Argument 5 ClassGuid/FunctionId defined
219 Arg6 - Argument 6 ClassGuid/FunctionId defined
220 Arg7 - Argument 7 ClassGuid/FunctionId defined
221 Arg8 - Argument 8 ClassGuid/FunctionId defined
224 Status of ClassGuid/FuncitonId
228 SAL_RETURN_REGS ReturnReg
;
229 SAL_EXTENDED_SAL_PROC EsalProc
;
231 ReturnReg
= GetEsalEntryPoint ();
232 if (ReturnReg
.Status
!= EFI_SAL_SUCCESS
) {
237 // Look at the physical mode ESAL entry point to determine of the ESAL entry point has been initialized
239 if (*(UINT64
*)ReturnReg
.r9
== 0 && *(UINT64
*)(ReturnReg
.r9
+ 8) == 0) {
241 // Both the function ponter and the GP value are zero, so attempt to initialize the ESAL Entry Point
243 DxeSalLibInitialize ();
244 ReturnReg
= GetEsalEntryPoint ();
245 if (ReturnReg
.Status
!= EFI_SAL_SUCCESS
) {
248 if (*(UINT64
*)ReturnReg
.r9
== 0 && *(UINT64
*)(ReturnReg
.r9
+ 8) == 0) {
250 // The ESAL Entry Point could not be initialized
252 ReturnReg
.Status
= EFI_SAL_ERROR
;
257 if (ReturnReg
.r11
& PSR_IT_MASK
) {
259 // Virtual mode plabel to entry point
261 EsalProc
= (SAL_EXTENDED_SAL_PROC
) ReturnReg
.r10
;
264 // Physical mode plabel to entry point
266 EsalProc
= (SAL_EXTENDED_SAL_PROC
) ReturnReg
.r9
;