]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Library/EdkDxeRuntimeSalLib/Ipf/EsalServiceLib.c
Removed the DxeSalLibConstructor() from the EdkDxeSalLib and EdkDxeRuntimeSalLib...
[mirror_edk2.git] / EdkModulePkg / Library / EdkDxeRuntimeSalLib / Ipf / EsalServiceLib.c
1 /*++
2
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
8
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.
11
12 Module Name:
13
14 EsalServiceLib.c
15
16 Abstract:
17
18 --*/
19
20 #include <Ipf/IpfDefines.h>
21
22 EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService = NULL;
23 EFI_PLABEL mPlabel;
24
25 EFI_STATUS
26 EFIAPI
27 DxeSalLibInitialize (
28 VOID
29 )
30 {
31 EFI_PLABEL *Plabel;
32 EFI_STATUS Status;
33
34 if (mEsalBootService != NULL) {
35 return EFI_SUCCESS;
36 }
37
38 //
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.
45 //
46 Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, &mEsalBootService);
47 if (EFI_ERROR (Status)) {
48 mEsalBootService = NULL;
49 return EFI_SUCCESS;
50 }
51
52 Plabel = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;
53
54 mPlabel.EntryPoint = Plabel->EntryPoint;
55 mPlabel.GP = Plabel->GP;
56 SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
57
58 return EFI_SUCCESS;
59 }
60
61 VOID
62 EFIAPI
63 DxeSalVirtualNotifyEvent (
64 IN EFI_EVENT Event,
65 IN VOID *Context
66 )
67 /*++
68
69 Routine Description:
70
71 Fixup virtual address pointer of label.
72
73 Arguments:
74
75 Event - The Event that is being processed
76
77 Context - Event Context
78
79 Returns:
80
81 None
82
83 --*/
84 {
85 EfiConvertPointer (0x0, (VOID **) &mPlabel.EntryPoint);
86 EfiConvertPointer (EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP);
87
88 SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
89 }
90
91 EFI_STATUS
92 EFIAPI
93 RegisterEsalFunction (
94 IN UINT64 FunctionId,
95 IN EFI_GUID *ClassGuid,
96 IN SAL_INTERNAL_EXTENDED_SAL_PROC Function,
97 IN VOID *ModuleGlobal
98 )
99 /*++
100
101 Routine Description:
102
103 Register ESAL Class Function and it's asociated global.
104 This function is boot service only!
105
106 Arguments:
107 FunctionId - ID of function to register
108 ClassGuid - GUID of function class
109 Function - Function to register under ClassGuid/FunctionId pair
110 ModuleGlobal - Module global for Function.
111
112 Returns:
113 EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.
114
115 --*/
116 {
117 DxeSalLibInitialize ();
118 return mEsalBootService->AddExtendedSalProc (
119 mEsalBootService,
120 ClassGuid,
121 FunctionId,
122 Function,
123 ModuleGlobal
124 );
125 }
126
127 EFI_STATUS
128 EFIAPI
129 RegisterEsalClass (
130 IN EFI_GUID *ClassGuid,
131 IN VOID *ModuleGlobal,
132 ...
133 )
134 /*++
135
136 Routine Description:
137
138 Register ESAL Class and it's asociated global.
139 This function is boot service only!
140
141 Arguments:
142 ClassGuid - GUID of function class
143 ModuleGlobal - Module global for Function.
144 ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL
145 indicates the end of the list.
146
147 Returns:
148 EFI_SUCCESS - All members of ClassGuid registered
149
150 --*/
151 {
152 VA_LIST Args;
153 EFI_STATUS Status;
154 SAL_INTERNAL_EXTENDED_SAL_PROC Function;
155 UINT64 FunctionId;
156 EFI_HANDLE NewHandle;
157
158 VA_START (Args, ModuleGlobal);
159
160 Status = EFI_SUCCESS;
161 while (!EFI_ERROR (Status)) {
162 Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);
163 if (Function == NULL) {
164 break;
165 }
166
167 FunctionId = VA_ARG (Args, UINT64);
168
169 Status = RegisterEsalFunction (FunctionId, ClassGuid, Function, ModuleGlobal);
170 }
171
172 if (EFI_ERROR (Status)) {
173 return Status;
174 }
175
176 NewHandle = NULL;
177 return gBS->InstallProtocolInterface (
178 &NewHandle,
179 ClassGuid,
180 EFI_NATIVE_INTERFACE,
181 NULL
182 );
183 }
184
185 SAL_RETURN_REGS
186 EFIAPI
187 EfiCallEsalService (
188 IN EFI_GUID *ClassGuid,
189 IN UINT64 FunctionId,
190 IN UINT64 Arg2,
191 IN UINT64 Arg3,
192 IN UINT64 Arg4,
193 IN UINT64 Arg5,
194 IN UINT64 Arg6,
195 IN UINT64 Arg7,
196 IN UINT64 Arg8
197 )
198 /*++
199
200 Routine Description:
201
202 Call module that is not linked direclty to this module. This code is IP
203 relative and hides the binding issues of virtual or physical calling. The
204 function that gets dispatched has extra arguments that include the registered
205 module global and a boolean flag to indicate if the system is in virutal mode.
206
207 Arguments:
208 ClassGuid - GUID of function
209 FunctionId - Function in ClassGuid to call
210 Arg2 - Argument 2 ClassGuid/FunctionId defined
211 Arg3 - Argument 3 ClassGuid/FunctionId defined
212 Arg4 - Argument 4 ClassGuid/FunctionId defined
213 Arg5 - Argument 5 ClassGuid/FunctionId defined
214 Arg6 - Argument 6 ClassGuid/FunctionId defined
215 Arg7 - Argument 7 ClassGuid/FunctionId defined
216 Arg8 - Argument 8 ClassGuid/FunctionId defined
217
218 Returns:
219 Status of ClassGuid/FuncitonId
220
221 --*/
222 {
223 SAL_RETURN_REGS ReturnReg;
224 SAL_EXTENDED_SAL_PROC EsalProc;
225
226 ReturnReg = GetEsalEntryPoint ();
227 if (ReturnReg.Status != EFI_SAL_SUCCESS) {
228 return ReturnReg;
229 }
230
231 //
232 // Look at the physical mode ESAL entry point to determine of the ESAL entry point has been initialized
233 //
234 if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) {
235 //
236 // Both the function ponter and the GP value are zero, so attempt to initialize the ESAL Entry Point
237 //
238 DxeSalLibInitialize ();
239 ReturnReg = GetEsalEntryPoint ();
240 if (ReturnReg.Status != EFI_SAL_SUCCESS) {
241 return ReturnReg;
242 }
243 if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) {
244 //
245 // The ESAL Entry Point could not be initialized
246 //
247 ReturnReg.Status = EFI_SAL_ERROR;
248 return ReturnReg;
249 }
250 }
251
252 if (ReturnReg.r11 & PSR_IT_MASK) {
253 //
254 // Virtual mode plabel to entry point
255 //
256 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r10;
257 } else {
258 //
259 // Physical mode plabel to entry point
260 //
261 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r9;
262 }
263
264 return EsalProc (
265 ClassGuid,
266 FunctionId,
267 Arg2,
268 Arg3,
269 Arg4,
270 Arg5,
271 Arg6,
272 Arg7,
273 Arg8
274 );
275 }