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