3 Copyright (c) 2004 - 2006, Intel Corporation. All rights reserved.<BR>
4 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
;
38 if (mEsalBootService
!= NULL
) {
43 // The protocol contains a function pointer, which is an indirect procedure call.
44 // An indirect procedure call goes through a plabel, and pointer to a function is
45 // a pointer to a plabel. To implement indirect procedure calls that can work in
46 // both physical and virtual mode, two plabels are required (one physical and one
47 // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it
48 // away. We cache it in a module global, so we can register the vitrual version.
50 Status
= gBS
->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid
, NULL
, (VOID
**) &mEsalBootService
);
51 if (EFI_ERROR (Status
)) {
52 mEsalBootService
= NULL
;
56 Plabel
= (EFI_PLABEL
*) (UINTN
) mEsalBootService
->ExtendedSalProc
;
58 mPlabel
.EntryPoint
= Plabel
->EntryPoint
;
59 mPlabel
.GP
= Plabel
->GP
;
60 SetEsalPhysicalEntryPoint (mPlabel
.EntryPoint
, mPlabel
.GP
);
67 RegisterEsalFunction (
69 IN EFI_GUID
*ClassGuid
,
70 IN SAL_INTERNAL_EXTENDED_SAL_PROC Function
,
77 Register ESAL Class Function and it's asociated global.
78 This function is boot service only!
81 FunctionId - ID of function to register
82 ClassGuid - GUID of function class
83 Function - Function to register under ClassGuid/FunctionId pair
84 ModuleGlobal - Module global for Function.
87 EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.
91 DxeSalLibInitialize ();
92 return mEsalBootService
->AddExtendedSalProc (
104 IN EFI_GUID
*ClassGuid
,
105 IN VOID
*ModuleGlobal
,
112 Register ESAL Class and it's asociated global.
113 This function is boot service only!
116 ClassGuid - GUID of function class
117 ModuleGlobal - Module global for Function.
118 ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL
119 indicates the end of the list.
122 EFI_SUCCESS - All members of ClassGuid registered
128 SAL_INTERNAL_EXTENDED_SAL_PROC Function
;
130 EFI_HANDLE NewHandle
;
132 VA_START (Args
, ModuleGlobal
);
134 Status
= EFI_SUCCESS
;
135 while (!EFI_ERROR (Status
)) {
136 Function
= (SAL_INTERNAL_EXTENDED_SAL_PROC
) VA_ARG (Args
, SAL_INTERNAL_EXTENDED_SAL_PROC
);
137 if (Function
== NULL
) {
141 FunctionId
= VA_ARG (Args
, UINT64
);
143 Status
= RegisterEsalFunction (FunctionId
, ClassGuid
, Function
, ModuleGlobal
);
146 if (EFI_ERROR (Status
)) {
151 return gBS
->InstallProtocolInterface (
154 EFI_NATIVE_INTERFACE
,
162 IN EFI_GUID
*ClassGuid
,
163 IN UINT64 FunctionId
,
176 Call module that is not linked direclty to this module. This code is IP
177 relative and hides the binding issues of virtual or physical calling. The
178 function that gets dispatched has extra arguments that include the registered
179 module global and a boolean flag to indicate if the system is in virutal mode.
182 ClassGuid - GUID of function
183 FunctionId - Function in ClassGuid to call
184 Arg2 - Argument 2 ClassGuid/FunctionId defined
185 Arg3 - Argument 3 ClassGuid/FunctionId defined
186 Arg4 - Argument 4 ClassGuid/FunctionId defined
187 Arg5 - Argument 5 ClassGuid/FunctionId defined
188 Arg6 - Argument 6 ClassGuid/FunctionId defined
189 Arg7 - Argument 7 ClassGuid/FunctionId defined
190 Arg8 - Argument 8 ClassGuid/FunctionId defined
193 Status of ClassGuid/FuncitonId
197 SAL_RETURN_REGS ReturnReg
;
198 SAL_EXTENDED_SAL_PROC EsalProc
;
200 ReturnReg
= GetEsalEntryPoint ();
201 if (ReturnReg
.Status
!= EFI_SAL_SUCCESS
) {
206 // Look at the physical mode ESAL entry point to determine of the ESAL entry point has been initialized
208 if (*(UINT64
*)ReturnReg
.r9
== 0 && *(UINT64
*)(ReturnReg
.r9
+ 8) == 0) {
210 // Both the function ponter and the GP value are zero, so attempt to initialize the ESAL Entry Point
212 DxeSalLibInitialize ();
213 ReturnReg
= GetEsalEntryPoint ();
214 if (ReturnReg
.Status
!= EFI_SAL_SUCCESS
) {
217 if (*(UINT64
*)ReturnReg
.r9
== 0 && *(UINT64
*)(ReturnReg
.r9
+ 8) == 0) {
219 // The ESAL Entry Point could not be initialized
221 ReturnReg
.Status
= EFI_SAL_ERROR
;
226 if (ReturnReg
.r11
& PSR_IT_MASK
) {
228 // Virtual mode plabel to entry point
230 EsalProc
= (SAL_EXTENDED_SAL_PROC
) ReturnReg
.r10
;
233 // Physical mode plabel to entry point
235 EsalProc
= (SAL_EXTENDED_SAL_PROC
) ReturnReg
.r9
;