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