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)
30 #include EFI_PROTOCOL_DEFINITION (SmmStatusCode)
31 #include EFI_PROTOCOL_DEFINITION (SmmBase)
34 // Driver Lib Module Globals
36 static EFI_RUNTIME_SERVICES
*mRT
;
37 static EFI_EVENT mRuntimeNotifyEvent
= NULL
;
38 static EFI_EVENT mEfiVirtualNotifyEvent
= NULL
;
39 static BOOLEAN mRuntimeLibInitialized
= FALSE
;
40 static BOOLEAN mEfiGoneVirtual
= FALSE
;
41 static BOOLEAN mInSmm
= FALSE
;
44 // Runtime Global, but you should use the Lib functions
46 EFI_CPU_IO_PROTOCOL
*gCpuIo
;
47 BOOLEAN mEfiAtRuntime
= FALSE
;
49 EFI_SMM_STATUS_CODE_PROTOCOL
*gSmmStatusCodeProtocol
= NULL
;
51 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
53 EFI_REPORT_STATUS_CODE gReportStatusCode
= NULL
;
54 EFI_EVENT gEfiStatusCodeNotifyEvent
= NULL
;
64 EFI_STATUS_CODE_PROTOCOL
*StatusCode
;
66 Status
= gBS
->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid
, NULL
, (VOID
**) &StatusCode
);
67 if (!EFI_ERROR (Status
)) {
68 gReportStatusCode
= StatusCode
->ReportStatusCode
;
74 IN EFI_GUID
*ProtocolGuid
,
81 Searches for a Protocol Interface passed from PEI through a HOB
85 ProtocolGuid - The Protocol GUID to search for in the HOB List
87 Interface - A pointer to the interface for the Protocol GUID
91 EFI_SUCCESS - The Protocol GUID was found and its interface is returned in Interface
93 EFI_NOT_FOUND - The Protocol GUID was not found in the HOB List
98 EFI_PEI_HOB_POINTERS GuidHob
;
103 Status
= EfiLibGetSystemConfigurationTable (&gEfiHobListGuid
, (VOID
**) &GuidHob
.Raw
);
104 if (EFI_ERROR (Status
)) {
108 for (Status
= EFI_NOT_FOUND
; EFI_ERROR (Status
);) {
109 if (END_OF_HOB_LIST (GuidHob
)) {
110 Status
= EFI_NOT_FOUND
;
114 if (GET_HOB_TYPE (GuidHob
) == EFI_HOB_TYPE_GUID_EXTENSION
) {
115 if (EfiCompareGuid (ProtocolGuid
, &GuidHob
.Guid
->Name
)) {
116 Status
= EFI_SUCCESS
;
117 *Interface
= (VOID
*) *(UINTN
*) ((UINT8
*) (&GuidHob
.Guid
->Name
) + sizeof (EFI_GUID
));
121 GuidHob
.Raw
= GET_NEXT_HOB (GuidHob
);
131 IN UINTN DebugDisposition
,
138 Determines the new virtual address that is to be used on subsequent memory accesses.
142 DebugDisposition - Supplies type information for the pointer being converted.
143 Address - A pointer to a pointer that is to be fixed to be the value needed
144 for the new virtual address mappings being applied.
152 return mRT
->ConvertPointer (DebugDisposition
, Address
);
156 EfiConvertInternalPointer (
163 Call EfiConvertPointer() to convert internal pointer.
167 Address - A pointer to a pointer that is to be fixed to be the value needed
168 for the new virtual address mappings being applied.
176 return EfiConvertPointer (EFI_INTERNAL_POINTER
, Address
);
181 EfiRuntimeLibFvbVirtualNotifyEvent (
189 Convert all pointers in mFvbEntry after ExitBootServices.
193 Event - The Event that is being processed
195 Context - Event Context
204 if (mFvbEntry
!= NULL
) {
205 for (Index
= 0; Index
< MAX_FVB_COUNT
; Index
++) {
206 if (NULL
!= mFvbEntry
[Index
].Fvb
) {
207 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->GetBlockSize
);
208 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->GetPhysicalAddress
);
209 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->GetVolumeAttributes
);
210 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->SetVolumeAttributes
);
211 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->Read
);
212 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->Write
);
213 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
->EraseBlocks
);
214 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].Fvb
);
217 if (NULL
!= mFvbEntry
[Index
].FvbExtension
) {
218 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].FvbExtension
->EraseFvbCustomBlock
);
219 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
[Index
].FvbExtension
);
223 EfiConvertInternalPointer ((VOID
**) &mFvbEntry
);
229 RuntimeDriverExitBootServices (
237 Set AtRuntime flag as TRUE after ExitBootServices
241 Event - The Event that is being processed
243 Context - Event Context
251 mEfiAtRuntime
= TRUE
;
254 extern BOOLEAN gEfiFvbInitialized
;
258 EfiRuntimeLibVirtualNotifyEvent (
266 Fixup internal data so that EFI can be call in virtual mode.
267 Call the passed in Child Notify event and convert any pointers in
272 Event - The Event that is being processed
274 Context - Event Context
282 EFI_EVENT_NOTIFY ChildNotifyEventHandler
;
284 if (Context
!= NULL
) {
285 ChildNotifyEventHandler
= (EFI_EVENT_NOTIFY
) (UINTN
) Context
;
286 ChildNotifyEventHandler (Event
, NULL
);
289 if (gEfiFvbInitialized
) {
290 EfiRuntimeLibFvbVirtualNotifyEvent (Event
, Context
);
293 // Update global for Runtime Services Table and IO
295 EfiConvertInternalPointer ((VOID
**) &gCpuIo
);
296 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
297 if (gReportStatusCode
!= NULL
) {
298 EfiConvertInternalPointer ((VOID
**) &gReportStatusCode
);
301 EfiConvertInternalPointer ((VOID
**) &mRT
);
304 // Clear out BootService globals
308 mEfiGoneVirtual
= TRUE
;
312 EfiInitializeRuntimeDriverLib (
313 IN EFI_HANDLE ImageHandle
,
314 IN EFI_SYSTEM_TABLE
*SystemTable
,
315 IN EFI_EVENT_NOTIFY GoVirtualChildEvent
321 Intialize runtime Driver Lib if it has not yet been initialized.
325 ImageHandle - The firmware allocated handle for the EFI image.
327 SystemTable - A pointer to the EFI System Table.
329 GoVirtualChildEvent - Caller can register a virtual notification event.
333 EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
338 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
342 if (mRuntimeLibInitialized
) {
343 return EFI_ALREADY_STARTED
;
346 mRuntimeLibInitialized
= TRUE
;
349 ASSERT (gST
!= NULL
);
351 gBS
= SystemTable
->BootServices
;
352 ASSERT (gBS
!= NULL
);
353 mRT
= SystemTable
->RuntimeServices
;
354 ASSERT (mRT
!= NULL
);
356 Status
= EfiLibGetSystemConfigurationTable (&gEfiDxeServicesTableGuid
, (VOID
**) &gDS
);
357 ASSERT_EFI_ERROR (Status
);
359 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
361 // Register EFI_STATUS_CODE_PROTOCOL notify function
363 Status
= gBS
->CreateEvent (
364 EFI_EVENT_NOTIFY_SIGNAL
,
368 &gEfiStatusCodeNotifyEvent
370 ASSERT_EFI_ERROR (Status
);
372 Status
= gBS
->RegisterProtocolNotify (
373 &gEfiStatusCodeRuntimeProtocolGuid
,
374 gEfiStatusCodeNotifyEvent
,
377 ASSERT_EFI_ERROR (Status
);
379 gBS
->SignalEvent (gEfiStatusCodeNotifyEvent
);
382 Status
= gBS
->LocateProtocol (&gEfiCpuIoProtocolGuid
, NULL
, (VOID
**) &gCpuIo
);
383 if (EFI_ERROR (Status
)) {
388 // Register our ExitBootServices () notify function
390 Status
= gBS
->CreateEvent (
391 EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES
,
393 RuntimeDriverExitBootServices
,
397 ASSERT_EFI_ERROR (Status
);
400 // Register SetVirtualAddressMap () notify function
402 Status
= gBS
->CreateEvent (
403 EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
405 EfiRuntimeLibVirtualNotifyEvent
,
406 (VOID
*) (UINTN
) GoVirtualChildEvent
,
407 &mEfiVirtualNotifyEvent
409 ASSERT_EFI_ERROR (Status
);
415 EfiShutdownRuntimeDriverLib (
422 This routine will free some resources which have been allocated in
423 EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error,
424 it must call this routine to free the allocated resource before the exiting.
432 EFI_SUCCESS - Shotdown the Runtime Driver Lib successfully
433 EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all
439 if (!mRuntimeLibInitialized
) {
441 // You must call EfiInitializeRuntimeDriverLib() first
443 return EFI_UNSUPPORTED
;
446 mRuntimeLibInitialized
= FALSE
;
449 // Close our ExitBootServices () notify function
451 if (mRuntimeNotifyEvent
!= NULL
) {
452 Status
= gBS
->CloseEvent (mRuntimeNotifyEvent
);
453 ASSERT_EFI_ERROR (Status
);
457 // Close SetVirtualAddressMap () notify function
459 if (mEfiVirtualNotifyEvent
!= NULL
) {
460 Status
= gBS
->CloseEvent (mEfiVirtualNotifyEvent
);
461 ASSERT_EFI_ERROR (Status
);
464 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
466 // Close EfiStatusCodeRuntimeProtocol notify function
468 if (gEfiStatusCodeNotifyEvent
!= NULL
) {
469 Status
= gBS
->CloseEvent (gEfiStatusCodeNotifyEvent
);
470 ASSERT_EFI_ERROR (Status
);
478 EfiInitializeSmmDriverLib (
479 IN EFI_HANDLE ImageHandle
,
480 IN EFI_SYSTEM_TABLE
*SystemTable
486 Intialize runtime Driver Lib if it has not yet been initialized.
490 ImageHandle - The firmware allocated handle for the EFI image.
492 SystemTable - A pointer to the EFI System Table.
496 EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
501 EFI_SMM_BASE_PROTOCOL
*SmmBase
;
503 if (mRuntimeLibInitialized
) {
504 return EFI_ALREADY_STARTED
;
507 mRuntimeLibInitialized
= TRUE
;
510 ASSERT (gST
!= NULL
);
512 gBS
= SystemTable
->BootServices
;
513 ASSERT (gBS
!= NULL
);
514 mRT
= SystemTable
->RuntimeServices
;
515 ASSERT (mRT
!= NULL
);
518 // Check whether it is in SMM mode.
520 Status
= gBS
->LocateProtocol (&gEfiSmmBaseProtocolGuid
, NULL
, &SmmBase
);
521 if (!EFI_ERROR (Status
)) {
522 SmmBase
->InSmm (SmmBase
, &mInSmm
);
526 // Directly locate SmmStatusCode protocol
528 Status
= gBS
->LocateProtocol (&gEfiSmmStatusCodeProtocolGuid
, NULL
, &gSmmStatusCodeProtocol
);
529 if (EFI_ERROR (Status
)) {
530 gSmmStatusCodeProtocol
= NULL
;
533 Status
= gBS
->LocateProtocol (&gEfiCpuIoProtocolGuid
, NULL
, (VOID
**) &gCpuIo
);
534 if (EFI_ERROR (Status
)) {
548 Return TRUE if ExitBootServices () has been called
554 TRUE - If ExitBootServices () has been called
558 return mEfiAtRuntime
;
568 Return TRUE if SetVirtualAddressMap () has been called
574 TRUE - If SetVirtualAddressMap () has been called
578 return mEfiGoneVirtual
;
581 // The following functions hide the mRT local global from the call to
582 // runtime service in the EFI system table.
587 OUT EFI_TIME_CAPABILITIES
*Capabilities
593 Returns the current time and date information, and the time-keeping
594 capabilities of the hardware platform.
598 Time - A pointer to storage to receive a snapshot of the current time.
599 Capabilities - An optional pointer to a buffer to receive the real time clock device's
608 return mRT
->GetTime (Time
, Capabilities
);
619 Sets the current local time and date information.
623 Time - A pointer to the current time.
631 return mRT
->SetTime (Time
);
636 OUT BOOLEAN
*Enabled
,
637 OUT BOOLEAN
*Pending
,
644 Returns the current wakeup alarm clock setting.
648 Enabled - Indicates if the alarm is currently enabled or disabled.
649 Pending - Indicates if the alarm signal is pending and requires acknowledgement.
650 Time - The current alarm setting.
658 return mRT
->GetWakeupTime (Enabled
, Pending
, Time
);
670 Sets the system wakeup alarm clock time.
674 Enable - Enable or disable the wakeup alarm.
675 Time - If Enable is TRUE, the time to set the wakeup alarm for.
676 If Enable is FALSE, then this parameter is optional, and may be NULL.
684 return mRT
->SetWakeupTime (Enable
, Time
);
689 IN CHAR16
*VariableName
,
690 IN EFI_GUID
* VendorGuid
,
691 OUT UINT32
*Attributes OPTIONAL
,
692 IN OUT UINTN
*DataSize
,
699 Returns the value of a variable.
703 VariableName - A Null-terminated Unicode string that is the name of the
705 VendorGuid - A unique identifier for the vendor.
706 Attributes - If not NULL, a pointer to the memory location to return the
707 attributes bitmask for the variable.
708 DataSize - On input, the size in bytes of the return Data buffer.
709 On output the size of data returned in Data.
710 Data - The buffer to return the contents of the variable.
718 return mRT
->GetVariable (VariableName
, VendorGuid
, Attributes
, DataSize
, Data
);
722 EfiGetNextVariableName (
723 IN OUT UINTN
*VariableNameSize
,
724 IN OUT CHAR16
*VariableName
,
725 IN OUT EFI_GUID
*VendorGuid
731 Enumerates the current variable names.
735 VariableNameSize - The size of the VariableName buffer.
736 VariableName - On input, supplies the last VariableName that was returned
737 by GetNextVariableName().
738 On output, returns the Nullterminated Unicode string of the
740 VendorGuid - On input, supplies the last VendorGuid that was returned by
741 GetNextVariableName().
742 On output, returns the VendorGuid of the current variable.
750 return mRT
->GetNextVariableName (VariableNameSize
, VariableName
, VendorGuid
);
755 IN CHAR16
*VariableName
,
756 IN EFI_GUID
*VendorGuid
,
757 IN UINT32 Attributes
,
765 Sets the value of a variable.
769 VariableName - A Null-terminated Unicode string that is the name of the
771 VendorGuid - A unique identifier for the vendor.
772 Attributes - Attributes bitmask to set for the variable.
773 DataSize - The size in bytes of the Data buffer.
774 Data - The contents for the variable.
782 return mRT
->SetVariable (VariableName
, VendorGuid
, Attributes
, DataSize
, Data
);
786 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
789 EfiQueryVariableInfo (
790 IN UINT32 Attributes
,
791 OUT UINT64
*MaximumVariableStorageSize
,
792 OUT UINT64
*RemainingVariableStorageSize
,
793 OUT UINT64
*MaximumVariableSize
800 This code returns information about the EFI variables.
804 Attributes Attributes bitmask to specify the type of variables
805 on which to return information.
806 MaximumVariableStorageSize Pointer to the maximum size of the storage space available
807 for the EFI variables associated with the attributes specified.
808 RemainingVariableStorageSize Pointer to the remaining size of the storage space available
809 for the EFI variables associated with the attributes specified.
810 MaximumVariableSize Pointer to the maximum size of the individual EFI variables
811 associated with the attributes specified.
819 return mRT
->QueryVariableInfo (Attributes
, MaximumVariableStorageSize
, RemainingVariableStorageSize
, MaximumVariableSize
);
825 EfiGetNextHighMonotonicCount (
826 OUT UINT32
*HighCount
832 Returns the next high 32 bits of the platform's monotonic counter.
836 HighCount - Pointer to returned value.
844 return mRT
->GetNextHighMonotonicCount (HighCount
);
849 IN EFI_RESET_TYPE ResetType
,
850 IN EFI_STATUS ResetStatus
,
858 Resets the entire platform.
862 ResetType - The type of reset to perform.
863 ResetStatus - The status code for the reset.
864 DataSize - The size, in bytes, of ResetData.
865 ResetData - A data buffer that includes a Null-terminated Unicode string, optionally
866 followed by additional binary data.
874 mRT
->ResetSystem (ResetType
, ResetStatus
, DataSize
, ResetData
);
878 EfiReportStatusCode (
879 IN EFI_STATUS_CODE_TYPE CodeType
,
880 IN EFI_STATUS_CODE_VALUE Value
,
882 IN EFI_GUID
*CallerId OPTIONAL
,
883 IN EFI_STATUS_CODE_DATA
*Data OPTIONAL
893 CodeType - Type of Status Code.
895 Value - Value to output for Status Code.
897 Instance - Instance Number of this status code.
899 CallerId - ID of the caller of this status code.
901 Data - Optional data associated with this status code.
912 if (gSmmStatusCodeProtocol
== NULL
) {
913 return EFI_UNSUPPORTED
;
915 Status
= gSmmStatusCodeProtocol
->ReportStatusCode (gSmmStatusCodeProtocol
, CodeType
, Value
, Instance
, CallerId
, Data
);
919 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
920 if (gReportStatusCode
== NULL
) {
922 // Because we've installed the protocol notification on EfiStatusCodeRuntimeProtocol,
923 // running here indicates that the StatusCode driver has not started yet.
925 if (EfiAtRuntime ()) {
927 // Running here only when StatusCode driver never starts.
929 return EFI_UNSUPPORTED
;
933 // Try to get the PEI version of ReportStatusCode.
935 Status
= GetPeiProtocol (&gEfiStatusCodeRuntimeProtocolGuid
, (VOID
**) &gReportStatusCode
);
936 if (EFI_ERROR (Status
) || (gReportStatusCode
== NULL
)) {
937 return EFI_UNSUPPORTED
;
940 Status
= gReportStatusCode (CodeType
, Value
, Instance
, CallerId
, Data
);
943 return EFI_UNSUPPORTED
;
946 // Check whether EFI_RUNTIME_SERVICES has Tiano Extension
948 Status
= EFI_UNSUPPORTED
;
949 if (mRT
->Hdr
.Revision
== EFI_SPECIFICATION_VERSION
&&
950 mRT
->Hdr
.HeaderSize
== sizeof (EFI_RUNTIME_SERVICES
) &&
951 mRT
->ReportStatusCode
!= NULL
) {
952 Status
= mRT
->ReportStatusCode (CodeType
, Value
, Instance
, CallerId
, Data
);