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