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