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