]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/RuntimeDxe/EfiRuntimeLib/Ipf/RuntimeLib.c
Add Missing invocations to VA_END() for VA_START().
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / RuntimeDxe / EfiRuntimeLib / Ipf / RuntimeLib.c
1 /*++
2
3 Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
4 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 RuntimeLib.c
15
16 Abstract:
17
18 Light weight lib to support Tiano Sal drivers.
19
20 --*/
21
22 #include "Tiano.h"
23 #include "EfiRuntimeLib.h"
24 #include EFI_PROTOCOL_DEFINITION (ExtendedSalBootService)
25 #include EFI_PROTOCOL_DEFINITION (ExtendedSalGuid)
26 #include "IpfDefines.h"
27 #include "SalApi.h"
28
29 //
30 // Worker functions in EsalLib.s
31 //
32 SAL_RETURN_REGS
33 GetEsalEntryPoint (
34 VOID
35 );
36
37 SAL_RETURN_REGS
38 SetEsalPhysicalEntryPoint (
39 IN UINT64 EntryPoint,
40 IN UINT64 Gp
41 );
42
43 SAL_RETURN_REGS
44 SetEsalVirtualEntryPoint (
45 IN UINT64 EntryPoint,
46 IN UINT64 Gp
47 );
48
49 VOID
50 SalFlushCache (
51 IN EFI_PHYSICAL_ADDRESS Start,
52 IN UINT64 Length
53 );
54
55 //
56 // Module Globals. It's not valid to use these after the
57 // EfiRuntimeLibVirtualNotifyEvent has fired.
58 //
59 static EFI_EVENT mEfiVirtualNotifyEvent;
60 static EFI_RUNTIME_SERVICES *mRT;
61 static EFI_PLABEL mPlabel;
62 static EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService;
63 static BOOLEAN mRuntimeLibInitialized = FALSE;
64
65 VOID
66 EFIAPI
67 EfiRuntimeLibVirtualNotifyEvent (
68 IN EFI_EVENT Event,
69 IN VOID *Context
70 )
71 /*++
72
73 Routine Description:
74
75 Fixup internal data so that EFI and SAL can be call in virtual mode.
76 Call the passed in Child Notify event and convert any pointers in
77 lib to virtual mode.
78
79 Arguments:
80
81 Event - The Event that is being processed
82
83 Context - Event Context
84
85 Returns:
86
87 None
88
89 --*/
90 {
91 EFI_EVENT_NOTIFY ChildNotify;
92
93 if (Context != NULL) {
94 //
95 // Call child event
96 //
97 ChildNotify = (EFI_EVENT_NOTIFY) (UINTN) Context;
98 ChildNotify (Event, NULL);
99 }
100
101 mRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID **) &mPlabel.EntryPoint);
102 mRT->ConvertPointer (EFI_INTERNAL_POINTER | EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP);
103
104 SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
105
106 //
107 // Clear out BootService globals
108 //
109 gBS = NULL;
110 gST = NULL;
111 mRT = NULL;
112
113 //
114 // Pointers don't work you must use a direct lib call
115 //
116 }
117
118 EFI_STATUS
119 EfiInitializeRuntimeDriverLib (
120 IN EFI_HANDLE ImageHandle,
121 IN EFI_SYSTEM_TABLE *SystemTable,
122 IN EFI_EVENT_NOTIFY GoVirtualChildEvent
123 )
124 /*++
125
126 Routine Description:
127
128 Intialize runtime Driver Lib if it has not yet been initialized.
129
130 Arguments:
131
132 ImageHandle - The firmware allocated handle for the EFI image.
133
134 SystemTable - A pointer to the EFI System Table.
135
136 GoVirtualChildEvent - Caller can register a virtual notification event.
137
138 Returns:
139
140 EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
141
142 --*/
143 {
144 EFI_STATUS Status;
145 EFI_PLABEL *Plabel;
146
147 if (mRuntimeLibInitialized) {
148 return EFI_ALREADY_STARTED;
149 }
150
151 mRuntimeLibInitialized = TRUE;
152
153 gST = SystemTable;
154 gBS = SystemTable->BootServices;
155 mRT = SystemTable->RuntimeServices;
156 Status = EfiLibGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
157 ASSERT_EFI_ERROR (Status);
158
159 //
160 // The protocol contains a function pointer, which is an indirect procedure call.
161 // An indirect procedure call goes through a plabel, and pointer to a function is
162 // a pointer to a plabel. To implement indirect procedure calls that can work in
163 // both physical and virtual mode, two plabels are required (one physical and one
164 // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it
165 // away. We cache it in a module global, so we can register the vitrual version.
166 //
167 Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, (VOID **) &mEsalBootService);
168 ASSERT_EFI_ERROR (Status);
169
170 Plabel = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;
171
172 mPlabel.EntryPoint = Plabel->EntryPoint;
173 mPlabel.GP = Plabel->GP;
174
175 SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
176
177 //
178 // Create a Virtual address change notification event. Pass in the callers
179 // GoVirtualChildEvent so it's get passed to the event as contex.
180 //
181 Status = gBS->CreateEvent (
182 EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
183 EFI_TPL_NOTIFY,
184 EfiRuntimeLibVirtualNotifyEvent,
185 (VOID *) GoVirtualChildEvent,
186 &mEfiVirtualNotifyEvent
187 );
188 ASSERT_EFI_ERROR (Status);
189
190 return EFI_SUCCESS;
191 }
192
193 EFI_STATUS
194 EfiShutdownRuntimeDriverLib (
195 VOID
196 )
197 /*++
198
199 Routine Description:
200
201 This routine will free some resources which have been allocated in
202 EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error,
203 it must call this routine to free the allocated resource before the exiting.
204
205 Arguments:
206
207 None
208
209 Returns:
210
211 EFI_SUCCESS - Shotdown the Runtime Driver Lib successfully
212 EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all
213
214 --*/
215 {
216 EFI_STATUS Status;
217
218 if (!mRuntimeLibInitialized) {
219 //
220 // You must call EfiInitializeRuntimeDriverLib() first
221 //
222 return EFI_UNSUPPORTED;
223 }
224
225 mRuntimeLibInitialized = FALSE;
226
227 //
228 // Close SetVirtualAddressMap () notify function
229 //
230 Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);
231 ASSERT_EFI_ERROR (Status);
232
233 return EFI_SUCCESS;
234 }
235
236 EFI_STATUS
237 RegisterEsalFunction (
238 IN UINT64 FunctionId,
239 IN EFI_GUID *ClassGuid,
240 IN SAL_INTERNAL_EXTENDED_SAL_PROC Function,
241 IN VOID *ModuleGlobal
242 )
243 /*++
244
245 Routine Description:
246
247 Register ESAL Class Function and it's asociated global.
248 This function is boot service only!
249
250 Arguments:
251 FunctionId - ID of function to register
252 ClassGuid - GUID of function class
253 Function - Function to register under ClassGuid/FunctionId pair
254 ModuleGlobal - Module global for Function.
255
256 Returns:
257 EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.
258
259 --*/
260 {
261 return mEsalBootService->AddExtendedSalProc (
262 mEsalBootService,
263 ClassGuid,
264 FunctionId,
265 Function,
266 ModuleGlobal
267 );
268 }
269
270 EFI_STATUS
271 RegisterEsalClass (
272 IN EFI_GUID *ClassGuid,
273 IN VOID *ModuleGlobal,
274 ...
275 )
276 /*++
277
278 Routine Description:
279
280 Register ESAL Class and it's asociated global.
281 This function is boot service only!
282
283 Arguments:
284 ClassGuid - GUID of function class
285 ModuleGlobal - Module global for Function.
286 ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL
287 indicates the end of the list.
288
289 Returns:
290 EFI_SUCCESS - All members of ClassGuid registered
291
292 --*/
293 {
294 VA_LIST Args;
295 EFI_STATUS Status;
296 SAL_INTERNAL_EXTENDED_SAL_PROC Function;
297 UINT64 FunctionId;
298 EFI_HANDLE NewHandle;
299
300 VA_START (Args, ModuleGlobal);
301
302 Status = EFI_SUCCESS;
303 while (!EFI_ERROR (Status)) {
304 Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);
305 if (Function == NULL) {
306 break;
307 }
308
309 FunctionId = VA_ARG (Args, UINT64);
310
311 Status = RegisterEsalFunction (FunctionId, ClassGuid, Function, ModuleGlobal);
312 }
313
314 VA_END (Args);
315
316 if (EFI_ERROR (Status)) {
317 return Status;
318 }
319
320 NewHandle = NULL;
321 return gBS->InstallProtocolInterface (
322 &NewHandle,
323 ClassGuid,
324 EFI_NATIVE_INTERFACE,
325 NULL
326 );
327 }
328
329 SAL_RETURN_REGS
330 EfiCallEsalService (
331 IN EFI_GUID *ClassGuid,
332 IN UINT64 FunctionId,
333 IN UINT64 Arg2,
334 IN UINT64 Arg3,
335 IN UINT64 Arg4,
336 IN UINT64 Arg5,
337 IN UINT64 Arg6,
338 IN UINT64 Arg7,
339 IN UINT64 Arg8
340 )
341 /*++
342
343 Routine Description:
344
345 Call module that is not linked direclty to this module. This code is IP
346 relative and hides the binding issues of virtual or physical calling. The
347 function that gets dispatched has extra arguments that include the registered
348 module global and a boolean flag to indicate if the system is in virutal mode.
349
350 Arguments:
351 ClassGuid - GUID of function
352 FunctionId - Function in ClassGuid to call
353 Arg2 - Argument 2 ClassGuid/FunctionId defined
354 Arg3 - Argument 3 ClassGuid/FunctionId defined
355 Arg4 - Argument 4 ClassGuid/FunctionId defined
356 Arg5 - Argument 5 ClassGuid/FunctionId defined
357 Arg6 - Argument 6 ClassGuid/FunctionId defined
358 Arg7 - Argument 7 ClassGuid/FunctionId defined
359 Arg8 - Argument 8 ClassGuid/FunctionId defined
360
361 Returns:
362 Status of ClassGuid/FuncitonId
363
364 --*/
365 {
366 SAL_RETURN_REGS ReturnReg;
367 SAL_EXTENDED_SAL_PROC EsalProc;
368
369 ReturnReg = GetEsalEntryPoint ();
370 if (ReturnReg.Status != EFI_SAL_SUCCESS) {
371 return ReturnReg;
372 }
373
374 if (ReturnReg.r11 & PSR_IT_MASK) {
375 //
376 // Virtual mode plabel to entry point
377 //
378 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r10;
379 } else {
380 //
381 // Physical mode plabel to entry point
382 //
383 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r9;
384 }
385
386 return EsalProc (
387 ClassGuid,
388 FunctionId,
389 Arg2,
390 Arg3,
391 Arg4,
392 Arg5,
393 Arg6,
394 Arg7,
395 Arg8
396 );
397 }
398
399 EFI_STATUS
400 EfiConvertPointer (
401 IN UINTN DebugDisposition,
402 IN OUT VOID *Address
403 )
404 /*++
405
406 Routine Description:
407
408 Determines the new virtual address that is to be used on subsequent memory accesses.
409
410 Arguments:
411
412 DebugDisposition - Supplies type information for the pointer being converted.
413 Address - A pointer to a pointer that is to be fixed to be the value needed
414 for the new virtual address mappings being applied.
415
416 Returns:
417
418 Status code
419
420 --*/
421 {
422 return mRT->ConvertPointer (DebugDisposition, Address);
423 }
424
425 BOOLEAN
426 EfiGoneVirtual (
427 VOID
428 )
429 /*++
430
431 Routine Description:
432 Return TRUE if SetVirtualAddressMap () has been called
433
434 Arguments:
435 NONE
436
437 Returns:
438 TRUE - If SetVirtualAddressMap () has been called
439
440 --*/
441 {
442 EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;
443 SAL_RETURN_REGS ReturnReg;
444
445 ReturnReg = EfiCallEsalService (&Guid, IsVirtual, 0, 0, 0, 0, 0, 0, 0);
446
447 return (BOOLEAN) (ReturnReg.r9 == 1);
448 }
449
450 BOOLEAN
451 EfiAtRuntime (
452 VOID
453 )
454 /*++
455
456 Routine Description:
457 Return TRUE if ExitBootService () has been called
458
459 Arguments:
460 NONE
461
462 Returns:
463 TRUE - If ExitBootService () has been called
464
465 --*/
466 {
467 EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;
468 SAL_RETURN_REGS ReturnReg;
469
470 ReturnReg = EfiCallEsalService (&Guid, IsEfiRuntime, 0, 0, 0, 0, 0, 0, 0);
471
472 return (BOOLEAN) (ReturnReg.r9 == 1);
473 }
474
475 EFI_STATUS
476 EfiReportStatusCode (
477 IN EFI_STATUS_CODE_TYPE CodeType,
478 IN EFI_STATUS_CODE_VALUE Value,
479 IN UINT32 Instance,
480 IN EFI_GUID * CallerId,
481 IN EFI_STATUS_CODE_DATA * Data OPTIONAL
482 )
483 /*++
484
485 Routine Description:
486
487 Status Code reporter
488
489 Arguments:
490
491 CodeType - Type of Status Code.
492
493 Value - Value to output for Status Code.
494
495 Instance - Instance Number of this status code.
496
497 CallerId - ID of the caller of this status code.
498
499 Data - Optional data associated with this status code.
500
501 Returns:
502
503 Status code
504
505 --*/
506 {
507 EFI_GUID Guid = EFI_EXTENDED_SAL_STATUS_CODE_SERVICES_PROTOCOL_GUID;
508 SAL_RETURN_REGS ReturnReg;
509
510
511 ReturnReg = EfiCallEsalService (
512 &Guid,
513 StatusCode,
514 (UINT64) CodeType,
515 (UINT64) Value,
516 (UINT64) Instance,
517 (UINT64) CallerId,
518 (UINT64) Data,
519 0,
520 0
521 );
522
523 return (EFI_STATUS) ReturnReg.Status;
524 }
525 //
526 // Sal Reset Driver Class
527 //
528 VOID
529 EfiResetSystem (
530 IN EFI_RESET_TYPE ResetType,
531 IN EFI_STATUS ResetStatus,
532 IN UINTN DataSize,
533 IN CHAR16 *ResetData
534 )
535 /*++
536
537 Routine Description:
538
539 Resets the entire platform.
540
541 Arguments:
542
543 ResetType - The type of reset to perform.
544 ResetStatus - The status code for the reset.
545 DataSize - The size, in bytes, of ResetData.
546 ResetData - A data buffer that includes a Null-terminated Unicode string, optionally
547 followed by additional binary data.
548
549 Returns:
550
551 None
552
553 --*/
554 {
555 EFI_GUID Guid = EFI_EXTENDED_SAL_RESET_SERVICES_PROTOCOL_GUID;
556
557 EfiCallEsalService (
558 &Guid,
559 ResetSystem,
560 (UINT64) ResetType,
561 (UINT64) ResetStatus,
562 (UINT64) DataSize,
563 (UINT64) ResetData,
564 0,
565 0,
566 0
567 );
568 }
569 //
570 // Sal MTC Driver Class
571 //
572 EFI_STATUS
573 EfiGetNextHighMonotonicCount (
574 OUT UINT32 *HighCount
575 )
576 /*++
577
578 Routine Description:
579
580 Returns the next high 32 bits of the platform's monotonic counter.
581
582 Arguments:
583
584 HighCount - Pointer to returned value.
585
586 Returns:
587
588 Status code
589
590 --*/
591 {
592 SAL_RETURN_REGS ReturnReg;
593
594 EFI_GUID Guid = EFI_EXTENDED_SAL_MTC_SERVICES_PROTOCOL_GUID;
595
596 ReturnReg = EfiCallEsalService (&Guid, GetNextHighMonotonicCount, (UINT64) HighCount, 0, 0, 0, 0, 0, 0);
597 return (EFI_STATUS) ReturnReg.Status;
598 }
599 //
600 // Sal Variable Driver Class
601 //
602 EFI_STATUS
603 EfiGetVariable (
604 IN CHAR16 *VariableName,
605 IN EFI_GUID * VendorGuid,
606 OUT UINT32 *Attributes OPTIONAL,
607 IN OUT UINTN *DataSize,
608 OUT VOID *Data
609 )
610 /*++
611
612 Routine Description:
613
614 Returns the value of a variable.
615
616 Arguments:
617
618 VariableName - A Null-terminated Unicode string that is the name of the
619 vendor's variable.
620 VendorGuid - A unique identifier for the vendor.
621 Attributes - If not NULL, a pointer to the memory location to return the
622 attributes bitmask for the variable.
623 DataSize - On input, the size in bytes of the return Data buffer.
624 On output the size of data returned in Data.
625 Data - The buffer to return the contents of the variable.
626
627 Returns:
628
629 Status code
630
631 --*/
632 {
633 SAL_RETURN_REGS ReturnReg;
634 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
635
636 ReturnReg = EfiCallEsalService (
637 &Guid,
638 EsalGetVariable,
639 (UINT64) VariableName,
640 (UINT64) VendorGuid,
641 (UINT64) Attributes,
642 (UINT64) DataSize,
643 (UINT64) Data,
644 0,
645 0
646 );
647 return (EFI_STATUS) ReturnReg.Status;
648 }
649
650 EFI_STATUS
651 EfiGetNextVariableName (
652 IN OUT UINTN *VariableNameSize,
653 IN OUT CHAR16 *VariableName,
654 IN OUT EFI_GUID *VendorGuid
655 )
656 /*++
657
658 Routine Description:
659
660 Enumerates the current variable names.
661
662 Arguments:
663
664 VariableNameSize - The size of the VariableName buffer.
665 VariableName - On input, supplies the last VariableName that was returned
666 by GetNextVariableName().
667 On output, returns the Nullterminated Unicode string of the
668 current variable.
669 VendorGuid - On input, supplies the last VendorGuid that was returned by
670 GetNextVariableName().
671 On output, returns the VendorGuid of the current variable.
672
673 Returns:
674
675 Status code
676
677 --*/
678 {
679 SAL_RETURN_REGS ReturnReg;
680 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
681
682 ReturnReg = EfiCallEsalService (
683 &Guid,
684 EsalGetNextVariableName,
685 (UINT64) VariableNameSize,
686 (UINT64) VariableName,
687 (UINT64) VendorGuid,
688 0,
689 0,
690 0,
691 0
692 );
693 return (EFI_STATUS) ReturnReg.Status;
694 }
695
696 EFI_STATUS
697 EfiSetVariable (
698 IN CHAR16 *VariableName,
699 IN EFI_GUID *VendorGuid,
700 IN UINT32 Attributes,
701 IN UINTN DataSize,
702 IN VOID *Data
703 )
704 /*++
705
706 Routine Description:
707
708 Sets the value of a variable.
709
710 Arguments:
711
712 VariableName - A Null-terminated Unicode string that is the name of the
713 vendor's variable.
714 VendorGuid - A unique identifier for the vendor.
715 Attributes - Attributes bitmask to set for the variable.
716 DataSize - The size in bytes of the Data buffer.
717 Data - The contents for the variable.
718
719 Returns:
720
721 Status code
722
723 --*/
724 {
725 SAL_RETURN_REGS ReturnReg;
726 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
727
728 ReturnReg = EfiCallEsalService (
729 &Guid,
730 EsalSetVariable,
731 (UINT64) VariableName,
732 (UINT64) VendorGuid,
733 (UINT64) Attributes,
734 (UINT64) DataSize,
735 (UINT64) Data,
736 0,
737 0
738 );
739 return (EFI_STATUS) ReturnReg.Status;
740 }
741
742 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
743
744 EFI_STATUS
745 EfiQueryVariableInfo (
746 IN UINT32 Attributes,
747 OUT UINT64 *MaximumVariableStorageSize,
748 OUT UINT64 *RemainingVariableStorageSize,
749 OUT UINT64 *MaximumVariableSize
750 )
751 /*++
752
753 Routine Description:
754
755 This code returns information about the EFI variables.
756
757 Arguments:
758
759 Attributes Attributes bitmask to specify the type of variables
760 on which to return information.
761 MaximumVariableStorageSize Pointer to the maximum size of the storage space available
762 for the EFI variables associated with the attributes specified.
763 RemainingVariableStorageSize Pointer to the remaining size of the storage space available
764 for the EFI variables associated with the attributes specified.
765 MaximumVariableSize Pointer to the maximum size of the individual EFI variables
766 associated with the attributes specified.
767
768 Returns:
769
770 Status code
771
772 --*/
773 {
774 SAL_RETURN_REGS ReturnReg;
775 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
776
777 ReturnReg = EfiCallEsalService (
778 &Guid,
779 EsalQueryVariableInfo,
780 (UINT64) Attributes,
781 (UINT64) MaximumVariableStorageSize,
782 (UINT64) RemainingVariableStorageSize,
783 (UINT64) MaximumVariableSize,
784 0,
785 0,
786 0
787 );
788 return (EFI_STATUS) ReturnReg.Status;
789 }
790
791 #endif
792
793 //
794 // Sal RTC Driver Class.
795 //
796 EFI_STATUS
797 EfiGetTime (
798 OUT EFI_TIME *Time,
799 OUT EFI_TIME_CAPABILITIES *Capabilities
800 )
801 /*++
802
803 Routine Description:
804
805 Returns the current time and date information, and the time-keeping
806 capabilities of the hardware platform.
807
808 Arguments:
809
810 Time - A pointer to storage to receive a snapshot of the current time.
811 Capabilities - An optional pointer to a buffer to receive the real time clock device's
812 capabilities.
813
814 Returns:
815
816 Status code
817
818 --*/
819 {
820 SAL_RETURN_REGS ReturnReg;
821 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
822
823 ReturnReg = EfiCallEsalService (&Guid, GetTime, (UINT64) Time, (UINT64) Capabilities, 0, 0, 0, 0, 0);
824 return ReturnReg.Status;
825 }
826
827 EFI_STATUS
828 EfiSetTime (
829 OUT EFI_TIME *Time
830 )
831 /*++
832
833 Routine Description:
834
835 Sets the current local time and date information.
836
837 Arguments:
838
839 Time - A pointer to the current time.
840
841 Returns:
842
843 Status code
844
845 --*/
846 {
847 SAL_RETURN_REGS ReturnReg;
848
849 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
850
851 ReturnReg = EfiCallEsalService (&Guid, SetTime, (UINT64) Time, 0, 0, 0, 0, 0, 0);
852 return ReturnReg.Status;
853 }
854
855 EFI_STATUS
856 EfiGetWakeupTime (
857 OUT BOOLEAN *Enabled,
858 OUT BOOLEAN *Pending,
859 OUT EFI_TIME *Time
860 )
861 /*++
862
863 Routine Description:
864
865 Returns the current wakeup alarm clock setting.
866
867 Arguments:
868
869 Enabled - Indicates if the alarm is currently enabled or disabled.
870 Pending - Indicates if the alarm signal is pending and requires acknowledgement.
871 Time - The current alarm setting.
872
873 Returns:
874
875 Status code
876
877 --*/
878 {
879 SAL_RETURN_REGS ReturnReg;
880
881 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
882
883 ReturnReg = EfiCallEsalService (&Guid, GetWakeupTime, (UINT64) Enabled, (UINT64) Pending, (UINT64) Time, 0, 0, 0, 0);
884 return ReturnReg.Status;
885 }
886
887 EFI_STATUS
888 EfiSetWakeupTime (
889 IN BOOLEAN Enable,
890 IN EFI_TIME *Time
891 )
892 /*++
893
894 Routine Description:
895
896 Sets the system wakeup alarm clock time.
897
898 Arguments:
899
900 Enable - Enable or disable the wakeup alarm.
901 Time - If Enable is TRUE, the time to set the wakeup alarm for.
902 If Enable is FALSE, then this parameter is optional, and may be NULL.
903
904 Returns:
905
906 Status code
907
908 --*/
909 {
910 SAL_RETURN_REGS ReturnReg;
911
912 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
913
914 ReturnReg = EfiCallEsalService (&Guid, SetWakeupTime, (UINT64) Enable, (UINT64) Time, 0, 0, 0, 0, 0);
915 return ReturnReg.Status;
916 }
917
918
919
920 //
921 // Base IO Services
922 //
923 EFI_STATUS
924 EfiIoRead (
925 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
926 IN UINT64 Address,
927 IN UINTN Count,
928 IN OUT VOID *Buffer
929 )
930 /*++
931
932 Routine Description:
933 Perform an IO read into Buffer.
934
935 Arguments:
936 Width - Width of read transaction, and repeat operation to use
937 Address - IO address to read
938 Count - Number of times to read the IO address.
939 Buffer - Buffer to read data into. size is Width * Count
940
941 Returns:
942 Status code
943
944 --*/
945 {
946
947 SAL_RETURN_REGS ReturnReg;
948
949 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
950
951 ReturnReg = EfiCallEsalService (&Guid, IoRead, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
952 ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);
953
954 return ReturnReg.Status;
955
956 }
957
958 EFI_STATUS
959 EfiIoWrite (
960 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
961 IN UINT64 Address,
962 IN UINTN Count,
963 IN OUT VOID *Buffer
964 )
965 /*++
966
967 Routine Description:
968 Perform an IO write into Buffer.
969
970 Arguments:
971 Width - Width of write transaction, and repeat operation to use
972 Address - IO address to write
973 Count - Number of times to write the IO address.
974 Buffer - Buffer to write data from. size is Width * Count
975
976 Returns:
977 Status code
978
979 --*/
980 {
981
982 SAL_RETURN_REGS ReturnReg;
983
984 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
985
986 ReturnReg = EfiCallEsalService (&Guid, IoWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
987
988 return ReturnReg.Status;
989
990 }
991
992 EFI_STATUS
993 EfiMemRead (
994 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
995 IN UINT64 Address,
996 IN UINTN Count,
997 IN OUT VOID *Buffer
998 )
999 /*++
1000
1001 Routine Description:
1002 Perform a Memory mapped IO read into Buffer.
1003
1004 Arguments:
1005 Width - Width of each read transaction.
1006 Address - Memory mapped IO address to read
1007 Count - Number of Width quanta to read
1008 Buffer - Buffer to read data into. size is Width * Count
1009
1010 Returns:
1011 Status code
1012
1013 --*/
1014 {
1015
1016 SAL_RETURN_REGS ReturnReg;
1017
1018 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
1019
1020 ReturnReg = EfiCallEsalService (&Guid, MemRead, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
1021 ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);
1022
1023 return ReturnReg.Status;
1024
1025 }
1026
1027 EFI_STATUS
1028 EfiMemWrite (
1029 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
1030 IN UINT64 Address,
1031 IN UINTN Count,
1032 IN OUT VOID *Buffer
1033 )
1034 /*++
1035
1036 Routine Description:
1037 Perform a memory mapped IO write into Buffer.
1038
1039 Arguments:
1040 Width - Width of write transaction, and repeat operation to use
1041 Address - IO address to write
1042 Count - Number of times to write the IO address.
1043 Buffer - Buffer to write data from. size is Width * Count
1044
1045 Returns:
1046 Status code
1047
1048 --*/
1049 {
1050
1051 SAL_RETURN_REGS ReturnReg;
1052
1053 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
1054
1055 ReturnReg = EfiCallEsalService (&Guid, MemWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
1056
1057 return ReturnReg.Status;
1058
1059 }
1060
1061
1062 #define EFI_PCI_ADDRESS_IPF(_seg, _bus, _devfunc, _reg) \
1063 (((_seg) << 24) | ((_bus) << 16) | ((_devfunc) << 8) | (_reg)) & 0xFFFFFFFF
1064
1065 //
1066 // PCI Class Functions
1067 //
1068 UINT8
1069 PciRead8 (
1070 UINT8 Segment,
1071 UINT8 Bus,
1072 UINT8 DevFunc,
1073 UINT8 Register
1074 )
1075 /*++
1076
1077 Routine Description:
1078 Perform an one byte PCI config cycle read
1079
1080 Arguments:
1081 Segment - PCI Segment ACPI _SEG
1082 Bus - PCI Bus
1083 DevFunc - PCI Device(7:3) and Func(2:0)
1084 Register - PCI config space register
1085
1086 Returns:
1087 Data read from PCI config space
1088
1089 --*/
1090 {
1091 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1092 UINT64 Address;
1093 SAL_RETURN_REGS Return;
1094
1095 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1096 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 1, 0, 0, 0, 0, 0);
1097
1098 return (UINT8) Return.r9;
1099 }
1100
1101
1102 UINT16
1103 PciRead16 (
1104 UINT8 Segment,
1105 UINT8 Bus,
1106 UINT8 DevFunc,
1107 UINT8 Register
1108 )
1109 /*++
1110
1111 Routine Description:
1112 Perform an two byte PCI config cycle read
1113
1114 Arguments:
1115 Segment - PCI Segment ACPI _SEG
1116 Bus - PCI Bus
1117 DevFunc - PCI Device(7:3) and Func(2:0)
1118 Register - PCI config space register
1119
1120 Returns:
1121 Data read from PCI config space
1122
1123 --*/
1124 {
1125 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1126 UINT64 Address;
1127 SAL_RETURN_REGS Return;
1128
1129 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1130 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 2, 0, 0, 0, 0, 0);
1131
1132 return (UINT16) Return.r9;
1133 }
1134
1135 UINT32
1136 PciRead32 (
1137 UINT8 Segment,
1138 UINT8 Bus,
1139 UINT8 DevFunc,
1140 UINT8 Register
1141 )
1142 /*++
1143
1144 Routine Description:
1145 Perform an four byte PCI config cycle read
1146
1147 Arguments:
1148 Segment - PCI Segment ACPI _SEG
1149 Bus - PCI Bus
1150 DevFunc - PCI Device(7:3) and Func(2:0)
1151 Register - PCI config space register
1152
1153 Returns:
1154 Data read from PCI config space
1155
1156 --*/
1157 {
1158 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1159 UINT64 Address;
1160 SAL_RETURN_REGS Return;
1161
1162 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1163 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 4, 0, 0, 0, 0, 0);
1164
1165 return (UINT32) Return.r9;
1166 }
1167
1168 VOID
1169 PciWrite8 (
1170 UINT8 Segment,
1171 UINT8 Bus,
1172 UINT8 DevFunc,
1173 UINT8 Register,
1174 UINT8 Data
1175 )
1176 /*++
1177
1178 Routine Description:
1179 Perform an one byte PCI config cycle write
1180
1181 Arguments:
1182 Segment - PCI Segment ACPI _SEG
1183 Bus - PCI Bus
1184 DevFunc - PCI Device(7:3) and Func(2:0)
1185 Register - PCI config space register
1186 Data - Data to write
1187
1188 Returns:
1189 NONE
1190
1191 --*/
1192 {
1193 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1194 UINT64 Address;
1195
1196 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1197 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 1, Data, 0, 0, 0, 0);
1198 }
1199
1200 VOID
1201 PciWrite16 (
1202 UINT8 Segment,
1203 UINT8 Bus,
1204 UINT8 DevFunc,
1205 UINT8 Register,
1206 UINT16 Data
1207 )
1208 /*++
1209
1210 Routine Description:
1211 Perform an two byte PCI config cycle write
1212
1213 Arguments:
1214 Segment - PCI Segment ACPI _SEG
1215 Bus - PCI Bus
1216 DevFunc - PCI Device(7:3) and Func(2:0)
1217 Register - PCI config space register
1218 Data - Data to write
1219
1220 Returns:
1221 None.
1222
1223 --*/
1224 {
1225 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1226 UINT64 Address;
1227
1228 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1229 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 2, Data, 0, 0, 0, 0);
1230 }
1231
1232 VOID
1233 PciWrite32 (
1234 UINT8 Segment,
1235 UINT8 Bus,
1236 UINT8 DevFunc,
1237 UINT8 Register,
1238 UINT32 Data
1239 )
1240 /*++
1241
1242 Routine Description:
1243 Perform an four byte PCI config cycle write
1244
1245 Arguments:
1246 Segment - PCI Segment ACPI _SEG
1247 Bus - PCI Bus
1248 DevFunc - PCI Device(7:3) and Func(2:0)
1249 Register - PCI config space register
1250 Data - Data to write
1251
1252 Returns:
1253 NONE
1254
1255 --*/
1256 {
1257 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1258 UINT64 Address;
1259
1260 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1261 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 4, Data, 0, 0, 0, 0);
1262 }
1263
1264 //
1265 // Stall class functions
1266 //
1267 VOID
1268 EfiStall (
1269 IN UINTN Microseconds
1270 )
1271 /*++
1272
1273 Routine Description:
1274 Delay for at least the request number of microseconds
1275
1276 Arguments:
1277 Microseconds - Number of microseconds to delay.
1278
1279 Returns:
1280 NONE
1281
1282 --*/
1283 {
1284 EFI_GUID Guid = EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID;
1285
1286 if (EfiAtRuntime ()) {
1287 EfiCallEsalService (&Guid, Stall, Microseconds, 4, 0, 0, 0, 0, 0);
1288 } else {
1289 gBS->Stall (Microseconds);
1290 }
1291 }
1292 //
1293 // Cache Flush Routine.
1294 //
1295 EFI_STATUS
1296 EfiCpuFlushCache (
1297 IN EFI_PHYSICAL_ADDRESS Start,
1298 IN UINT64 Length
1299 )
1300 /*++
1301
1302 Routine Description:
1303
1304 Flush cache with specified range.
1305
1306 Arguments:
1307
1308 Start - Start address
1309 Length - Length in bytes
1310
1311 Returns:
1312
1313 Status code
1314
1315 EFI_SUCCESS - success
1316
1317 --*/
1318 {
1319 SalFlushCache (Start, Length);
1320 return EFI_SUCCESS;
1321 }