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