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
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.
18 Light weight lib to support Tiano drivers.
23 #include "EfiRuntimeLib.h"
25 #include EFI_PROTOCOL_DEFINITION (CpuIo)
26 #include EFI_PROTOCOL_DEFINITION (FirmwareVolumeBlock)
27 #include EFI_GUID_DEFINITION (StatusCodeCallerId)
28 #include EFI_GUID_DEFINITION (Hob)
29 #include EFI_ARCH_PROTOCOL_DEFINITION (StatusCode)
32 // Driver Lib Module Globals
34 static EFI_RUNTIME_SERVICES
*mRT
;
35 static EFI_EVENT mRuntimeNotifyEvent
= NULL
;
36 static EFI_EVENT mEfiVirtualNotifyEvent
= NULL
;
37 static BOOLEAN mRuntimeLibInitialized
= FALSE
;
38 static BOOLEAN mEfiGoneVirtual
= FALSE
;
41 // Runtime Global, but you should use the Lib functions
43 EFI_CPU_IO_PROTOCOL
*gCpuIo
;
44 BOOLEAN mEfiAtRuntime
= FALSE
;
47 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
49 EFI_REPORT_STATUS_CODE gReportStatusCode
= NULL
;
50 EFI_EVENT gEfiStatusCodeNotifyEvent
= NULL
;
60 EFI_STATUS_CODE_PROTOCOL
*StatusCode
;
62 Status
= gBS
->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid
, NULL
, (VOID
**) &StatusCode
);
63 if (!EFI_ERROR (Status
)) {
64 gReportStatusCode
= StatusCode
->ReportStatusCode
;
70 IN EFI_GUID
*ProtocolGuid
,
77 Searches for a Protocol Interface passed from PEI through a HOB
81 ProtocolGuid - The Protocol GUID to search for in the HOB List
83 Interface - A pointer to the interface for the Protocol GUID
87 EFI_SUCCESS - The Protocol GUID was found and its interface is returned in Interface
89 EFI_NOT_FOUND - The Protocol GUID was not found in the HOB List
94 EFI_PEI_HOB_POINTERS GuidHob
;
99 Status
= EfiLibGetSystemConfigurationTable (&gEfiHobListGuid
, (VOID
**) &GuidHob
.Raw
);
100 if (EFI_ERROR (Status
)) {
104 for (Status
= EFI_NOT_FOUND
; EFI_ERROR (Status
);) {
105 if (END_OF_HOB_LIST (GuidHob
)) {
106 Status
= EFI_NOT_FOUND
;
110 if (GET_HOB_TYPE (GuidHob
) == EFI_HOB_TYPE_GUID_EXTENSION
) {
111 if (EfiCompareGuid (ProtocolGuid
, &GuidHob
.Guid
->Name
)) {
112 Status
= EFI_SUCCESS
;
113 *Interface
= (VOID
*) *(UINTN
*) ((UINT8
*) (&GuidHob
.Guid
->Name
) + sizeof (EFI_GUID
));
117 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
127 IN UINTN DebugDisposition
,
134 Determines the new virtual address that is to be used on subsequent memory accesses.
138 DebugDisposition - Supplies type information for the pointer being converted.
139 Address - A pointer to a pointer that is to be fixed to be the value needed
140 for the new virtual address mappings being applied.
148 return mRT
->ConvertPointer (DebugDisposition
, Address
);
152 EfiConvertInternalPointer (
159 Call EfiConvertPointer() to convert internal pointer.
163 Address - A pointer to a pointer that is to be fixed to be the value needed
164 for the new virtual address mappings being applied.
172 return EfiConvertPointer (EFI_INTERNAL_POINTER
, Address
);
177 EfiRuntimeLibFvbVirtualNotifyEvent (
185 Convert all pointers in mFvbEntry after ExitBootServices.
189 Event - The Event that is being processed
191 Context - Event Context
200 if (mFvbEntry
!= NULL
) {
201 for (Index
= 0; Index
< MAX_FVB_COUNT
; Index
++) {
202 if (NULL
!= mFvbEntry
[Index
].Fvb
) {
203 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->GetBlockSize
);
204 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->GetPhysicalAddress
);
205 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->GetVolumeAttributes
);
206 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->SetVolumeAttributes
);
207 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->Read
);
208 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->Write
);
209 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->EraseBlocks
);
210 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
);
213 if (NULL
!= mFvbEntry
[Index
].FvbExtension
) {
214 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].FvbExtension
->EraseFvbCustomBlock
);
215 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].FvbExtension
);
219 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
);
225 RuntimeDriverExitBootServices (
233 Set AtRuntime flag as TRUE after ExitBootServices
237 Event - The Event that is being processed
239 Context - Event Context
247 mEfiAtRuntime
= TRUE
;
250 extern BOOLEAN gEfiFvbInitialized
;
254 EfiRuntimeLibVirtualNotifyEvent (
262 Fixup internal data so that EFI can be call in virtual mode.
263 Call the passed in Child Notify event and convert any pointers in
268 Event - The Event that is being processed
270 Context - Event Context
278 EFI_EVENT_NOTIFY ChildNotifyEventHandler
;
280 if (Context
!= NULL
) {
281 ChildNotifyEventHandler
= (EFI_EVENT_NOTIFY
) (UINTN
) Context
;
282 ChildNotifyEventHandler (Event
, NULL
);
285 if (gEfiFvbInitialized
) {
286 EfiRuntimeLibFvbVirtualNotifyEvent (Event
, Context
);
289 // Update global for Runtime Services Table and IO
291 EfiConvertInternalPointer ((VOID
**) &gCpuIo
);
292 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
293 if (gReportStatusCode
!= NULL
) {
294 EfiConvertInternalPointer ((VOID
**) &gReportStatusCode
);
297 EfiConvertInternalPointer ((VOID
**) &mRT
);
300 // Clear out BootService globals
304 mEfiGoneVirtual
= TRUE
;
308 EfiInitializeRuntimeDriverLib (
309 IN EFI_HANDLE ImageHandle
,
310 IN EFI_SYSTEM_TABLE
*SystemTable
,
311 IN EFI_EVENT_NOTIFY GoVirtualChildEvent
317 Intialize runtime Driver Lib if it has not yet been initialized.
321 ImageHandle - The firmware allocated handle for the EFI image.
323 SystemTable - A pointer to the EFI System Table.
325 GoVirtualChildEvent - Caller can register a virtual notification event.
329 EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
334 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
338 if (mRuntimeLibInitialized
) {
339 return EFI_ALREADY_STARTED
;
342 mRuntimeLibInitialized
= TRUE
;
345 ASSERT (gST
!= NULL
);
347 gBS
= SystemTable
->BootServices
;
348 ASSERT (gBS
!= NULL
);
349 mRT
= SystemTable
->RuntimeServices
;
350 ASSERT (mRT
!= NULL
);
352 Status
= EfiLibGetSystemConfigurationTable (&gEfiDxeServicesTableGuid
, (VOID
**) &gDS
);
353 ASSERT_EFI_ERROR (Status
);
355 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
357 // Register EFI_STATUS_CODE_PROTOCOL notify function
359 Status
= gBS
->CreateEvent (
360 EFI_EVENT_NOTIFY_SIGNAL
,
364 &gEfiStatusCodeNotifyEvent
366 ASSERT_EFI_ERROR (Status
);
368 Status
= gBS
->RegisterProtocolNotify (
369 &gEfiStatusCodeRuntimeProtocolGuid
,
370 gEfiStatusCodeNotifyEvent
,
373 ASSERT_EFI_ERROR (Status
);
375 gBS
->SignalEvent (gEfiStatusCodeNotifyEvent
);
378 Status
= gBS
->LocateProtocol (&gEfiCpuIoProtocolGuid
, NULL
, (VOID
**) &gCpuIo
);
379 if (EFI_ERROR (Status
)) {
384 // Register our ExitBootServices () notify function
386 Status
= gBS
->CreateEvent (
387 EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES
,
389 RuntimeDriverExitBootServices
,
393 ASSERT_EFI_ERROR (Status
);
396 // Register SetVirtualAddressMap () notify function
398 Status
= gBS
->CreateEvent (
399 EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
401 EfiRuntimeLibVirtualNotifyEvent
,
402 (VOID
*) (UINTN
) GoVirtualChildEvent
,
403 &mEfiVirtualNotifyEvent
405 ASSERT_EFI_ERROR (Status
);
411 EfiShutdownRuntimeDriverLib (
418 This routine will free some resources which have been allocated in
419 EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error,
420 it must call this routine to free the allocated resource before the exiting.
428 EFI_SUCCESS - Shotdown the Runtime Driver Lib successfully
429 EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all
435 if (!mRuntimeLibInitialized
) {
437 // You must call EfiInitializeRuntimeDriverLib() first
439 return EFI_UNSUPPORTED
;
442 mRuntimeLibInitialized
= FALSE
;
445 // Close our ExitBootServices () notify function
447 if (mRuntimeNotifyEvent
!= NULL
) {
448 Status
= gBS
->CloseEvent (mRuntimeNotifyEvent
);
449 ASSERT_EFI_ERROR (Status
);
453 // Close SetVirtualAddressMap () notify function
455 if (mEfiVirtualNotifyEvent
!= NULL
) {
456 Status
= gBS
->CloseEvent (mEfiVirtualNotifyEvent
);
457 ASSERT_EFI_ERROR (Status
);
460 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
462 // Close EfiStatusCodeRuntimeProtocol notify function
464 if (gEfiStatusCodeNotifyEvent
!= NULL
) {
465 Status
= gBS
->CloseEvent (gEfiStatusCodeNotifyEvent
);
466 ASSERT_EFI_ERROR (Status
);
474 EfiInitializeSmmDriverLib (
475 IN EFI_HANDLE ImageHandle
,
476 IN EFI_SYSTEM_TABLE
*SystemTable
482 Intialize runtime Driver Lib if it has not yet been initialized.
486 ImageHandle - The firmware allocated handle for the EFI image.
488 SystemTable - A pointer to the EFI System Table.
492 EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
497 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
501 if (mRuntimeLibInitialized
) {
502 return EFI_ALREADY_STARTED
;
505 mRuntimeLibInitialized
= TRUE
;
508 ASSERT (gST
!= NULL
);
510 gBS
= SystemTable
->BootServices
;
511 ASSERT (gBS
!= NULL
);
512 mRT
= SystemTable
->RuntimeServices
;
513 ASSERT (mRT
!= NULL
);
515 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
517 // Register EFI_STATUS_CODE_PROTOCOL notify function
519 Status
= gBS
->CreateEvent (
520 EFI_EVENT_NOTIFY_SIGNAL
,
524 &gEfiStatusCodeNotifyEvent
526 ASSERT_EFI_ERROR (Status
);
528 Status
= gBS
->RegisterProtocolNotify (
529 &gEfiStatusCodeRuntimeProtocolGuid
,
530 gEfiStatusCodeNotifyEvent
,
533 ASSERT_EFI_ERROR (Status
);
535 gBS
->SignalEvent (gEfiStatusCodeNotifyEvent
);
538 Status
= gBS
->LocateProtocol (&gEfiCpuIoProtocolGuid
, NULL
, (VOID
**) &gCpuIo
);
539 if (EFI_ERROR (Status
)) {
553 Return TRUE if ExitBootServices () has been called
559 TRUE - If ExitBootServices () has been called
563 return mEfiAtRuntime
;
573 Return TRUE if SetVirtualAddressMap () has been called
579 TRUE - If SetVirtualAddressMap () has been called
583 return mEfiGoneVirtual
;
586 // The following functions hide the mRT local global from the call to
587 // runtime service in the EFI system table.
592 OUT EFI_TIME_CAPABILITIES
*Capabilities
598 Returns the current time and date information, and the time-keeping
599 capabilities of the hardware platform.
603 Time - A pointer to storage to receive a snapshot of the current time.
604 Capabilities - An optional pointer to a buffer to receive the real time clock device's
613 return mRT
->GetTime (Time
, Capabilities
);
624 Sets the current local time and date information.
628 Time - A pointer to the current time.
636 return mRT
->SetTime (Time
);
641 OUT BOOLEAN
*Enabled
,
642 OUT BOOLEAN
*Pending
,
649 Returns the current wakeup alarm clock setting.
653 Enabled - Indicates if the alarm is currently enabled or disabled.
654 Pending - Indicates if the alarm signal is pending and requires acknowledgement.
655 Time - The current alarm setting.
663 return mRT
->GetWakeupTime (Enabled
, Pending
, Time
);
675 Sets the system wakeup alarm clock time.
679 Enable - Enable or disable the wakeup alarm.
680 Time - If Enable is TRUE, the time to set the wakeup alarm for.
681 If Enable is FALSE, then this parameter is optional, and may be NULL.
689 return mRT
->SetWakeupTime (Enable
, Time
);
694 IN CHAR16
*VariableName
,
695 IN EFI_GUID
* VendorGuid
,
696 OUT UINT32
*Attributes OPTIONAL
,
697 IN OUT UINTN
*DataSize
,
704 Returns the value of a variable.
708 VariableName - A Null-terminated Unicode string that is the name of the
710 VendorGuid - A unique identifier for the vendor.
711 Attributes - If not NULL, a pointer to the memory location to return the
712 attributes bitmask for the variable.
713 DataSize - On input, the size in bytes of the return Data buffer.
714 On output the size of data returned in Data.
715 Data - The buffer to return the contents of the variable.
723 return mRT
->GetVariable (VariableName
, VendorGuid
, Attributes
, DataSize
, Data
);
727 EfiGetNextVariableName (
728 IN OUT UINTN
*VariableNameSize
,
729 IN OUT CHAR16
*VariableName
,
730 IN OUT EFI_GUID
*VendorGuid
736 Enumerates the current variable names.
740 VariableNameSize - The size of the VariableName buffer.
741 VariableName - On input, supplies the last VariableName that was returned
742 by GetNextVariableName().
743 On output, returns the Nullterminated Unicode string of the
745 VendorGuid - On input, supplies the last VendorGuid that was returned by
746 GetNextVariableName().
747 On output, returns the VendorGuid of the current variable.
755 return mRT
->GetNextVariableName (VariableNameSize
, VariableName
, VendorGuid
);
760 IN CHAR16
*VariableName
,
761 IN EFI_GUID
*VendorGuid
,
762 IN UINT32 Attributes
,
770 Sets the value of a variable.
774 VariableName - A Null-terminated Unicode string that is the name of the
776 VendorGuid - A unique identifier for the vendor.
777 Attributes - Attributes bitmask to set for the variable.
778 DataSize - The size in bytes of the Data buffer.
779 Data - The contents for the variable.
787 return mRT
->SetVariable (VariableName
, VendorGuid
, Attributes
, DataSize
, Data
);
791 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
794 EfiQueryVariableInfo (
795 IN UINT32 Attributes
,
796 OUT UINT64
*MaximumVariableStorageSize
,
797 OUT UINT64
*RemainingVariableStorageSize
,
798 OUT UINT64
*MaximumVariableSize
805 This code returns information about the EFI variables.
809 Attributes Attributes bitmask to specify the type of variables
810 on which to return information.
811 MaximumVariableStorageSize Pointer to the maximum size of the storage space available
812 for the EFI variables associated with the attributes specified.
813 RemainingVariableStorageSize Pointer to the remaining size of the storage space available
814 for the EFI variables associated with the attributes specified.
815 MaximumVariableSize Pointer to the maximum size of the individual EFI variables
816 associated with the attributes specified.
824 return mRT
->QueryVariableInfo (Attributes
, MaximumVariableStorageSize
, RemainingVariableStorageSize
, MaximumVariableSize
);
830 EfiGetNextHighMonotonicCount (
831 OUT UINT32
*HighCount
837 Returns the next high 32 bits of the platform's monotonic counter.
841 HighCount - Pointer to returned value.
849 return mRT
->GetNextHighMonotonicCount (HighCount
);
854 IN EFI_RESET_TYPE ResetType
,
855 IN EFI_STATUS ResetStatus
,
863 Resets the entire platform.
867 ResetType - The type of reset to perform.
868 ResetStatus - The status code for the reset.
869 DataSize - The size, in bytes, of ResetData.
870 ResetData - A data buffer that includes a Null-terminated Unicode string, optionally
871 followed by additional binary data.
879 mRT
->ResetSystem (ResetType
, ResetStatus
, DataSize
, ResetData
);
883 EfiReportStatusCode (
884 IN EFI_STATUS_CODE_TYPE CodeType
,
885 IN EFI_STATUS_CODE_VALUE Value
,
887 IN EFI_GUID
*CallerId OPTIONAL
,
888 IN EFI_STATUS_CODE_DATA
*Data OPTIONAL
898 CodeType - Type of Status Code.
900 Value - Value to output for Status Code.
902 Instance - Instance Number of this status code.
904 CallerId - ID of the caller of this status code.
906 Data - Optional data associated with this status code.
916 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
917 if (gReportStatusCode
== NULL
) {
919 // Because we've installed the protocol notification on EfiStatusCodeRuntimeProtocol,
920 // running here indicates that the StatusCode driver has not started yet.
922 if (EfiAtRuntime ()) {
924 // Running here only when StatusCode driver never starts.
926 return EFI_UNSUPPORTED
;
930 // Try to get the PEI version of ReportStatusCode.
932 Status
= GetPeiProtocol (&gEfiStatusCodeRuntimeProtocolGuid
, (VOID
**) &gReportStatusCode
);
933 if (EFI_ERROR (Status
)) {
934 return EFI_UNSUPPORTED
;
937 Status
= gReportStatusCode (CodeType
, Value
, Instance
, CallerId
, Data
);
940 return EFI_UNSUPPORTED
;
943 // Check whether EFI_RUNTIME_SERVICES has Tiano Extension
945 Status
= EFI_UNSUPPORTED
;
946 if (mRT
->Hdr
.Revision
== EFI_SPECIFICATION_VERSION
&&
947 mRT
->Hdr
.HeaderSize
== sizeof (EFI_RUNTIME_SERVICES
) &&
948 mRT
->ReportStatusCode
!= NULL
) {
949 Status
= mRT
->ReportStatusCode (CodeType
, Value
, Instance
, CallerId
, Data
);