]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/RuntimeDxe/EfiRuntimeLib/X64/RuntimeLib.c
Update the copyright notice format
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / RuntimeDxe / EfiRuntimeLib / X64 / RuntimeLib.c
1 /*++
2
3 Copyright (c) 2005 - 2008, 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 drivers.
19
20 --*/
21
22 #include "Tiano.h"
23 #include "EfiRuntimeLib.h"
24 #include EFI_PROTOCOL_DEFINITION (CpuIo)
25 #include EFI_PROTOCOL_DEFINITION (FirmwareVolumeBlock)
26 #include EFI_GUID_DEFINITION (StatusCodeCallerId)
27 #include EFI_ARCH_PROTOCOL_DEFINITION (StatusCode)
28
29 //
30 // Driver Lib Module Globals
31 //
32 static EFI_RUNTIME_SERVICES *mRT;
33 static EFI_EVENT mRuntimeNotifyEvent = NULL;
34 static EFI_EVENT mEfiVirtualNotifyEvent = NULL;
35 static BOOLEAN mRuntimeLibInitialized = FALSE;
36 static BOOLEAN mEfiGoneVirtual = FALSE;
37
38 //
39 // Runtime Global, but you should use the Lib functions
40 //
41 EFI_CPU_IO_PROTOCOL *gCpuIo;
42 BOOLEAN mEfiAtRuntime = FALSE;
43 FVB_ENTRY *mFvbEntry;
44
45 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
46 static EFI_STATUS_CODE_PROTOCOL *gStatusCode = NULL;
47 #endif
48
49 EFI_STATUS
50 EfiConvertPointer (
51 IN UINTN DebugDisposition,
52 IN OUT VOID *Address
53 )
54 /*++
55
56 Routine Description:
57
58 Determines the new virtual address that is to be used on subsequent memory accesses.
59
60 Arguments:
61
62 DebugDisposition - Supplies type information for the pointer being converted.
63 Address - A pointer to a pointer that is to be fixed to be the value needed
64 for the new virtual address mappings being applied.
65
66 Returns:
67
68 Status code
69
70 --*/
71 {
72 return mRT->ConvertPointer (DebugDisposition, Address);
73 }
74
75 EFI_STATUS
76 EfiConvertInternalPointer (
77 IN OUT VOID *Address
78 )
79 /*++
80
81 Routine Description:
82
83 Call EfiConvertPointer() to convert internal pointer.
84
85 Arguments:
86
87 Address - A pointer to a pointer that is to be fixed to be the value needed
88 for the new virtual address mappings being applied.
89
90 Returns:
91
92 Status code
93
94 --*/
95 {
96 return EfiConvertPointer (EFI_INTERNAL_POINTER, Address);
97 }
98
99 VOID
100 EFIAPI
101 EfiRuntimeLibFvbVirtualNotifyEvent (
102 IN EFI_EVENT Event,
103 IN VOID *Context
104 )
105 /*++
106
107 Routine Description:
108
109 Convert all pointers in mFvbEntry after ExitBootServices.
110
111 Arguments:
112
113 Event - The Event that is being processed
114
115 Context - Event Context
116
117 Returns:
118
119 None
120
121 --*/
122 {
123 UINTN Index;
124 if (mFvbEntry != NULL) {
125 for (Index = 0; Index < MAX_FVB_COUNT; Index++) {
126 if (NULL != mFvbEntry[Index].Fvb) {
127 EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->GetBlockSize);
128 EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->GetPhysicalAddress);
129 EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->GetVolumeAttributes);
130 EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->SetVolumeAttributes);
131 EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->Read);
132 EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->Write);
133 EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb->EraseBlocks);
134 EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].Fvb);
135 }
136
137 if (NULL != mFvbEntry[Index].FvbExtension) {
138 EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].FvbExtension->EraseFvbCustomBlock);
139 EfiConvertInternalPointer ((VOID **) &mFvbEntry[Index].FvbExtension);
140 }
141 }
142
143 EfiConvertInternalPointer ((VOID **) &mFvbEntry);
144 }
145 }
146
147 VOID
148 EFIAPI
149 RuntimeDriverExitBootServices (
150 IN EFI_EVENT Event,
151 IN VOID *Context
152 )
153 /*++
154
155 Routine Description:
156
157 Set AtRuntime flag as TRUE after ExitBootServices
158
159 Arguments:
160
161 Event - The Event that is being processed
162
163 Context - Event Context
164
165 Returns:
166
167 None
168
169 --*/
170 {
171 mEfiAtRuntime = TRUE;
172 }
173
174 extern BOOLEAN gEfiFvbInitialized;
175
176 VOID
177 EFIAPI
178 EfiRuntimeLibVirtualNotifyEvent (
179 IN EFI_EVENT Event,
180 IN VOID *Context
181 )
182 /*++
183
184 Routine Description:
185
186 Fixup internal data so that EFI can be call in virtual mode.
187 Call the passed in Child Notify event and convert any pointers in
188 lib to virtual mode.
189
190 Arguments:
191
192 Event - The Event that is being processed
193
194 Context - Event Context
195
196 Returns:
197
198 None
199
200 --*/
201 {
202 EFI_EVENT_NOTIFY ChildNotifyEventHandler;
203
204 if (Context != NULL) {
205 ChildNotifyEventHandler = (EFI_EVENT_NOTIFY) (UINTN) Context;
206 ChildNotifyEventHandler (Event, NULL);
207 }
208
209 if (gEfiFvbInitialized) {
210 EfiRuntimeLibFvbVirtualNotifyEvent (Event, Context);
211 }
212 //
213 // Update global for Runtime Services Table and IO
214 //
215 EfiConvertInternalPointer ((VOID **) &gCpuIo);
216 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
217 if (gStatusCode != NULL) {
218 EfiConvertInternalPointer ((VOID **) &gStatusCode->ReportStatusCode);
219 EfiConvertInternalPointer ((VOID **) &gStatusCode);
220 }
221 #endif
222 EfiConvertInternalPointer ((VOID **) &mRT);
223
224 //
225 // Clear out BootService globals
226 //
227 gBS = NULL;
228 gST = NULL;
229 mEfiGoneVirtual = TRUE;
230 }
231
232 EFI_STATUS
233 EfiInitializeRuntimeDriverLib (
234 IN EFI_HANDLE ImageHandle,
235 IN EFI_SYSTEM_TABLE *SystemTable,
236 IN EFI_EVENT_NOTIFY GoVirtualChildEvent
237 )
238 /*++
239
240 Routine Description:
241
242 Intialize runtime Driver Lib if it has not yet been initialized.
243
244 Arguments:
245
246 ImageHandle - The firmware allocated handle for the EFI image.
247
248 SystemTable - A pointer to the EFI System Table.
249
250 GoVirtualChildEvent - Caller can register a virtual notification event.
251
252 Returns:
253
254 EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
255
256 --*/
257 {
258 EFI_STATUS Status;
259
260 if (mRuntimeLibInitialized) {
261 return EFI_ALREADY_STARTED;
262 }
263
264 mRuntimeLibInitialized = TRUE;
265
266 gST = SystemTable;
267 ASSERT (gST != NULL);
268
269 gBS = SystemTable->BootServices;
270 ASSERT (gBS != NULL);
271 mRT = SystemTable->RuntimeServices;
272 ASSERT (mRT != NULL);
273
274 Status = EfiLibGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
275 ASSERT_EFI_ERROR (Status);
276
277 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
278 Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID **)&gStatusCode);
279 if (EFI_ERROR (Status)) {
280 gStatusCode = NULL;
281 }
282 #endif
283
284 Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID **) &gCpuIo);
285 if (EFI_ERROR (Status)) {
286 gCpuIo = NULL;
287 }
288
289 //
290 // Register our ExitBootServices () notify function
291 //
292 Status = gBS->CreateEvent (
293 EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
294 EFI_TPL_NOTIFY,
295 RuntimeDriverExitBootServices,
296 NULL,
297 &mRuntimeNotifyEvent
298 );
299 ASSERT_EFI_ERROR (Status);
300
301 //
302 // Register SetVirtualAddressMap () notify function
303 //
304 Status = gBS->CreateEvent (
305 EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
306 EFI_TPL_NOTIFY,
307 EfiRuntimeLibVirtualNotifyEvent,
308 (VOID *) (UINTN) GoVirtualChildEvent,
309 &mEfiVirtualNotifyEvent
310 );
311 ASSERT_EFI_ERROR (Status);
312
313 return EFI_SUCCESS;
314 }
315
316 EFI_STATUS
317 EfiShutdownRuntimeDriverLib (
318 VOID
319 )
320 /*++
321
322 Routine Description:
323
324 This routine will free some resources which have been allocated in
325 EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error,
326 it must call this routine to free the allocated resource before the exiting.
327
328 Arguments:
329
330 None
331
332 Returns:
333
334 EFI_SUCCESS - Shotdown the Runtime Driver Lib successfully
335 EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all
336
337 --*/
338 {
339 EFI_STATUS Status;
340
341 if (!mRuntimeLibInitialized) {
342 //
343 // You must call EfiInitializeRuntimeDriverLib() first
344 //
345 return EFI_UNSUPPORTED;
346 }
347
348 mRuntimeLibInitialized = FALSE;
349
350 //
351 // Close our ExitBootServices () notify function
352 //
353 if (mRuntimeNotifyEvent != NULL) {
354 Status = gBS->CloseEvent (mRuntimeNotifyEvent);
355 ASSERT_EFI_ERROR (Status);
356 }
357
358 //
359 // Close SetVirtualAddressMap () notify function
360 //
361 if (mEfiVirtualNotifyEvent != NULL) {
362 Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);
363 ASSERT_EFI_ERROR (Status);
364 }
365
366 return EFI_SUCCESS;
367 }
368
369 EFI_STATUS
370 EfiInitializeSmmDriverLib (
371 IN EFI_HANDLE ImageHandle,
372 IN EFI_SYSTEM_TABLE *SystemTable
373 )
374 /*++
375
376 Routine Description:
377
378 Intialize runtime Driver Lib if it has not yet been initialized.
379
380 Arguments:
381
382 ImageHandle - The firmware allocated handle for the EFI image.
383
384 SystemTable - A pointer to the EFI System Table.
385
386 Returns:
387
388 EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
389
390 --*/
391 {
392 EFI_STATUS Status;
393
394 if (mRuntimeLibInitialized) {
395 return EFI_ALREADY_STARTED;
396 }
397
398 mRuntimeLibInitialized = TRUE;
399
400 gST = SystemTable;
401 ASSERT (gST != NULL);
402
403 gBS = SystemTable->BootServices;
404 ASSERT (gBS != NULL);
405 mRT = SystemTable->RuntimeServices;
406 ASSERT (mRT != NULL);
407
408 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
409 Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID **)&gStatusCode);
410 if (EFI_ERROR (Status)) {
411 gStatusCode = NULL;
412 }
413 #endif
414
415 Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID **) &gCpuIo);
416 if (EFI_ERROR (Status)) {
417 gCpuIo = NULL;
418 }
419
420 return EFI_SUCCESS;
421 }
422
423 BOOLEAN
424 EfiAtRuntime (
425 VOID
426 )
427 /*++
428
429 Routine Description:
430 Return TRUE if ExitBootServices () has been called
431
432 Arguments:
433 NONE
434
435 Returns:
436 TRUE - If ExitBootServices () has been called
437
438 --*/
439 {
440 return mEfiAtRuntime;
441 }
442
443 BOOLEAN
444 EfiGoneVirtual (
445 VOID
446 )
447 /*++
448
449 Routine Description:
450 Return TRUE if SetVirtualAddressMap () has been called
451
452 Arguments:
453 NONE
454
455 Returns:
456 TRUE - If SetVirtualAddressMap () has been called
457
458 --*/
459 {
460 return mEfiGoneVirtual;
461 }
462 //
463 // The following functions hide the mRT local global from the call to
464 // runtime service in the EFI system table.
465 //
466 EFI_STATUS
467 EfiGetTime (
468 OUT EFI_TIME *Time,
469 OUT EFI_TIME_CAPABILITIES *Capabilities
470 )
471 /*++
472
473 Routine Description:
474
475 Returns the current time and date information, and the time-keeping
476 capabilities of the hardware platform.
477
478 Arguments:
479
480 Time - A pointer to storage to receive a snapshot of the current time.
481 Capabilities - An optional pointer to a buffer to receive the real time clock device's
482 capabilities.
483
484 Returns:
485
486 Status code
487
488 --*/
489 {
490 return mRT->GetTime (Time, Capabilities);
491 }
492
493 EFI_STATUS
494 EfiSetTime (
495 IN EFI_TIME *Time
496 )
497 /*++
498
499 Routine Description:
500
501 Sets the current local time and date information.
502
503 Arguments:
504
505 Time - A pointer to the current time.
506
507 Returns:
508
509 Status code
510
511 --*/
512 {
513 return mRT->SetTime (Time);
514 }
515
516 EFI_STATUS
517 EfiGetWakeupTime (
518 OUT BOOLEAN *Enabled,
519 OUT BOOLEAN *Pending,
520 OUT EFI_TIME *Time
521 )
522 /*++
523
524 Routine Description:
525
526 Returns the current wakeup alarm clock setting.
527
528 Arguments:
529
530 Enabled - Indicates if the alarm is currently enabled or disabled.
531 Pending - Indicates if the alarm signal is pending and requires acknowledgement.
532 Time - The current alarm setting.
533
534 Returns:
535
536 Status code
537
538 --*/
539 {
540 return mRT->GetWakeupTime (Enabled, Pending, Time);
541 }
542
543 EFI_STATUS
544 EfiSetWakeupTime (
545 IN BOOLEAN Enable,
546 IN EFI_TIME *Time
547 )
548 /*++
549
550 Routine Description:
551
552 Sets the system wakeup alarm clock time.
553
554 Arguments:
555
556 Enable - Enable or disable the wakeup alarm.
557 Time - If Enable is TRUE, the time to set the wakeup alarm for.
558 If Enable is FALSE, then this parameter is optional, and may be NULL.
559
560 Returns:
561
562 Status code
563
564 --*/
565 {
566 return mRT->SetWakeupTime (Enable, Time);
567 }
568
569 EFI_STATUS
570 EfiGetVariable (
571 IN CHAR16 *VariableName,
572 IN EFI_GUID * VendorGuid,
573 OUT UINT32 *Attributes OPTIONAL,
574 IN OUT UINTN *DataSize,
575 OUT VOID *Data
576 )
577 /*++
578
579 Routine Description:
580
581 Returns the value of a variable.
582
583 Arguments:
584
585 VariableName - A Null-terminated Unicode string that is the name of the
586 vendor's variable.
587 VendorGuid - A unique identifier for the vendor.
588 Attributes - If not NULL, a pointer to the memory location to return the
589 attributes bitmask for the variable.
590 DataSize - On input, the size in bytes of the return Data buffer.
591 On output the size of data returned in Data.
592 Data - The buffer to return the contents of the variable.
593
594 Returns:
595
596 Status code
597
598 --*/
599 {
600 return mRT->GetVariable (VariableName, VendorGuid, Attributes, DataSize, Data);
601 }
602
603 EFI_STATUS
604 EfiGetNextVariableName (
605 IN OUT UINTN *VariableNameSize,
606 IN OUT CHAR16 *VariableName,
607 IN OUT EFI_GUID *VendorGuid
608 )
609 /*++
610
611 Routine Description:
612
613 Enumerates the current variable names.
614
615 Arguments:
616
617 VariableNameSize - The size of the VariableName buffer.
618 VariableName - On input, supplies the last VariableName that was returned
619 by GetNextVariableName().
620 On output, returns the Nullterminated Unicode string of the
621 current variable.
622 VendorGuid - On input, supplies the last VendorGuid that was returned by
623 GetNextVariableName().
624 On output, returns the VendorGuid of the current variable.
625
626 Returns:
627
628 Status code
629
630 --*/
631 {
632 return mRT->GetNextVariableName (VariableNameSize, VariableName, VendorGuid);
633 }
634
635 EFI_STATUS
636 EfiSetVariable (
637 IN CHAR16 *VariableName,
638 IN EFI_GUID *VendorGuid,
639 IN UINT32 Attributes,
640 IN UINTN DataSize,
641 IN VOID *Data
642 )
643 /*++
644
645 Routine Description:
646
647 Sets the value of a variable.
648
649 Arguments:
650
651 VariableName - A Null-terminated Unicode string that is the name of the
652 vendor's variable.
653 VendorGuid - A unique identifier for the vendor.
654 Attributes - Attributes bitmask to set for the variable.
655 DataSize - The size in bytes of the Data buffer.
656 Data - The contents for the variable.
657
658 Returns:
659
660 Status code
661
662 --*/
663 {
664 return mRT->SetVariable (VariableName, VendorGuid, Attributes, DataSize, Data);
665 }
666
667 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
668
669 EFI_STATUS
670 EfiQueryVariableInfo (
671 IN UINT32 Attributes,
672 OUT UINT64 *MaximumVariableStorageSize,
673 OUT UINT64 *RemainingVariableStorageSize,
674 OUT UINT64 *MaximumVariableSize
675 )
676
677 /*++
678
679 Routine Description:
680
681 This code returns information about the EFI variables.
682
683 Arguments:
684
685 Attributes Attributes bitmask to specify the type of variables
686 on which to return information.
687 MaximumVariableStorageSize Pointer to the maximum size of the storage space available
688 for the EFI variables associated with the attributes specified.
689 RemainingVariableStorageSize Pointer to the remaining size of the storage space available
690 for the EFI variables associated with the attributes specified.
691 MaximumVariableSize Pointer to the maximum size of the individual EFI variables
692 associated with the attributes specified.
693
694 Returns:
695
696 Status code
697
698 --*/
699 {
700 return mRT->QueryVariableInfo (Attributes, MaximumVariableStorageSize, RemainingVariableStorageSize, MaximumVariableSize);
701 }
702
703 #endif
704
705
706 EFI_STATUS
707 EfiGetNextHighMonotonicCount (
708 OUT UINT32 *HighCount
709 )
710 /*++
711
712 Routine Description:
713
714 Returns the next high 32 bits of the platform's monotonic counter.
715
716 Arguments:
717
718 HighCount - Pointer to returned value.
719
720 Returns:
721
722 Status code
723
724 --*/
725 {
726 return mRT->GetNextHighMonotonicCount (HighCount);
727 }
728
729 VOID
730 EfiResetSystem (
731 IN EFI_RESET_TYPE ResetType,
732 IN EFI_STATUS ResetStatus,
733 IN UINTN DataSize,
734 IN CHAR16 *ResetData
735 )
736 /*++
737
738 Routine Description:
739
740 Resets the entire platform.
741
742 Arguments:
743
744 ResetType - The type of reset to perform.
745 ResetStatus - The status code for the reset.
746 DataSize - The size, in bytes, of ResetData.
747 ResetData - A data buffer that includes a Null-terminated Unicode string, optionally
748 followed by additional binary data.
749
750 Returns:
751
752 None
753
754 --*/
755 {
756 mRT->ResetSystem (ResetType, ResetStatus, DataSize, ResetData);
757 }
758
759 EFI_STATUS
760 EfiReportStatusCode (
761 IN EFI_STATUS_CODE_TYPE CodeType,
762 IN EFI_STATUS_CODE_VALUE Value,
763 IN UINT32 Instance,
764 IN EFI_GUID * CallerId,
765 IN EFI_STATUS_CODE_DATA * Data OPTIONAL
766 )
767 /*++
768
769 Routine Description:
770
771 Status Code reporter
772
773 Arguments:
774
775 CodeType - Type of Status Code.
776
777 Value - Value to output for Status Code.
778
779 Instance - Instance Number of this status code.
780
781 CallerId - ID of the caller of this status code.
782
783 Data - Optional data associated with this status code.
784
785 Returns:
786
787 Status code
788
789 --*/
790 {
791 EFI_STATUS Status;
792
793 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
794 if (gStatusCode == NULL) {
795 if (EfiAtRuntime ()) {
796 return EFI_UNSUPPORTED;
797 }
798 Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID **)&gStatusCode);
799 if (EFI_ERROR (Status) || gStatusCode == NULL) {
800 return EFI_UNSUPPORTED;
801 }
802 }
803 Status = gStatusCode->ReportStatusCode (CodeType, Value, Instance, CallerId, Data);
804 #else
805 if (mRT == NULL) {
806 return EFI_UNSUPPORTED;
807 }
808 //
809 // Check whether EFI_RUNTIME_SERVICES has Tiano Extension
810 //
811 Status = EFI_UNSUPPORTED;
812 if (mRT->Hdr.Revision == EFI_SPECIFICATION_VERSION &&
813 mRT->Hdr.HeaderSize == sizeof (EFI_RUNTIME_SERVICES) &&
814 mRT->ReportStatusCode != NULL) {
815 Status = mRT->ReportStatusCode (CodeType, Value, Instance, CallerId, Data);
816 }
817 #endif
818 return Status;
819 }