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
;
34 if (mEsalBootService
!= NULL
) {
39 // The protocol contains a function pointer, which is an indirect procedure call.
40 // An indirect procedure call goes through a plabel, and pointer to a function is
41 // a pointer to a plabel. To implement indirect procedure calls that can work in
42 // both physical and virtual mode, two plabels are required (one physical and one
43 // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it
44 // away. We cache it in a module global, so we can register the vitrual version.
46 Status
= gBS
->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid
, NULL
, &mEsalBootService
);
47 if (EFI_ERROR (Status
)) {
48 mEsalBootService
= NULL
;
52 Plabel
= (EFI_PLABEL
*) (UINTN
) mEsalBootService
->ExtendedSalProc
;
54 mPlabel
.EntryPoint
= Plabel
->EntryPoint
;
55 mPlabel
.GP
= Plabel
->GP
;
56 SetEsalPhysicalEntryPoint (mPlabel
.EntryPoint
, mPlabel
.GP
);
63 DxeSalLibConstructor (
64 IN EFI_HANDLE ImageHandle
,
65 IN EFI_SYSTEM_TABLE
*SystemTable
68 return DxeSalLibInitialize ();
73 DxeSalVirtualNotifyEvent (
81 Fixup virtual address pointer of label.
85 Event - The Event that is being processed
87 Context - Event Context
95 EfiConvertPointer (0x0, (VOID
**) &mPlabel
.EntryPoint
);
96 EfiConvertPointer (EFI_IPF_GP_POINTER
, (VOID
**) &mPlabel
.GP
);
98 SetEsalVirtualEntryPoint (mPlabel
.EntryPoint
, mPlabel
.GP
);
103 RegisterEsalFunction (
104 IN UINT64 FunctionId
,
105 IN EFI_GUID
*ClassGuid
,
106 IN SAL_INTERNAL_EXTENDED_SAL_PROC Function
,
107 IN VOID
*ModuleGlobal
113 Register ESAL Class Function and it's asociated global.
114 This function is boot service only!
117 FunctionId - ID of function to register
118 ClassGuid - GUID of function class
119 Function - Function to register under ClassGuid/FunctionId pair
120 ModuleGlobal - Module global for Function.
123 EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.
127 DxeSalLibInitialize ();
128 return mEsalBootService
->AddExtendedSalProc (
140 IN EFI_GUID
*ClassGuid
,
141 IN VOID
*ModuleGlobal
,
148 Register ESAL Class and it's asociated global.
149 This function is boot service only!
152 ClassGuid - GUID of function class
153 ModuleGlobal - Module global for Function.
154 ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL
155 indicates the end of the list.
158 EFI_SUCCESS - All members of ClassGuid registered
164 SAL_INTERNAL_EXTENDED_SAL_PROC Function
;
166 EFI_HANDLE NewHandle
;
168 VA_START (Args
, ModuleGlobal
);
170 Status
= EFI_SUCCESS
;
171 while (!EFI_ERROR (Status
)) {
172 Function
= (SAL_INTERNAL_EXTENDED_SAL_PROC
) VA_ARG (Args
, SAL_INTERNAL_EXTENDED_SAL_PROC
);
173 if (Function
== NULL
) {
177 FunctionId
= VA_ARG (Args
, UINT64
);
179 Status
= RegisterEsalFunction (FunctionId
, ClassGuid
, Function
, ModuleGlobal
);
182 if (EFI_ERROR (Status
)) {
187 return gBS
->InstallProtocolInterface (
190 EFI_NATIVE_INTERFACE
,
198 IN EFI_GUID
*ClassGuid
,
199 IN UINT64 FunctionId
,
212 Call module that is not linked direclty to this module. This code is IP
213 relative and hides the binding issues of virtual or physical calling. The
214 function that gets dispatched has extra arguments that include the registered
215 module global and a boolean flag to indicate if the system is in virutal mode.
218 ClassGuid - GUID of function
219 FunctionId - Function in ClassGuid to call
220 Arg2 - Argument 2 ClassGuid/FunctionId defined
221 Arg3 - Argument 3 ClassGuid/FunctionId defined
222 Arg4 - Argument 4 ClassGuid/FunctionId defined
223 Arg5 - Argument 5 ClassGuid/FunctionId defined
224 Arg6 - Argument 6 ClassGuid/FunctionId defined
225 Arg7 - Argument 7 ClassGuid/FunctionId defined
226 Arg8 - Argument 8 ClassGuid/FunctionId defined
229 Status of ClassGuid/FuncitonId
233 SAL_RETURN_REGS ReturnReg
;
234 SAL_EXTENDED_SAL_PROC EsalProc
;
236 ReturnReg
= GetEsalEntryPoint ();
237 if (ReturnReg
.Status
!= EFI_SAL_SUCCESS
) {
242 // Look at the physical mode ESAL entry point to determine of the ESAL entry point has been initialized
244 if (*(UINT64
*)ReturnReg
.r9
== 0 && *(UINT64
*)(ReturnReg
.r9
+ 8) == 0) {
246 // Both the function ponter and the GP value are zero, so attempt to initialize the ESAL Entry Point
248 DxeSalLibInitialize ();
249 ReturnReg
= GetEsalEntryPoint ();
250 if (ReturnReg
.Status
!= EFI_SAL_SUCCESS
) {
253 if (*(UINT64
*)ReturnReg
.r9
== 0 && *(UINT64
*)(ReturnReg
.r9
+ 8) == 0) {
255 // The ESAL Entry Point could not be initialized
257 ReturnReg
.Status
= EFI_SAL_ERROR
;
262 if (ReturnReg
.r11
& PSR_IT_MASK
) {
264 // Virtual mode plabel to entry point
266 EsalProc
= (SAL_EXTENDED_SAL_PROC
) ReturnReg
.r10
;
269 // Physical mode plabel to entry point
271 EsalProc
= (SAL_EXTENDED_SAL_PROC
) ReturnReg
.r9
;