]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/RuntimeDxe/EfiRuntimeLib/Ipf/RuntimeLib.c
1) Add in EBC build support.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / RuntimeDxe / EfiRuntimeLib / Ipf / RuntimeLib.c
CommitLineData
3eb9473e 1/*++\r
2\r
3Copyright (c) 2004 - 2005, 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
11\r
12Module Name:\r
13\r
14 RuntimeLib.c\r
15\r
16Abstract:\r
17\r
18 Light weight lib to support Tiano Sal drivers.\r
19\r
20--*/\r
21\r
22#include "Tiano.h"\r
23#include "EfiRuntimeLib.h"\r
24#include EFI_PROTOCOL_DEFINITION (ExtendedSalBootService)\r
25#include EFI_PROTOCOL_DEFINITION (ExtendedSalGuid)\r
26#include "IpfDefines.h"\r
27#include "SalApi.h"\r
28\r
29//\r
30// Worker functions in EsalLib.s\r
31//\r
32SAL_RETURN_REGS\r
33GetEsalEntryPoint (\r
34 VOID\r
35 );\r
36\r
37SAL_RETURN_REGS\r
38SetEsalPhysicalEntryPoint (\r
39 IN UINT64 EntryPoint,\r
40 IN UINT64 Gp\r
41 );\r
42\r
43SAL_RETURN_REGS\r
44SetEsalVirtualEntryPoint (\r
45 IN UINT64 EntryPoint,\r
46 IN UINT64 Gp\r
47 );\r
48\r
49VOID\r
50SalFlushCache (\r
51 IN EFI_PHYSICAL_ADDRESS Start,\r
52 IN UINT64 Length\r
53 );\r
54\r
55//\r
56// Module Globals. It's not valid to use these after the\r
57// EfiRuntimeLibVirtualNotifyEvent has fired.\r
58//\r
59static EFI_EVENT mEfiVirtualNotifyEvent;\r
60static EFI_RUNTIME_SERVICES *mRT;\r
61static EFI_PLABEL mPlabel;\r
62static EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService;\r
63static BOOLEAN mRuntimeLibInitialized = FALSE;\r
64\r
65VOID\r
66EFIAPI\r
67EfiRuntimeLibVirtualNotifyEvent (\r
68 IN EFI_EVENT Event,\r
69 IN VOID *Context\r
70 )\r
71/*++\r
72\r
73Routine Description:\r
74\r
75 Fixup internal data so that EFI and SAL can be call in virtual mode.\r
76 Call the passed in Child Notify event and convert any pointers in \r
77 lib to virtual mode.\r
78\r
79Arguments:\r
80\r
81 Event - The Event that is being processed\r
82 \r
83 Context - Event Context\r
84\r
85Returns: \r
86\r
87 None\r
88\r
89--*/\r
90{\r
91 EFI_EVENT_NOTIFY ChildNotify;\r
92\r
93 if (Context != NULL) {\r
94 //\r
95 // Call child event\r
96 //\r
97 ChildNotify = (EFI_EVENT_NOTIFY) (UINTN) Context;\r
98 ChildNotify (Event, NULL);\r
99 }\r
100\r
101 mRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mPlabel.EntryPoint);\r
102 mRT->ConvertPointer (EFI_INTERNAL_POINTER | EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP);\r
103\r
104 SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);\r
105\r
106 //\r
107 // Clear out BootService globals\r
108 //\r
109 gBS = NULL;\r
110 gST = NULL;\r
111 mRT = NULL;\r
112\r
113 //\r
114 // Pointers don't work you must use a direct lib call\r
115 //\r
116}\r
117\r
118EFI_STATUS\r
119EfiInitializeRuntimeDriverLib (\r
120 IN EFI_HANDLE ImageHandle,\r
121 IN EFI_SYSTEM_TABLE *SystemTable,\r
122 IN EFI_EVENT_NOTIFY GoVirtualChildEvent\r
123 )\r
124/*++\r
125\r
126Routine Description:\r
127\r
128 Intialize runtime Driver Lib if it has not yet been initialized. \r
129\r
130Arguments:\r
131\r
132 ImageHandle - The firmware allocated handle for the EFI image.\r
133 \r
134 SystemTable - A pointer to the EFI System Table.\r
135\r
136 GoVirtualChildEvent - Caller can register a virtual notification event.\r
137\r
138Returns: \r
139\r
140 EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.\r
141\r
142--*/\r
143{\r
144 EFI_STATUS Status;\r
145 EFI_PLABEL *Plabel;\r
146\r
147 if (mRuntimeLibInitialized) {\r
148 return EFI_ALREADY_STARTED;\r
149 }\r
150\r
151 mRuntimeLibInitialized = TRUE;\r
152\r
153 gST = SystemTable;\r
154 gBS = SystemTable->BootServices;\r
155 mRT = SystemTable->RuntimeServices;\r
156 Status = EfiLibGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);\r
157 ASSERT_EFI_ERROR (Status);\r
158\r
159 //\r
160 // The protocol contains a function pointer, which is an indirect procedure call.\r
161 // An indirect procedure call goes through a plabel, and pointer to a function is\r
162 // a pointer to a plabel. To implement indirect procedure calls that can work in\r
163 // both physical and virtual mode, two plabels are required (one physical and one\r
164 // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it\r
165 // away. We cache it in a module global, so we can register the vitrual version.\r
166 //\r
167 Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, &mEsalBootService);\r
168 ASSERT_EFI_ERROR (Status);\r
169\r
170 Plabel = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;\r
171\r
172 mPlabel.EntryPoint = Plabel->EntryPoint;\r
173 mPlabel.GP = Plabel->GP;\r
174\r
175 SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);\r
176\r
177 //\r
178 // Create a Virtual address change notification event. Pass in the callers\r
179 // GoVirtualChildEvent so it's get passed to the event as contex.\r
180 //\r
181 Status = gBS->CreateEvent (\r
182 EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\r
183 EFI_TPL_NOTIFY,\r
184 EfiRuntimeLibVirtualNotifyEvent,\r
185 (VOID *) GoVirtualChildEvent,\r
186 &mEfiVirtualNotifyEvent\r
187 );\r
188 ASSERT_EFI_ERROR (Status);\r
189\r
190 return EFI_SUCCESS;\r
191}\r
192\r
193EFI_STATUS\r
194EfiShutdownRuntimeDriverLib (\r
195 VOID\r
196 )\r
197/*++\r
198\r
199Routine Description:\r
200\r
201 This routine will free some resources which have been allocated in\r
202 EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error, \r
203 it must call this routine to free the allocated resource before the exiting.\r
204\r
205Arguments:\r
206\r
207 None\r
208\r
209Returns: \r
210\r
211 EFI_SUCCESS - Shotdown the Runtime Driver Lib successfully\r
212 EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all\r
213\r
214--*/\r
215{\r
216 EFI_STATUS Status;\r
217\r
218 if (!mRuntimeLibInitialized) {\r
219 //\r
220 // You must call EfiInitializeRuntimeDriverLib() first\r
221 //\r
222 return EFI_UNSUPPORTED;\r
223 }\r
224\r
225 mRuntimeLibInitialized = FALSE;\r
226\r
227 //\r
228 // Close SetVirtualAddressMap () notify function\r
229 //\r
230 Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);\r
231 ASSERT_EFI_ERROR (Status);\r
232\r
233 return EFI_SUCCESS;\r
234}\r
235 \r
236EFI_STATUS\r
237RegisterEsalFunction (\r
238 IN UINT64 FunctionId,\r
239 IN EFI_GUID *ClassGuid,\r
240 IN SAL_INTERNAL_EXTENDED_SAL_PROC Function,\r
241 IN VOID *ModuleGlobal\r
242 )\r
243/*++\r
244\r
245Routine Description:\r
246\r
247 Register ESAL Class Function and it's asociated global.\r
248 This function is boot service only!\r
249\r
250Arguments:\r
251 FunctionId - ID of function to register\r
252 ClassGuid - GUID of function class \r
253 Function - Function to register under ClassGuid/FunctionId pair\r
254 ModuleGlobal - Module global for Function.\r
255\r
256Returns: \r
257 EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.\r
258\r
259--*/\r
260{\r
261 return mEsalBootService->AddExtendedSalProc (\r
262 mEsalBootService,\r
263 ClassGuid,\r
264 FunctionId,\r
265 Function,\r
266 ModuleGlobal\r
267 );\r
268}\r
269\r
270EFI_STATUS\r
271RegisterEsalClass (\r
272 IN EFI_GUID *ClassGuid,\r
273 IN VOID *ModuleGlobal,\r
274 ...\r
275 )\r
276/*++\r
277\r
278Routine Description:\r
279\r
280 Register ESAL Class and it's asociated global.\r
281 This function is boot service only!\r
282\r
283Arguments:\r
284 ClassGuid - GUID of function class \r
285 ModuleGlobal - Module global for Function.\r
286 ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL \r
287 indicates the end of the list.\r
288\r
289Returns: \r
290 EFI_SUCCESS - All members of ClassGuid registered\r
291\r
292--*/\r
293{\r
294 VA_LIST Args;\r
295 EFI_STATUS Status;\r
296 SAL_INTERNAL_EXTENDED_SAL_PROC Function;\r
297 UINT64 FunctionId;\r
298 EFI_HANDLE NewHandle;\r
299\r
300 VA_START (Args, ModuleGlobal);\r
301\r
302 Status = EFI_SUCCESS;\r
303 while (!EFI_ERROR (Status)) {\r
304 Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);\r
305 if (Function == NULL) {\r
306 break;\r
307 }\r
308\r
309 FunctionId = VA_ARG (Args, UINT64);\r
310\r
311 Status = RegisterEsalFunction (FunctionId, ClassGuid, Function, ModuleGlobal);\r
312 }\r
313\r
314 if (EFI_ERROR (Status)) {\r
315 return Status;\r
316 }\r
317\r
318 NewHandle = NULL;\r
319 return gBS->InstallProtocolInterface (\r
320 &NewHandle,\r
321 ClassGuid,\r
322 EFI_NATIVE_INTERFACE,\r
323 NULL\r
324 );\r
325}\r
326\r
327SAL_RETURN_REGS\r
328EfiCallEsalService (\r
329 IN EFI_GUID *ClassGuid,\r
330 IN UINT64 FunctionId,\r
331 IN UINT64 Arg2,\r
332 IN UINT64 Arg3,\r
333 IN UINT64 Arg4,\r
334 IN UINT64 Arg5,\r
335 IN UINT64 Arg6,\r
336 IN UINT64 Arg7,\r
337 IN UINT64 Arg8\r
338 )\r
339/*++\r
340\r
341Routine Description:\r
342\r
343 Call module that is not linked direclty to this module. This code is IP \r
344 relative and hides the binding issues of virtual or physical calling. The\r
345 function that gets dispatched has extra arguments that include the registered\r
346 module global and a boolean flag to indicate if the system is in virutal mode.\r
347\r
348Arguments:\r
349 ClassGuid - GUID of function\r
350 FunctionId - Function in ClassGuid to call\r
351 Arg2 - Argument 2 ClassGuid/FunctionId defined\r
352 Arg3 - Argument 3 ClassGuid/FunctionId defined\r
353 Arg4 - Argument 4 ClassGuid/FunctionId defined\r
354 Arg5 - Argument 5 ClassGuid/FunctionId defined\r
355 Arg6 - Argument 6 ClassGuid/FunctionId defined\r
356 Arg7 - Argument 7 ClassGuid/FunctionId defined\r
357 Arg8 - Argument 8 ClassGuid/FunctionId defined\r
358\r
359Returns: \r
360 Status of ClassGuid/FuncitonId\r
361\r
362--*/\r
363{\r
364 SAL_RETURN_REGS ReturnReg;\r
365 SAL_EXTENDED_SAL_PROC EsalProc;\r
366\r
367 ReturnReg = GetEsalEntryPoint ();\r
368 if (ReturnReg.Status != EFI_SAL_SUCCESS) {\r
369 return ReturnReg;\r
370 }\r
371\r
372 if (ReturnReg.r11 & PSR_IT_MASK) {\r
373 //\r
374 // Virtual mode plabel to entry point\r
375 //\r
376 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r10;\r
377 } else {\r
378 //\r
379 // Physical mode plabel to entry point\r
380 //\r
381 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r9;\r
382 }\r
383\r
384 return EsalProc (\r
385 ClassGuid,\r
386 FunctionId,\r
387 Arg2,\r
388 Arg3,\r
389 Arg4,\r
390 Arg5,\r
391 Arg6,\r
392 Arg7,\r
393 Arg8\r
394 );\r
395}\r
396\r
397EFI_STATUS\r
398EfiConvertPointer (\r
399 IN UINTN DebugDisposition,\r
400 IN OUT VOID *Address\r
401 )\r
402/*++\r
403\r
404Routine Description:\r
405\r
406 Determines the new virtual address that is to be used on subsequent memory accesses.\r
407\r
408Arguments:\r
409\r
410 DebugDisposition - Supplies type information for the pointer being converted.\r
411 Address - A pointer to a pointer that is to be fixed to be the value needed\r
412 for the new virtual address mappings being applied.\r
413\r
414Returns:\r
415\r
416 Status code\r
417\r
418--*/\r
419{\r
420 return mRT->ConvertPointer (DebugDisposition, Address);\r
421}\r
422\r
423BOOLEAN\r
424EfiGoneVirtual (\r
425 VOID\r
426 )\r
427/*++\r
428\r
429Routine Description:\r
430 Return TRUE if SetVirtualAddressMap () has been called\r
431\r
432Arguments:\r
433 NONE\r
434\r
435Returns: \r
436 TRUE - If SetVirtualAddressMap () has been called\r
437\r
438--*/\r
439{\r
440 EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;\r
441 SAL_RETURN_REGS ReturnReg;\r
442\r
443 ReturnReg = EfiCallEsalService (&Guid, IsVirtual, 0, 0, 0, 0, 0, 0, 0);\r
444\r
445 return (BOOLEAN) (ReturnReg.r9 == 1);\r
446}\r
447\r
448BOOLEAN\r
449EfiAtRuntime (\r
450 VOID\r
451 )\r
452/*++\r
453\r
454Routine Description:\r
455 Return TRUE if ExitBootService () has been called\r
456\r
457Arguments:\r
458 NONE\r
459\r
460Returns: \r
461 TRUE - If ExitBootService () has been called\r
462\r
463--*/\r
464{\r
465 EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;\r
466 SAL_RETURN_REGS ReturnReg;\r
467\r
468 ReturnReg = EfiCallEsalService (&Guid, IsEfiRuntime, 0, 0, 0, 0, 0, 0, 0);\r
469\r
470 return (BOOLEAN) (ReturnReg.r9 == 1);\r
471}\r
472\r
473EFI_STATUS\r
474EfiReportStatusCode (\r
475 IN EFI_STATUS_CODE_TYPE CodeType,\r
476 IN EFI_STATUS_CODE_VALUE Value,\r
477 IN UINT32 Instance,\r
478 IN EFI_GUID * CallerId,\r
479 IN EFI_STATUS_CODE_DATA * Data OPTIONAL\r
480 )\r
481/*++\r
482\r
483Routine Description:\r
484\r
485 Status Code reporter\r
486\r
487Arguments:\r
488\r
489 CodeType - Type of Status Code.\r
490 \r
491 Value - Value to output for Status Code.\r
492 \r
493 Instance - Instance Number of this status code.\r
494 \r
495 CallerId - ID of the caller of this status code.\r
496 \r
497 Data - Optional data associated with this status code.\r
498\r
499Returns:\r
500\r
501 Status code\r
502\r
503--*/\r
504{\r
505 EFI_GUID Guid = EFI_EXTENDED_SAL_STATUS_CODE_SERVICES_PROTOCOL_GUID;\r
506 SAL_RETURN_REGS ReturnReg;\r
507\r
508\r
509 ReturnReg = EfiCallEsalService (\r
510 &Guid,\r
511 StatusCode,\r
512 (UINT64) CodeType,\r
513 (UINT64) Value,\r
514 (UINT64) Instance,\r
515 (UINT64) CallerId,\r
516 (UINT64) Data,\r
517 0,\r
518 0\r
519 );\r
520\r
521 return (EFI_STATUS) ReturnReg.Status;\r
522}\r
523//\r
524// Sal Reset Driver Class\r
525//\r
526VOID\r
527EfiResetSystem (\r
528 IN EFI_RESET_TYPE ResetType,\r
529 IN EFI_STATUS ResetStatus,\r
530 IN UINTN DataSize,\r
531 IN CHAR16 *ResetData\r
532 )\r
533/*++\r
534\r
535Routine Description:\r
536\r
537 Resets the entire platform.\r
538\r
539Arguments:\r
540\r
541 ResetType - The type of reset to perform.\r
542 ResetStatus - The status code for the reset.\r
543 DataSize - The size, in bytes, of ResetData.\r
544 ResetData - A data buffer that includes a Null-terminated Unicode string, optionally\r
545 followed by additional binary data.\r
546\r
547Returns:\r
548\r
549 None\r
550\r
551--*/\r
552{\r
553 EFI_GUID Guid = EFI_EXTENDED_SAL_RESET_SERVICES_PROTOCOL_GUID;\r
554\r
555 EfiCallEsalService (\r
556 &Guid,\r
557 ResetSystem,\r
558 (UINT64) ResetType,\r
559 (UINT64) ResetStatus,\r
560 (UINT64) DataSize,\r
561 (UINT64) ResetData,\r
562 0,\r
563 0,\r
564 0\r
565 );\r
566}\r
567//\r
568// Sal MTC Driver Class\r
569//\r
570EFI_STATUS\r
571EfiGetNextHighMonotonicCount (\r
572 OUT UINT32 *HighCount\r
573 )\r
574/*++\r
575\r
576Routine Description:\r
577\r
578