]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/RuntimeDxe/EfiRuntimeLib/Ipf/RuntimeLib.c
MdeModulePkg PciBusDxe: Add typecast to eliminate possible "loss of precision" warning.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / RuntimeDxe / EfiRuntimeLib / Ipf / RuntimeLib.c
1 /*++
2
3 Copyright (c) 2004 - 2010, 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 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 ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);
951
952 return ReturnReg.Status;
953
954 }
955
956 EFI_STATUS
957 EfiIoWrite (
958 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
959 IN UINT64 Address,
960 IN UINTN Count,
961 IN OUT VOID *Buffer
962 )
963 /*++
964
965 Routine Description:
966 Perform an IO write into Buffer.
967
968 Arguments:
969 Width - Width of write transaction, and repeat operation to use
970 Address - IO address to write
971 Count - Number of times to write the IO address.
972 Buffer - Buffer to write data from. size is Width * Count
973
974 Returns:
975 Status code
976
977 --*/
978 {
979
980 SAL_RETURN_REGS ReturnReg;
981
982 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
983
984 ReturnReg = EfiCallEsalService (&Guid, IoWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
985
986 return ReturnReg.Status;
987
988 }
989
990 EFI_STATUS
991 EfiMemRead (
992 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
993 IN UINT64 Address,
994 IN UINTN Count,
995 IN OUT VOID *Buffer
996 )
997 /*++
998
999 Routine Description:
1000 Perform a Memory mapped IO read into Buffer.
1001
1002 Arguments:
1003 Width - Width of each read transaction.
1004 Address - Memory mapped IO address to read
1005 Count - Number of Width quanta to read
1006 Buffer - Buffer to read data into. size is Width * Count
1007
1008 Returns:
1009 Status code
1010
1011 --*/
1012 {
1013
1014 SAL_RETURN_REGS ReturnReg;
1015
1016 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
1017
1018 ReturnReg = EfiCallEsalService (&Guid, MemRead, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
1019 ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);
1020
1021 return ReturnReg.Status;
1022
1023 }
1024
1025 EFI_STATUS
1026 EfiMemWrite (
1027 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
1028 IN UINT64 Address,
1029 IN UINTN Count,
1030 IN OUT VOID *Buffer
1031 )
1032 /*++
1033
1034 Routine Description:
1035 Perform a memory mapped IO write into Buffer.
1036
1037 Arguments:
1038 Width - Width of write transaction, and repeat operation to use
1039 Address - IO address to write
1040 Count - Number of times to write the IO address.
1041 Buffer - Buffer to write data from. size is Width * Count
1042
1043 Returns:
1044 Status code
1045
1046 --*/
1047 {
1048
1049 SAL_RETURN_REGS ReturnReg;
1050
1051 EFI_GUID Guid = EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID;
1052
1053 ReturnReg = EfiCallEsalService (&Guid, MemWrite, (UINT64) Width, Address, Count, (UINT64) Buffer, 0, 0, 0);
1054
1055 return ReturnReg.Status;
1056
1057 }
1058
1059
1060 #define EFI_PCI_ADDRESS_IPF(_seg, _bus, _devfunc, _reg) \
1061 (((_seg) << 24) | ((_bus) << 16) | ((_devfunc) << 8) | (_reg)) & 0xFFFFFFFF
1062
1063 //
1064 // PCI Class Functions
1065 //
1066 UINT8
1067 PciRead8 (
1068 UINT8 Segment,
1069 UINT8 Bus,
1070 UINT8 DevFunc,
1071 UINT8 Register
1072 )
1073 /*++
1074
1075 Routine Description:
1076 Perform an one byte PCI config cycle read
1077
1078 Arguments:
1079 Segment - PCI Segment ACPI _SEG
1080 Bus - PCI Bus
1081 DevFunc - PCI Device(7:3) and Func(2:0)
1082 Register - PCI config space register
1083
1084 Returns:
1085 Data read from PCI config space
1086
1087 --*/
1088 {
1089 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1090 UINT64 Address;
1091 SAL_RETURN_REGS Return;
1092
1093 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1094 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 1, 0, 0, 0, 0, 0);
1095
1096 return (UINT8) Return.r9;
1097 }
1098
1099
1100 UINT16
1101 PciRead16 (
1102 UINT8 Segment,
1103 UINT8 Bus,
1104 UINT8 DevFunc,
1105 UINT8 Register
1106 )
1107 /*++
1108
1109 Routine Description:
1110 Perform an two byte PCI config cycle read
1111
1112 Arguments:
1113 Segment - PCI Segment ACPI _SEG
1114 Bus - PCI Bus
1115 DevFunc - PCI Device(7:3) and Func(2:0)
1116 Register - PCI config space register
1117
1118 Returns:
1119 Data read from PCI config space
1120
1121 --*/
1122 {
1123 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1124 UINT64 Address;
1125 SAL_RETURN_REGS Return;
1126
1127 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1128 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 2, 0, 0, 0, 0, 0);
1129
1130 return (UINT16) Return.r9;
1131 }
1132
1133 UINT32
1134 PciRead32 (
1135 UINT8 Segment,
1136 UINT8 Bus,
1137 UINT8 DevFunc,
1138 UINT8 Register
1139 )
1140 /*++
1141
1142 Routine Description:
1143 Perform an four byte PCI config cycle read
1144
1145 Arguments:
1146 Segment - PCI Segment ACPI _SEG
1147 Bus - PCI Bus
1148 DevFunc - PCI Device(7:3) and Func(2:0)
1149 Register - PCI config space register
1150
1151 Returns:
1152 Data read from PCI config space
1153
1154 --*/
1155 {
1156 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1157 UINT64 Address;
1158 SAL_RETURN_REGS Return;
1159
1160 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1161 Return = EfiCallEsalService (&Guid, SalPciConfigRead, Address, 4, 0, 0, 0, 0, 0);
1162
1163 return (UINT32) Return.r9;
1164 }
1165
1166 VOID
1167 PciWrite8 (
1168 UINT8 Segment,
1169 UINT8 Bus,
1170 UINT8 DevFunc,
1171 UINT8 Register,
1172 UINT8 Data
1173 )
1174 /*++
1175
1176 Routine Description:
1177 Perform an one byte PCI config cycle write
1178
1179 Arguments:
1180 Segment - PCI Segment ACPI _SEG
1181 Bus - PCI Bus
1182 DevFunc - PCI Device(7:3) and Func(2:0)
1183 Register - PCI config space register
1184 Data - Data to write
1185
1186 Returns:
1187 NONE
1188
1189 --*/
1190 {
1191 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1192 UINT64 Address;
1193
1194 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1195 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 1, Data, 0, 0, 0, 0);
1196 }
1197
1198 VOID
1199 PciWrite16 (
1200 UINT8 Segment,
1201 UINT8 Bus,
1202 UINT8 DevFunc,
1203 UINT8 Register,
1204 UINT16 Data
1205 )
1206 /*++
1207
1208 Routine Description:
1209 Perform an two byte PCI config cycle write
1210
1211 Arguments:
1212 Segment - PCI Segment ACPI _SEG
1213 Bus - PCI Bus
1214 DevFunc - PCI Device(7:3) and Func(2:0)
1215 Register - PCI config space register
1216 Data - Data to write
1217
1218 Returns:
1219 None.
1220
1221 --*/
1222 {
1223 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1224 UINT64 Address;
1225
1226 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1227 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 2, Data, 0, 0, 0, 0);
1228 }
1229
1230 VOID
1231 PciWrite32 (
1232 UINT8 Segment,
1233 UINT8 Bus,
1234 UINT8 DevFunc,
1235 UINT8 Register,
1236 UINT32 Data
1237 )
1238 /*++
1239
1240 Routine Description:
1241 Perform an four byte PCI config cycle write
1242
1243 Arguments:
1244 Segment - PCI Segment ACPI _SEG
1245 Bus - PCI Bus
1246 DevFunc - PCI Device(7:3) and Func(2:0)
1247 Register - PCI config space register
1248 Data - Data to write
1249
1250 Returns:
1251 NONE
1252
1253 --*/
1254 {
1255 EFI_GUID Guid = EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID;
1256 UINT64 Address;
1257
1258 Address = EFI_PCI_ADDRESS_IPF (Segment, Bus, DevFunc, Register);
1259 EfiCallEsalService (&Guid, SalPciConfigWrite, Address, 4, Data, 0, 0, 0, 0);
1260 }
1261
1262 //
1263 // Stall class functions
1264 //
1265 VOID
1266 EfiStall (
1267 IN UINTN Microseconds
1268 )
1269 /*++
1270
1271 Routine Description:
1272 Delay for at least the request number of microseconds
1273
1274 Arguments:
1275 Microseconds - Number of microseconds to delay.
1276
1277 Returns:
1278 NONE
1279
1280 --*/
1281 {
1282 EFI_GUID Guid = EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID;
1283
1284 if (EfiAtRuntime ()) {
1285 EfiCallEsalService (&Guid, Stall, Microseconds, 4, 0, 0, 0, 0, 0);
1286 } else {
1287 gBS->Stall (Microseconds);
1288 }
1289 }
1290 //
1291 // Cache Flush Routine.
1292 //
1293 EFI_STATUS
1294 EfiCpuFlushCache (
1295 IN EFI_PHYSICAL_ADDRESS Start,
1296 IN UINT64 Length
1297 )
1298 /*++
1299
1300 Routine Description:
1301
1302 Flush cache with specified range.
1303
1304 Arguments:
1305
1306 Start - Start address
1307 Length - Length in bytes
1308
1309 Returns:
1310
1311 Status code
1312
1313 EFI_SUCCESS - success
1314
1315 --*/
1316 {
1317 SalFlushCache (Start, Length);
1318 return EFI_SUCCESS;
1319 }