]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/RuntimeDxe/EfiRuntimeLib/Ipf/RuntimeLib.c
300b2f6aaa7a4bda4131722cca8f10e9e1081a5d
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / RuntimeDxe / EfiRuntimeLib / Ipf / RuntimeLib.c
1 /*++
2
3 Copyright (c) 2004 - 2005, 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 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, &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 if (EFI_ERROR (Status)) {
315 return Status;
316 }
317
318 NewHandle = NULL;
319 return gBS->InstallProtocolInterface (
320 &NewHandle,
321 ClassGuid,
322 EFI_NATIVE_INTERFACE,
323 NULL
324 );
325 }
326
327 SAL_RETURN_REGS
328 EfiCallEsalService (
329 IN EFI_GUID *ClassGuid,
330 IN UINT64 FunctionId,
331 IN UINT64 Arg2,
332 IN UINT64 Arg3,
333 IN UINT64 Arg4,
334 IN UINT64 Arg5,
335 IN UINT64 Arg6,
336 IN UINT64 Arg7,
337 IN UINT64 Arg8
338 )
339 /*++
340
341 Routine Description:
342
343 Call module that is not linked direclty to this module. This code is IP
344 relative and hides the binding issues of virtual or physical calling. The
345 function that gets dispatched has extra arguments that include the registered
346 module global and a boolean flag to indicate if the system is in virutal mode.
347
348 Arguments:
349 ClassGuid - GUID of function
350 FunctionId - Function in ClassGuid to call
351 Arg2 - Argument 2 ClassGuid/FunctionId defined
352 Arg3 - Argument 3 ClassGuid/FunctionId defined
353 Arg4 - Argument 4 ClassGuid/FunctionId defined
354 Arg5 - Argument 5 ClassGuid/FunctionId defined
355 Arg6 - Argument 6 ClassGuid/FunctionId defined
356 Arg7 - Argument 7 ClassGuid/FunctionId defined
357 Arg8 - Argument 8 ClassGuid/FunctionId defined
358
359 Returns:
360 Status of ClassGuid/FuncitonId
361
362 --*/
363 {
364 SAL_RETURN_REGS ReturnReg;
365 SAL_EXTENDED_SAL_PROC EsalProc;
366
367 ReturnReg = GetEsalEntryPoint ();
368 if (ReturnReg.Status != EFI_SAL_SUCCESS) {
369 return ReturnReg;
370 }
371
372 if (ReturnReg.r11 & PSR_IT_MASK) {
373 //
374 // Virtual mode plabel to entry point
375 //
376 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r10;
377 } else {
378 //
379 // Physical mode plabel to entry point
380 //
381 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r9;
382 }
383
384 return EsalProc (
385 ClassGuid,
386 FunctionId,
387 Arg2,
388 Arg3,
389 Arg4,
390 Arg5,
391 Arg6,
392 Arg7,
393 Arg8
394 );
395 }
396
397 EFI_STATUS
398 EfiConvertPointer (
399 IN UINTN DebugDisposition,
400 IN OUT VOID *Address
401 )
402 /*++
403
404 Routine Description:
405
406 Determines the new virtual address that is to be used on subsequent memory accesses.
407
408 Arguments:
409
410 DebugDisposition - Supplies type information for the pointer being converted.
411 Address - A pointer to a pointer that is to be fixed to be the value needed
412 for the new virtual address mappings being applied.
413
414 Returns:
415
416 Status code
417
418 --*/
419 {
420 return mRT->ConvertPointer (DebugDisposition, Address);
421 }
422
423 BOOLEAN
424 EfiGoneVirtual (
425 VOID
426 )
427 /*++
428
429 Routine Description:
430 Return TRUE if SetVirtualAddressMap () has been called
431
432 Arguments:
433 NONE
434
435 Returns:
436 TRUE - If SetVirtualAddressMap () has been called
437
438 --*/
439 {
440 EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;
441 SAL_RETURN_REGS ReturnReg;
442
443 ReturnReg = EfiCallEsalService (&Guid, IsVirtual, 0, 0, 0, 0, 0, 0, 0);
444
445 return (BOOLEAN) (ReturnReg.r9 == 1);
446 }
447
448 BOOLEAN
449 EfiAtRuntime (
450 VOID
451 )
452 /*++
453
454 Routine Description:
455 Return TRUE if ExitBootService () has been called
456
457 Arguments:
458 NONE
459
460 Returns:
461 TRUE - If ExitBootService () has been called
462
463 --*/
464 {
465 EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;
466 SAL_RETURN_REGS ReturnReg;
467
468 ReturnReg = EfiCallEsalService (&Guid, IsEfiRuntime, 0, 0, 0, 0, 0, 0, 0);
469
470 return (BOOLEAN) (ReturnReg.r9 == 1);
471 }
472
473 EFI_STATUS
474 EfiReportStatusCode (
475 IN EFI_STATUS_CODE_TYPE CodeType,
476 IN EFI_STATUS_CODE_VALUE Value,
477 IN UINT32 Instance,
478 IN EFI_GUID * CallerId,
479 IN EFI_STATUS_CODE_DATA * Data OPTIONAL
480 )
481 /*++
482
483 Routine Description:
484
485 Status Code reporter
486
487 Arguments:
488
489 CodeType - Type of Status Code.
490
491 Value - Value to output for Status Code.
492
493 Instance - Instance Number of this status code.
494
495 CallerId - ID of the caller of this status code.
496
497 Data - Optional data associated with this status code.
498
499 Returns:
500
501 Status code
502
503 --*/
504 {
505 EFI_GUID Guid = EFI_EXTENDED_SAL_STATUS_CODE_SERVICES_PROTOCOL_GUID;
506 SAL_RETURN_REGS ReturnReg;
507
508
509 ReturnReg = EfiCallEsalService (
510 &Guid,
511 StatusCode,
512 (UINT64) CodeType,
513 (UINT64) Value,
514 (UINT64) Instance,
515 (UINT64) CallerId,
516 (UINT64) Data,
517 0,
518 0
519 );
520
521 return (EFI_STATUS) ReturnReg.Status;
522 }
523 //
524 // Sal Reset Driver Class
525 //
526 VOID
527 EfiResetSystem (
528 IN EFI_RESET_TYPE ResetType,
529 IN EFI_STATUS ResetStatus,
530 IN UINTN DataSize,
531 IN CHAR16 *ResetData
532 )
533 /*++
534
535 Routine Description:
536
537 Resets the entire platform.
538
539 Arguments:
540
541 ResetType - The type of reset to perform.
542 ResetStatus - The status code for the reset.
543 DataSize - The size, in bytes, of ResetData.
544 ResetData - A data buffer that includes a Null-terminated Unicode string, optionally
545 followed by additional binary data.
546
547 Returns:
548
549 None
550
551 --*/
552 {
553 EFI_GUID Guid = EFI_EXTENDED_SAL_RESET_SERVICES_PROTOCOL_GUID;
554
555 EfiCallEsalService (
556 &Guid,
557 ResetSystem,
558 (UINT64) ResetType,
559 (UINT64) ResetStatus,
560 (UINT64) DataSize,
561 (UINT64) ResetData,
562 0,
563 0,
564 0
565 );
566 }
567 //
568 // Sal MTC Driver Class
569 //
570 EFI_STATUS
571 EfiGetNextHighMonotonicCount (
572 OUT UINT32 *HighCount
573 )
574 /*++
575
576 Routine Description:
577
578 Returns the next high 32 bits of the platform's monotonic counter.
579
580 Arguments:
581
582 HighCount - Pointer to returned value.
583
584 Returns:
585
586 Status code
587
588 --*/
589 {
590 SAL_RETURN_REGS ReturnReg;
591
592 EFI_GUID Guid = EFI_EXTENDED_SAL_MTC_SERVICES_PROTOCOL_GUID;
593
594 ReturnReg = EfiCallEsalService (&Guid, GetNextHighMonotonicCount, (UINT64) HighCount, 0, 0, 0, 0, 0, 0);
595 return (EFI_STATUS) ReturnReg.Status;
596 }
597 //
598 // Sal Variable Driver Class
599 //
600 EFI_STATUS
601 EfiGetVariable (
602 IN CHAR16 *VariableName,
603 IN EFI_GUID * VendorGuid,
604 OUT UINT32 *Attributes OPTIONAL,
605 IN OUT UINTN *DataSize,
606 OUT VOID *Data
607 )
608 /*++
609
610 Routine Description:
611
612 Returns the value of a variable.
613
614 Arguments:
615
616 VariableName - A Null-terminated Unicode string that is the name of the
617 vendor's variable.
618 VendorGuid - A unique identifier for the vendor.
619 Attributes - If not NULL, a pointer to the memory location to return the
620 attributes bitmask for the variable.
621 DataSize - On input, the size in bytes of the return Data buffer.
622 On output the size of data returned in Data.
623 Data - The buffer to return the contents of the variable.
624
625 Returns:
626
627 Status code
628
629 --*/
630 {
631 SAL_RETURN_REGS ReturnReg;
632 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
633
634 ReturnReg = EfiCallEsalService (
635 &Guid,
636 EsalGetVariable,
637 (UINT64) VariableName,
638 (UINT64) VendorGuid,
639 (UINT64) Attributes,
640 (UINT64) DataSize,
641 (UINT64) Data,
642 0,
643 0
644 );
645 return (EFI_STATUS) ReturnReg.Status;
646 }
647
648 EFI_STATUS
649 EfiGetNextVariableName (
650 IN OUT UINTN *VariableNameSize,
651 IN OUT CHAR16 *VariableName,
652 IN OUT EFI_GUID *VendorGuid
653 )
654 /*++
655
656 Routine Description:
657
658 Enumerates the current variable names.
659
660 Arguments:
661
662 VariableNameSize - The size of the VariableName buffer.
663 VariableName - On input, supplies the last VariableName that was returned
664 by GetNextVariableName().
665 On output, returns the Nullterminated Unicode string of the
666 current variable.
667 VendorGuid - On input, supplies the last VendorGuid that was returned by
668 GetNextVariableName().
669 On output, returns the VendorGuid of the current variable.
670
671 Returns:
672
673 Status code
674
675 --*/
676 {
677 SAL_RETURN_REGS ReturnReg;
678 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
679
680 ReturnReg = EfiCallEsalService (
681 &Guid,
682 EsalGetNextVariableName,
683 (UINT64) VariableNameSize,
684 (UINT64) VariableName,
685 (UINT64) VendorGuid,
686 0,
687 0,
688 0,
689 0
690 );
691 return (EFI_STATUS) ReturnReg.Status;
692 }
693
694 EFI_STATUS
695 EfiSetVariable (
696 IN CHAR16 *VariableName,
697 IN EFI_GUID *VendorGuid,
698 IN UINT32 Attributes,
699 IN UINTN DataSize,
700 IN VOID *Data
701 )
702 /*++
703
704 Routine Description:
705
706 Sets the value of a variable.
707
708 Arguments:
709
710 VariableName - A Null-terminated Unicode string that is the name of the
711 vendor's variable.
712 VendorGuid - A unique identifier for the vendor.
713 Attributes - Attributes bitmask to set for the variable.
714 DataSize - The size in bytes of the Data buffer.
715 Data - The contents for the variable.
716
717 Returns:
718
719 Status code
720
721 --*/
722 {
723 SAL_RETURN_REGS ReturnReg;
724 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
725
726 ReturnReg = EfiCallEsalService (
727 &Guid,
728 EsalSetVariable,
729 (UINT64) VariableName,
730 (UINT64) VendorGuid,
731 (UINT64) Attributes,
732 (UINT64) DataSize,
733 (UINT64) Data,
734 0,
735 0
736 );
737 return (EFI_STATUS) ReturnReg.Status;
738 }
739
740 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
741
742 EFI_STATUS
743 EfiQueryVariableInfo (
744 IN UINT32 Attributes,
745 OUT UINT64 *MaximumVariableStorageSize,
746 OUT UINT64 *RemainingVariableStorageSize,
747 OUT UINT64 *MaximumVariableSize
748 )
749 /*++
750
751 Routine Description:
752
753 This code returns information about the EFI variables.
754
755 Arguments:
756
757 Attributes Attributes bitmask to specify the type of variables
758 on which to return information.
759 MaximumVariableStorageSize Pointer to the maximum size of the storage space available
760 for the EFI variables associated with the attributes specified.
761 RemainingVariableStorageSize Pointer to the remaining size of the storage space available
762 for the EFI variables associated with the attributes specified.
763 MaximumVariableSize Pointer to the maximum size of the individual EFI variables
764 associated with the attributes specified.
765
766 Returns:
767
768 Status code
769
770 --*/
771 {
772 SAL_RETURN_REGS ReturnReg;
773 EFI_GUID Guid = EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID;
774
775 ReturnReg = EfiCallEsalService (
776 &Guid,
777 EsalQueryVariableInfo,
778 (UINT64) Attributes,
779 (UINT64) MaximumVariableStorageSize,
780 (UINT64) RemainingVariableStorageSize,
781 (UINT64) MaximumVariableSize,
782 0,
783 0,
784 0
785 );
786 return (EFI_STATUS) ReturnReg.Status;
787 }
788
789 #endif
790
791 //
792 // Sal RTC Driver Class.
793 //
794 EFI_STATUS
795 EfiGetTime (
796 OUT EFI_TIME *Time,
797 OUT EFI_TIME_CAPABILITIES *Capabilities
798 )
799 /*++
800
801 Routine Description:
802
803 Returns the current time and date information, and the time-keeping
804 capabilities of the hardware platform.
805
806 Arguments:
807
808 Time - A pointer to storage to receive a snapshot of the current time.
809 Capabilities - An optional pointer to a buffer to receive the real time clock device's
810 capabilities.
811
812 Returns:
813
814 Status code
815
816 --*/
817 {
818 SAL_RETURN_REGS ReturnReg;
819 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
820
821 ReturnReg = EfiCallEsalService (&Guid, GetTime, (UINT64) Time, (UINT64) Capabilities, 0, 0, 0, 0, 0);
822 return ReturnReg.Status;
823 }
824
825 EFI_STATUS
826 EfiSetTime (
827 OUT EFI_TIME *Time
828 )
829 /*++
830
831 Routine Description:
832
833 Sets the current local time and date information.
834
835 Arguments:
836
837 Time - A pointer to the current time.
838
839 Returns:
840
841 Status code
842
843 --*/
844 {
845 SAL_RETURN_REGS ReturnReg;
846
847 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
848
849 ReturnReg = EfiCallEsalService (&Guid, SetTime, (UINT64) Time, 0, 0, 0, 0, 0, 0);
850 return ReturnReg.Status;
851 }
852
853 EFI_STATUS
854 EfiGetWakeupTime (
855 OUT BOOLEAN *Enabled,
856 OUT BOOLEAN *Pending,
857 OUT EFI_TIME *Time
858 )
859 /*++
860
861 Routine Description:
862
863 Returns the current wakeup alarm clock setting.
864
865 Arguments:
866
867 Enabled - Indicates if the alarm is currently enabled or disabled.
868 Pending - Indicates if the alarm signal is pending and requires acknowledgement.
869 Time - The current alarm setting.
870
871 Returns:
872
873 Status code
874
875 --*/
876 {
877 SAL_RETURN_REGS ReturnReg;
878
879 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
880
881 ReturnReg = EfiCallEsalService (&Guid, GetWakeupTime, (UINT64) Enabled, (UINT64) Pending, (UINT64) Time, 0, 0, 0, 0);
882 return ReturnReg.Status;
883 }
884
885 EFI_STATUS
886 EfiSetWakeupTime (
887 IN BOOLEAN Enable,
888 IN EFI_TIME *Time
889 )
890 /*++
891
892 Routine Description:
893
894 Sets the system wakeup alarm clock time.
895
896 Arguments:
897
898 Enable - Enable or disable the wakeup alarm.
899 Time - If Enable is TRUE, the time to set the wakeup alarm for.
900 If Enable is FALSE, then this parameter is optional, and may be NULL.
901
902 Returns:
903
904 Status code
905
906 --*/
907 {
908 SAL_RETURN_REGS ReturnReg;
909
910 EFI_GUID Guid = EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID;
911
912 ReturnReg = EfiCallEsalService (&Guid, SetWakeupTime, (UINT64) Enable, (UINT64) Time, 0, 0, 0, 0, 0);
913 return ReturnReg.Status;
914 }
915
916
917
918 //
919 // Base IO Services
920 //
921 EFI_STATUS
922 EfiIoRead (
923 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
924 IN UINT64 Address,
925 IN UINTN Count,
926 IN OUT VOID *Buffer
927 )
928 /*++
929
930 Routine Description:
931 Perform an IO read into Buffer.
932
933 Arguments:
934 Width - Width of read transaction, and repeat operation to use
935 Address - IO address to read
936 Count - Number of times to read the IO address.
937 Buffer - Buffer to read data into. size is Width * Count
938
939 Returns:
940 Status code
941
942 --*/
943 {
944
945 SAL_RETURN_REGS ReturnReg;
946
947 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
948
949 ReturnReg = EfiCallEsalService (&Guid, IoRead, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
950
951 return ReturnReg.Status;
952
953 }
954
955 EFI_STATUS
956 EfiIoWrite (
957 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
958 IN UINT64 Address,
959 IN UINTN Count,
960 IN OUT VOID *Buffer
961 )
962 /*++
963
964 Routine Description:
965 Perform an IO write into Buffer.
966
967 Arguments:
968 Width - Width of write transaction, and repeat operation to use
969 Address - IO address to write
970 Count - Number of times to write the IO address.
971 Buffer - Buffer to write data from. size is Width * Count
972
973 Returns:
974 Status code
975
976 --*/
977 {
978
979 SAL_RETURN_REGS ReturnReg;
980
981 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
982
983 ReturnReg = EfiCallEsalService (&Guid, IoWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
984
985 return ReturnReg.Status;
986
987 }
988
989 EFI_STATUS
990 EfiMemRead (
991 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
992 IN UINT64 Address,
993 IN UINTN Count,
994 IN OUT VOID *Buffer
995 )
996 /*++
997
998 Routine Description:
999 Perform a Memory mapped IO read into Buffer.
1000
1001 Arguments:
1002 Width - Width of each read transaction.
1003 Address - Memory mapped IO address to read
1004 Count - Number of Width quanta to read
1005 Buffer - Buffer to read data into. size is Width * Count
1006
1007 Returns:
1008 Status code
1009
1010 --*/
1011 {
1012
1013 SAL_RETURN_REGS ReturnReg;
1014
1015 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
1016
1017 ReturnReg = EfiCallEsalService (&Guid, MemRead, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
1018
1019 return ReturnReg.Status;
1020
1021 }
1022
1023 EFI_STATUS
1024 EfiMemWrite (
1025 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
1026 IN UINT64 Address,
1027 IN UINTN Count,
1028 IN OUT VOID *Buffer
1029 )
1030 /*++
1031
1032 Routine Description:
1033 Perform a memory mapped IO write into Buffer.
1034
1035 Arguments:
1036 Width - Width of write transaction, and repeat operation to use
1037 Address - IO address to write
1038 Count - Number of times to write the IO address.
1039 Buffer - Buffer to write data from. size is Width * Count
1040
1041 Returns:
1042 Status code
1043
1044 --*/
1045 {
1046
1047 SAL_RETURN_REGS ReturnReg;
1048
1049 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
1050
1051 ReturnReg = EfiCallEsalService (&Guid, MemWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
1052
1053 return ReturnReg.Status;
1054
1055 }
1056
1057
1058 #define EFI_PCI_ADDRESS_IPF(_seg, _bus, _devfunc, _reg) \
1059 (((_seg) << 24) | ((_bus) << 16) | ((_devfunc) << 8) | (_reg)) & 0xFFFFFFFF
1060
1061 //
1062 // PCI Class Functions
1063 //
1064 UINT8
1065 PciRead8 (
1066 UINT8 Segment,
1067 UINT8 Bus,
1068 UINT8 DevFunc,
1069 UINT8 Register
1070 )
1071 /*++
1072
1073 Routine Description:
1074 Perform an one byte PCI config cycle read
1075
1076 Arguments:
1077 Segment - PCI Segment ACPI _SEG
1078 Bus - PCI Bus
1079 DevFunc - PCI Device(7:3) and Func(2:0)
1080 Register - PCI config space register
1081
1082 Returns:
1083 Data read from PCI config space
1084
1085 --*/
1086 {
1087 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1088 UINT64 Address;
1089 SAL_RETURN_REGS Return;
1090
1091 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1092 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 1, 0, 0, 0, 0, 0);
1093
1094 return (UINT8) Return.r9;
1095 }
1096
1097
1098 UINT16
1099 PciRead16 (
1100 UINT8 Segment,
1101 UINT8 Bus,
1102 UINT8 DevFunc,
1103 UINT8 Register
1104 )
1105 /*++
1106
1107 Routine Description:
1108 Perform an two byte PCI config cycle read
1109
1110 Arguments:
1111 Segment - PCI Segment ACPI _SEG
1112 Bus - PCI Bus
1113 DevFunc - PCI Device(7:3) and Func(2:0)
1114 Register - PCI config space register
1115
1116 Returns:
1117 Data read from PCI config space
1118
1119 --*/
1120 {
1121 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1122 UINT64 Address;
1123 SAL_RETURN_REGS Return;
1124
1125 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1126 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 2, 0, 0, 0, 0, 0);
1127
1128 return (UINT16) Return.r9;
1129 }
1130
1131 UINT32
1132 PciRead32 (
1133 UINT8 Segment,
1134 UINT8 Bus,
1135 UINT8 DevFunc,
1136 UINT8 Register
1137 )
1138 /*++
1139
1140 Routine Description:
1141 Perform an four byte PCI config cycle read
1142
1143 Arguments:
1144 Segment - PCI Segment ACPI _SEG
1145 Bus - PCI Bus
1146 DevFunc - PCI Device(7:3) and Func(2:0)
1147 Register - PCI config space register
1148
1149 Returns:
1150 Data read from PCI config space
1151
1152 --*/
1153 {
1154 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1155 UINT64 Address;
1156 SAL_RETURN_REGS Return;
1157
1158 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1159 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 4, 0, 0, 0, 0, 0);
1160
1161 return (UINT32) Return.r9;
1162 }
1163
1164 VOID
1165 PciWrite8 (
1166 UINT8 Segment,
1167 UINT8 Bus,
1168 UINT8 DevFunc,
1169 UINT8 Register,
1170 UINT8 Data
1171 )
1172 /*++
1173
1174 Routine Description:
1175 Perform an one byte PCI config cycle write
1176
1177 Arguments:
1178 Segment - PCI Segment ACPI _SEG
1179 Bus - PCI Bus
1180 DevFunc - PCI Device(7:3) and Func(2:0)
1181 Register - PCI config space register
1182 Data - Data to write
1183
1184 Returns:
1185 NONE
1186
1187 --*/
1188 {
1189 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1190 UINT64 Address;
1191
1192 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1193 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 1, Data, 0, 0, 0, 0);
1194 }
1195
1196 VOID
1197 PciWrite16 (
1198 UINT8 Segment,
1199 UINT8 Bus,
1200 UINT8 DevFunc,
1201 UINT8 Register,
1202 UINT16 Data
1203 )
1204 /*++
1205
1206 Routine Description:
1207 Perform an two byte PCI config cycle write
1208
1209 Arguments:
1210 Segment - PCI Segment ACPI _SEG
1211 Bus - PCI Bus
1212 DevFunc - PCI Device(7:3) and Func(2:0)
1213 Register - PCI config space register
1214 Data - Data to write
1215
1216 Returns:
1217 None.
1218
1219 --*/
1220 {
1221 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1222 UINT64 Address;
1223
1224 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1225 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 2, Data, 0, 0, 0, 0);
1226 }
1227
1228 VOID
1229 PciWrite32 (
1230 UINT8 Segment,
1231 UINT8 Bus,
1232 UINT8 DevFunc,
1233 UINT8 Register,
1234 UINT32 Data
1235 )
1236 /*++
1237
1238 Routine Description:
1239 Perform an four byte PCI config cycle write
1240
1241 Arguments:
1242 Segment - PCI Segment ACPI _SEG
1243 Bus - PCI Bus
1244 DevFunc - PCI Device(7:3) and Func(2:0)
1245 Register - PCI config space register
1246 Data - Data to write
1247
1248 Returns:
1249 NONE
1250
1251 --*/
1252 {
1253 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1254 UINT64 Address;
1255
1256 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1257 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 4, Data, 0, 0, 0, 0);
1258 }
1259
1260 //
1261 // Stall class functions
1262 //
1263 VOID
1264 EfiStall (
1265 IN UINTN Microseconds
1266 )
1267 /*++
1268
1269 Routine Description:
1270 Delay for at least the request number of microseconds
1271
1272 Arguments:
1273 Microseconds - Number of microseconds to delay.
1274
1275 Returns:
1276 NONE
1277
1278 --*/
1279 {
1280 EFI_GUID Guid = EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID;
1281
1282 if (EfiAtRuntime ()) {
1283 EfiCallEsalService (&Guid, Stall, Microseconds, 4, 0, 0, 0, 0, 0);
1284 } else {
1285 gBS->Stall (Microseconds);
1286 }
1287 }
1288 //
1289 // Cache Flush Routine.
1290 //
1291 EFI_STATUS
1292 EfiCpuFlushCache (
1293 IN EFI_PHYSICAL_ADDRESS Start,
1294 IN UINT64 Length
1295 )
1296 /*++
1297
1298 Routine Description:
1299
1300 Flush cache with specified range.
1301
1302 Arguments:
1303
1304 Start - Start address
1305 Length - Length in bytes
1306
1307 Returns:
1308
1309 Status code
1310
1311 EFI_SUCCESS - success
1312
1313 --*/
1314 {
1315 SalFlushCache (Start, Length);
1316 return EFI_SUCCESS;
1317 }