-/** @file\r
-\r
- Implement all four UEFI Runtime Variable services for the nonvolatile\r
- and volatile storage space and install variable architecture protocol.\r
- \r
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-#include "Variable.h"\r
-\r
-extern VARIABLE_STORE_HEADER *mNvVariableCache;\r
-extern VARIABLE_INFO_ENTRY *gVariableInfo;\r
-EFI_HANDLE mHandle = NULL;\r
-EFI_EVENT mVirtualAddressChangeEvent = NULL;\r
-EFI_EVENT mFtwRegistration = NULL;\r
-extern BOOLEAN mEndOfDxe;\r
-EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock = { VariableLockRequestToLock };\r
-\r
-/**\r
- Return TRUE if ExitBootServices () has been called.\r
- \r
- @retval TRUE If ExitBootServices () has been called.\r
-**/\r
-BOOLEAN\r
-AtRuntime (\r
- VOID\r
- )\r
-{\r
- return EfiAtRuntime ();\r
-}\r
-\r
-\r
-/**\r
- Initializes a basic mutual exclusion lock.\r
-\r
- This function initializes a basic mutual exclusion lock to the released state \r
- and returns the lock. Each lock provides mutual exclusion access at its task \r
- priority level. Since there is no preemption or multiprocessor support in EFI,\r
- acquiring the lock only consists of raising to the locks TPL.\r
- If Lock is NULL, then ASSERT().\r
- If Priority is not a valid TPL value, then ASSERT().\r
-\r
- @param Lock A pointer to the lock data structure to initialize.\r
- @param Priority EFI TPL is associated with the lock.\r
-\r
- @return The lock.\r
-\r
-**/\r
-EFI_LOCK *\r
-InitializeLock (\r
- IN OUT EFI_LOCK *Lock,\r
- IN EFI_TPL Priority\r
- )\r
-{\r
- return EfiInitializeLock (Lock, Priority);\r
-}\r
-\r
-\r
-/**\r
- Acquires lock only at boot time. Simply returns at runtime.\r
-\r
- This is a temperary function that will be removed when\r
- EfiAcquireLock() in UefiLib can handle the call in UEFI\r
- Runtimer driver in RT phase.\r
- It calls EfiAcquireLock() at boot time, and simply returns\r
- at runtime.\r
-\r
- @param Lock A pointer to the lock to acquire.\r
-\r
-**/\r
-VOID\r
-AcquireLockOnlyAtBootTime (\r
- IN EFI_LOCK *Lock\r
- )\r
-{\r
- if (!AtRuntime ()) {\r
- EfiAcquireLock (Lock);\r
- }\r
-}\r
-\r
-\r
-/**\r
- Releases lock only at boot time. Simply returns at runtime.\r
-\r
- This is a temperary function which will be removed when\r
- EfiReleaseLock() in UefiLib can handle the call in UEFI\r
- Runtimer driver in RT phase.\r
- It calls EfiReleaseLock() at boot time and simply returns\r
- at runtime.\r
-\r
- @param Lock A pointer to the lock to release.\r
-\r
-**/\r
-VOID\r
-ReleaseLockOnlyAtBootTime (\r
- IN EFI_LOCK *Lock\r
- )\r
-{\r
- if (!AtRuntime ()) {\r
- EfiReleaseLock (Lock);\r
- }\r
-}\r
-\r
-/**\r
- Retrive the Fault Tolerent Write protocol interface.\r
-\r
- @param[out] FtwProtocol The interface of Ftw protocol\r
-\r
- @retval EFI_SUCCESS The FTW protocol instance was found and returned in FtwProtocol.\r
- @retval EFI_NOT_FOUND The FTW protocol instance was not found.\r
- @retval EFI_INVALID_PARAMETER SarProtocol is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-GetFtwProtocol (\r
- OUT VOID **FtwProtocol\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Locate Fault Tolerent Write protocol\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiFaultTolerantWriteProtocolGuid,\r
- NULL,\r
- FtwProtocol\r
- ); \r
- return Status;\r
-}\r
-\r
-/**\r
- Retrive the FVB protocol interface by HANDLE.\r
-\r
- @param[in] FvBlockHandle The handle of FVB protocol that provides services for\r
- reading, writing, and erasing the target block.\r
- @param[out] FvBlock The interface of FVB protocol\r
-\r
- @retval EFI_SUCCESS The interface information for the specified protocol was returned.\r
- @retval EFI_UNSUPPORTED The device does not support the FVB protocol.\r
- @retval EFI_INVALID_PARAMETER FvBlockHandle is not a valid EFI_HANDLE or FvBlock is NULL.\r
- \r
-**/\r
-EFI_STATUS\r
-GetFvbByHandle (\r
- IN EFI_HANDLE FvBlockHandle,\r
- OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock\r
- )\r
-{\r
- //\r
- // To get the FVB protocol interface on the handle\r
- //\r
- return gBS->HandleProtocol (\r
- FvBlockHandle,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- (VOID **) FvBlock\r
- );\r
-}\r
-\r
-\r
-/**\r
- Function returns an array of handles that support the FVB protocol\r
- in a buffer allocated from pool. \r
-\r
- @param[out] NumberHandles The number of handles returned in Buffer.\r
- @param[out] Buffer A pointer to the buffer to return the requested\r
- array of handles that support FVB protocol.\r
-\r
- @retval EFI_SUCCESS The array of handles was returned in Buffer, and the number of\r
- handles in Buffer was returned in NumberHandles.\r
- @retval EFI_NOT_FOUND No FVB handle was found.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the matching results.\r
- @retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.\r
- \r
-**/\r
-EFI_STATUS\r
-GetFvbCountAndBuffer (\r
- OUT UINTN *NumberHandles,\r
- OUT EFI_HANDLE **Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Locate all handles of Fvb protocol\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- NULL,\r
- NumberHandles,\r
- Buffer\r
- );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.\r
-\r
- This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
- It convers pointer to new virtual address.\r
-\r
- @param Event Event whose notification function is being invoked.\r
- @param Context Pointer to the notification function's context.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-VariableClassAddressChangeEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetAttributes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->SetAttributes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Read);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Write);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->EraseBlocks);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.HobVariableBase);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);\r
- EfiConvertPointer (0x0, (VOID **) &mNvVariableCache); \r
-}\r
-\r
-\r
-/**\r
- Notification function of EVT_GROUP_READY_TO_BOOT event group.\r
-\r
- This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.\r
- When the Boot Manager is about to load and execute a boot option, it reclaims variable\r
- storage if free size is below the threshold.\r
-\r
- @param Event Event whose notification function is being invoked.\r
- @param Context Pointer to the notification function's context.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-OnReadyToBoot (\r
- EFI_EVENT Event,\r
- VOID *Context\r
- )\r
-{\r
- //\r
- // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled.\r
- //\r
- mEndOfDxe = TRUE;\r
- ReclaimForOS ();\r
- if (FeaturePcdGet (PcdVariableCollectStatistics)) {\r
- gBS->InstallConfigurationTable (&gEfiVariableGuid, gVariableInfo);\r
- }\r
-}\r
-\r
-/**\r
- Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.\r
-\r
- This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.\r
-\r
- @param Event Event whose notification function is being invoked.\r
- @param Context Pointer to the notification function's context.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-OnEndOfDxe (\r
- EFI_EVENT Event,\r
- VOID *Context\r
- )\r
-{\r
- mEndOfDxe = TRUE;\r
-}\r
-\r
-/**\r
- Fault Tolerant Write protocol notification event handler.\r
-\r
- Non-Volatile variable write may needs FTW protocol to reclaim when \r
- writting variable.\r
-\r
- @param[in] Event Event whose notification function is being invoked.\r
- @param[in] Context Pointer to the notification function's context.\r
- \r
-**/\r
-VOID\r
-EFIAPI\r
-FtwNotificationEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;\r
- EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;\r
- EFI_PHYSICAL_ADDRESS NvStorageVariableBase;\r
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r
- EFI_PHYSICAL_ADDRESS BaseAddress;\r
- UINT64 Length;\r
- EFI_PHYSICAL_ADDRESS VariableStoreBase;\r
- UINT64 VariableStoreLength;\r
-\r
- //\r
- // Ensure FTW protocol is installed.\r
- //\r
- Status = GetFtwProtocol ((VOID**) &FtwProtocol);\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
- \r
- //\r
- // Find the proper FVB protocol for variable.\r
- //\r
- NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);\r
- if (NvStorageVariableBase == 0) {\r
- NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);\r
- }\r
- Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
- mVariableModuleGlobal->FvbInstance = FvbProtocol;\r
-\r
- //\r
- // Mark the variable storage region of the FLASH as RUNTIME.\r
- //\r
- VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;\r
- VariableStoreLength = ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase)->Size;\r
- BaseAddress = VariableStoreBase & (~EFI_PAGE_MASK);\r
- Length = VariableStoreLength + (VariableStoreBase - BaseAddress);\r
- Length = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK);\r
-\r
- Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));\r
- } else {\r
- Status = gDS->SetMemorySpaceAttributes (\r
- BaseAddress,\r
- Length,\r
- GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));\r
- }\r
- }\r
- \r
- Status = VariableWriteServiceInitialize ();\r
- ASSERT_EFI_ERROR (Status);\r
- \r
- //\r
- // Install the Variable Write Architectural protocol.\r
- //\r
- Status = gBS->InstallProtocolInterface (\r
- &mHandle,\r
- &gEfiVariableWriteArchProtocolGuid, \r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- \r
- //\r
- // Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again.\r
- //\r
- gBS->CloseEvent (Event);\r
-\r
-}\r
-\r
-\r
-/**\r
- Variable Driver main entry point. The Variable driver places the 4 EFI\r
- runtime services in the EFI System Table and installs arch protocols \r
- for variable read and write services being availible. It also registers\r
- a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
-\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
- @param[in] SystemTable A pointer to the EFI System Table.\r
- \r
- @retval EFI_SUCCESS Variable service successfully initialized.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-VariableServiceInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_EVENT ReadyToBootEvent;\r
- EFI_EVENT EndOfDxeEvent;\r
-\r
- Status = VariableCommonInitialize ();\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &mHandle,\r
- &gEdkiiVariableLockProtocolGuid,\r
- &mVariableLock,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable;\r
- SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;\r
- SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;\r
- SystemTable->RuntimeServices->QueryVariableInfo = VariableServiceQueryVariableInfo;\r
- \r
- //\r
- // Now install the Variable Runtime Architectural protocol on a new handle.\r
- //\r
- Status = gBS->InstallProtocolInterface (\r
- &mHandle,\r
- &gEfiVariableArchProtocolGuid, \r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Register FtwNotificationEvent () notify function.\r
- // \r
- EfiCreateProtocolNotifyEvent (\r
- &gEfiFaultTolerantWriteProtocolGuid,\r
- TPL_CALLBACK,\r
- FtwNotificationEvent,\r
- (VOID *)SystemTable,\r
- &mFtwRegistration\r
- );\r
-\r
- Status = gBS->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- VariableClassAddressChangeEvent,\r
- NULL,\r
- &gEfiEventVirtualAddressChangeGuid,\r
- &mVirtualAddressChangeEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Register the event handling function to reclaim variable for OS usage.\r
- //\r
- Status = EfiCreateEventReadyToBootEx (\r
- TPL_NOTIFY, \r
- OnReadyToBoot, \r
- NULL, \r
- &ReadyToBootEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Register the event handling function to set the End Of DXE flag.\r
- //\r
- Status = gBS->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- OnEndOfDxe,\r
- NULL,\r
- &gEfiEndOfDxeEventGroupGuid,\r
- &EndOfDxeEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
+/** @file
+
+ Implement all four UEFI Runtime Variable services for the nonvolatile
+ and volatile storage space and install variable architecture protocol.
+
+Copyright (C) 2013, Red Hat, Inc.
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Variable.h"
+
+extern VARIABLE_STORE_HEADER *mNvVariableCache;
+extern VARIABLE_INFO_ENTRY *gVariableInfo;
+EFI_HANDLE mHandle = NULL;
+EFI_EVENT mVirtualAddressChangeEvent = NULL;
+EFI_EVENT mFtwRegistration = NULL;
+extern LIST_ENTRY mLockedVariableList;
+extern BOOLEAN mEndOfDxe;
+EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock = { VariableLockRequestToLock };
+
+/**
+ Return TRUE if ExitBootServices () has been called.
+
+ @retval TRUE If ExitBootServices () has been called.
+**/
+BOOLEAN
+AtRuntime (
+ VOID
+ )
+{
+ return EfiAtRuntime ();
+}
+
+
+/**
+ Initializes a basic mutual exclusion lock.
+
+ This function initializes a basic mutual exclusion lock to the released state
+ and returns the lock. Each lock provides mutual exclusion access at its task
+ priority level. Since there is no preemption or multiprocessor support in EFI,
+ acquiring the lock only consists of raising to the locks TPL.
+ If Lock is NULL, then ASSERT().
+ If Priority is not a valid TPL value, then ASSERT().
+
+ @param Lock A pointer to the lock data structure to initialize.
+ @param Priority EFI TPL is associated with the lock.
+
+ @return The lock.
+
+**/
+EFI_LOCK *
+InitializeLock (
+ IN OUT EFI_LOCK *Lock,
+ IN EFI_TPL Priority
+ )
+{
+ return EfiInitializeLock (Lock, Priority);
+}
+
+
+/**
+ Acquires lock only at boot time. Simply returns at runtime.
+
+ This is a temperary function that will be removed when
+ EfiAcquireLock() in UefiLib can handle the call in UEFI
+ Runtimer driver in RT phase.
+ It calls EfiAcquireLock() at boot time, and simply returns
+ at runtime.
+
+ @param Lock A pointer to the lock to acquire.
+
+**/
+VOID
+AcquireLockOnlyAtBootTime (
+ IN EFI_LOCK *Lock
+ )
+{
+ if (!AtRuntime ()) {
+ EfiAcquireLock (Lock);
+ }
+}
+
+
+/**
+ Releases lock only at boot time. Simply returns at runtime.
+
+ This is a temperary function which will be removed when
+ EfiReleaseLock() in UefiLib can handle the call in UEFI
+ Runtimer driver in RT phase.
+ It calls EfiReleaseLock() at boot time and simply returns
+ at runtime.
+
+ @param Lock A pointer to the lock to release.
+
+**/
+VOID
+ReleaseLockOnlyAtBootTime (
+ IN EFI_LOCK *Lock
+ )
+{
+ if (!AtRuntime ()) {
+ EfiReleaseLock (Lock);
+ }
+}
+
+/**
+ Retrive the Fault Tolerent Write protocol interface.
+
+ @param[out] FtwProtocol The interface of Ftw protocol
+
+ @retval EFI_SUCCESS The FTW protocol instance was found and returned in FtwProtocol.
+ @retval EFI_NOT_FOUND The FTW protocol instance was not found.
+ @retval EFI_INVALID_PARAMETER SarProtocol is NULL.
+
+**/
+EFI_STATUS
+GetFtwProtocol (
+ OUT VOID **FtwProtocol
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate Fault Tolerent Write protocol
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiFaultTolerantWriteProtocolGuid,
+ NULL,
+ FtwProtocol
+ );
+ return Status;
+}
+
+/**
+ Retrive the FVB protocol interface by HANDLE.
+
+ @param[in] FvBlockHandle The handle of FVB protocol that provides services for
+ reading, writing, and erasing the target block.
+ @param[out] FvBlock The interface of FVB protocol
+
+ @retval EFI_SUCCESS The interface information for the specified protocol was returned.
+ @retval EFI_UNSUPPORTED The device does not support the FVB protocol.
+ @retval EFI_INVALID_PARAMETER FvBlockHandle is not a valid EFI_HANDLE or FvBlock is NULL.
+
+**/
+EFI_STATUS
+GetFvbByHandle (
+ IN EFI_HANDLE FvBlockHandle,
+ OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock
+ )
+{
+ //
+ // To get the FVB protocol interface on the handle
+ //
+ return gBS->HandleProtocol (
+ FvBlockHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ (VOID **) FvBlock
+ );
+}
+
+
+/**
+ Function returns an array of handles that support the FVB protocol
+ in a buffer allocated from pool.
+
+ @param[out] NumberHandles The number of handles returned in Buffer.
+ @param[out] Buffer A pointer to the buffer to return the requested
+ array of handles that support FVB protocol.
+
+ @retval EFI_SUCCESS The array of handles was returned in Buffer, and the number of
+ handles in Buffer was returned in NumberHandles.
+ @retval EFI_NOT_FOUND No FVB handle was found.
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the matching results.
+ @retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.
+
+**/
+EFI_STATUS
+GetFvbCountAndBuffer (
+ OUT UINTN *NumberHandles,
+ OUT EFI_HANDLE **Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate all handles of Fvb protocol
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ NumberHandles,
+ Buffer
+ );
+ return Status;
+}
+
+
+/**
+ Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+
+ This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+ It convers pointer to new virtual address.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+VariableClassAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ LIST_ENTRY *Link;
+ VARIABLE_ENTRY *Entry;
+ EFI_STATUS Status;
+
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetAttributes);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->SetAttributes);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Read);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Write);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->EraseBlocks);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.HobVariableBase);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
+ EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
+
+ //
+ // in the list of locked variables, convert the name pointers first
+ //
+ for ( Link = GetFirstNode (&mLockedVariableList)
+ ; !IsNull (&mLockedVariableList, Link)
+ ; Link = GetNextNode (&mLockedVariableList, Link)
+ ) {
+ Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);
+ Status = EfiConvertPointer (0x0, (VOID **) &Entry->Name);
+ ASSERT_EFI_ERROR (Status);
+ }
+ //
+ // second, convert the list itself using UefiRuntimeLib
+ //
+ Status = EfiConvertList (0x0, &mLockedVariableList);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+ Notification function of EVT_GROUP_READY_TO_BOOT event group.
+
+ This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.
+ When the Boot Manager is about to load and execute a boot option, it reclaims variable
+ storage if free size is below the threshold.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+OnReadyToBoot (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+{
+ //
+ // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled.
+ //
+ mEndOfDxe = TRUE;
+ ReclaimForOS ();
+ if (FeaturePcdGet (PcdVariableCollectStatistics)) {
+ gBS->InstallConfigurationTable (&gEfiVariableGuid, gVariableInfo);
+ }
+}
+
+/**
+ Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
+
+ This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+OnEndOfDxe (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+{
+ mEndOfDxe = TRUE;
+}
+
+/**
+ Fault Tolerant Write protocol notification event handler.
+
+ Non-Volatile variable write may needs FTW protocol to reclaim when
+ writting variable.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+FtwNotificationEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;
+ EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
+ EFI_PHYSICAL_ADDRESS NvStorageVariableBase;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 Length;
+ EFI_PHYSICAL_ADDRESS VariableStoreBase;
+ UINT64 VariableStoreLength;
+
+ //
+ // Ensure FTW protocol is installed.
+ //
+ Status = GetFtwProtocol ((VOID**) &FtwProtocol);
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+
+ //
+ // Find the proper FVB protocol for variable.
+ //
+ NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);
+ if (NvStorageVariableBase == 0) {
+ NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);
+ }
+ Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+ mVariableModuleGlobal->FvbInstance = FvbProtocol;
+
+ //
+ // Mark the variable storage region of the FLASH as RUNTIME.
+ //
+ VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;
+ VariableStoreLength = ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase)->Size;
+ BaseAddress = VariableStoreBase & (~EFI_PAGE_MASK);
+ Length = VariableStoreLength + (VariableStoreBase - BaseAddress);
+ Length = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK);
+
+ Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));
+ } else {
+ Status = gDS->SetMemorySpaceAttributes (
+ BaseAddress,
+ Length,
+ GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));
+ }
+ }
+
+ Status = VariableWriteServiceInitialize ();
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install the Variable Write Architectural protocol.
+ //
+ Status = gBS->InstallProtocolInterface (
+ &mHandle,
+ &gEfiVariableWriteArchProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again.
+ //
+ gBS->CloseEvent (Event);
+
+}
+
+
+/**
+ Variable Driver main entry point. The Variable driver places the 4 EFI
+ runtime services in the EFI System Table and installs arch protocols
+ for variable read and write services being availible. It also registers
+ a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS Variable service successfully initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT ReadyToBootEvent;
+ EFI_EVENT EndOfDxeEvent;
+
+ Status = VariableCommonInitialize ();
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEdkiiVariableLockProtocolGuid,
+ &mVariableLock,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable;
+ SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
+ SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;
+ SystemTable->RuntimeServices->QueryVariableInfo = VariableServiceQueryVariableInfo;
+
+ //
+ // Now install the Variable Runtime Architectural protocol on a new handle.
+ //
+ Status = gBS->InstallProtocolInterface (
+ &mHandle,
+ &gEfiVariableArchProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register FtwNotificationEvent () notify function.
+ //
+ EfiCreateProtocolNotifyEvent (
+ &gEfiFaultTolerantWriteProtocolGuid,
+ TPL_CALLBACK,
+ FtwNotificationEvent,
+ (VOID *)SystemTable,
+ &mFtwRegistration
+ );
+
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ VariableClassAddressChangeEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mVirtualAddressChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register the event handling function to reclaim variable for OS usage.
+ //
+ Status = EfiCreateEventReadyToBootEx (
+ TPL_NOTIFY,
+ OnReadyToBoot,
+ NULL,
+ &ReadyToBootEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register the event handling function to set the End Of DXE flag.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ OnEndOfDxe,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
-/** @file\r
- Implement all four UEFI Runtime Variable services for the nonvolatile\r
- and volatile storage space and install variable architecture protocol.\r
-\r
-Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "Variable.h"\r
-#include "AuthService.h"\r
-\r
-extern VARIABLE_STORE_HEADER *mNvVariableCache;\r
-extern VARIABLE_INFO_ENTRY *gVariableInfo;\r
-EFI_HANDLE mHandle = NULL;\r
-EFI_EVENT mVirtualAddressChangeEvent = NULL;\r
-EFI_EVENT mFtwRegistration = NULL;\r
-extern BOOLEAN mEndOfDxe;\r
-EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock = { VariableLockRequestToLock };\r
-\r
-/**\r
- Return TRUE if ExitBootServices () has been called.\r
-\r
- @retval TRUE If ExitBootServices () has been called.\r
-**/\r
-BOOLEAN\r
-AtRuntime (\r
- VOID\r
- )\r
-{\r
- return EfiAtRuntime ();\r
-}\r
-\r
-\r
-/**\r
- Initializes a basic mutual exclusion lock.\r
-\r
- This function initializes a basic mutual exclusion lock to the released state\r
- and returns the lock. Each lock provides mutual exclusion access at its task\r
- priority level. Since there is no preemption or multiprocessor support in EFI,\r
- acquiring the lock only consists of raising to the locks TPL.\r
- If Lock is NULL, then ASSERT().\r
- If Priority is not a valid TPL value, then ASSERT().\r
-\r
- @param Lock A pointer to the lock data structure to initialize.\r
- @param Priority EFI TPL is associated with the lock.\r
-\r
- @return The lock.\r
-\r
-**/\r
-EFI_LOCK *\r
-InitializeLock (\r
- IN OUT EFI_LOCK *Lock,\r
- IN EFI_TPL Priority\r
- )\r
-{\r
- return EfiInitializeLock (Lock, Priority);\r
-}\r
-\r
-\r
-/**\r
- Acquires lock only at boot time. Simply returns at runtime.\r
-\r
- This is a temperary function that will be removed when\r
- EfiAcquireLock() in UefiLib can handle the call in UEFI\r
- Runtimer driver in RT phase.\r
- It calls EfiAcquireLock() at boot time, and simply returns\r
- at runtime.\r
-\r
- @param Lock A pointer to the lock to acquire.\r
-\r
-**/\r
-VOID\r
-AcquireLockOnlyAtBootTime (\r
- IN EFI_LOCK *Lock\r
- )\r
-{\r
- if (!AtRuntime ()) {\r
- EfiAcquireLock (Lock);\r
- }\r
-}\r
-\r
-\r
-/**\r
- Releases lock only at boot time. Simply returns at runtime.\r
-\r
- This is a temperary function which will be removed when\r
- EfiReleaseLock() in UefiLib can handle the call in UEFI\r
- Runtimer driver in RT phase.\r
- It calls EfiReleaseLock() at boot time and simply returns\r
- at runtime.\r
-\r
- @param Lock A pointer to the lock to release.\r
-\r
-**/\r
-VOID\r
-ReleaseLockOnlyAtBootTime (\r
- IN EFI_LOCK *Lock\r
- )\r
-{\r
- if (!AtRuntime ()) {\r
- EfiReleaseLock (Lock);\r
- }\r
-}\r
-\r
-/**\r
- Retrive the Fault Tolerent Write protocol interface.\r
-\r
- @param[out] FtwProtocol The interface of Ftw protocol\r
-\r
- @retval EFI_SUCCESS The FTW protocol instance was found and returned in FtwProtocol.\r
- @retval EFI_NOT_FOUND The FTW protocol instance was not found.\r
- @retval EFI_INVALID_PARAMETER SarProtocol is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-GetFtwProtocol (\r
- OUT VOID **FtwProtocol\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Locate Fault Tolerent Write protocol\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiFaultTolerantWriteProtocolGuid,\r
- NULL,\r
- FtwProtocol\r
- );\r
- return Status;\r
-}\r
-\r
-/**\r
- Retrive the FVB protocol interface by HANDLE.\r
-\r
- @param[in] FvBlockHandle The handle of FVB protocol that provides services for\r
- reading, writing, and erasing the target block.\r
- @param[out] FvBlock The interface of FVB protocol\r
-\r
- @retval EFI_SUCCESS The interface information for the specified protocol was returned.\r
- @retval EFI_UNSUPPORTED The device does not support the FVB protocol.\r
- @retval EFI_INVALID_PARAMETER FvBlockHandle is not a valid EFI_HANDLE or FvBlock is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-GetFvbByHandle (\r
- IN EFI_HANDLE FvBlockHandle,\r
- OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock\r
- )\r
-{\r
- //\r
- // To get the FVB protocol interface on the handle\r
- //\r
- return gBS->HandleProtocol (\r
- FvBlockHandle,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- (VOID **) FvBlock\r
- );\r
-}\r
-\r
-\r
-/**\r
- Function returns an array of handles that support the FVB protocol\r
- in a buffer allocated from pool.\r
-\r
- @param[out] NumberHandles The number of handles returned in Buffer.\r
- @param[out] Buffer A pointer to the buffer to return the requested\r
- array of handles that support FVB protocol.\r
-\r
- @retval EFI_SUCCESS The array of handles was returned in Buffer, and the number of\r
- handles in Buffer was returned in NumberHandles.\r
- @retval EFI_NOT_FOUND No FVB handle was found.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the matching results.\r
- @retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-GetFvbCountAndBuffer (\r
- OUT UINTN *NumberHandles,\r
- OUT EFI_HANDLE **Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Locate all handles of Fvb protocol\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- NULL,\r
- NumberHandles,\r
- Buffer\r
- );\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.\r
-\r
- This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
- It convers pointer to new virtual address.\r
-\r
- @param Event Event whose notification function is being invoked.\r
- @param Context Pointer to the notification function's context.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-VariableClassAddressChangeEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetAttributes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->SetAttributes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Read);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Write);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->EraseBlocks);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);\r
- EfiConvertPointer (0x0, (VOID **) &mHashCtx);\r
- EfiConvertPointer (0x0, (VOID **) &mStorageArea);\r
- EfiConvertPointer (0x0, (VOID **) &mSerializationRuntimeBuffer);\r
- EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);\r
-}\r
-\r
-\r
-/**\r
- Notification function of EVT_GROUP_READY_TO_BOOT event group.\r
-\r
- This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.\r
- When the Boot Manager is about to load and execute a boot option, it reclaims variable\r
- storage if free size is below the threshold.\r
-\r
- @param Event Event whose notification function is being invoked.\r
- @param Context Pointer to the notification function's context.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-OnReadyToBoot (\r
- EFI_EVENT Event,\r
- VOID *Context\r
- )\r
-{\r
- //\r
- // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled.\r
- //\r
- mEndOfDxe = TRUE;\r
- ReclaimForOS ();\r
- if (FeaturePcdGet (PcdVariableCollectStatistics)) {\r
- gBS->InstallConfigurationTable (&gEfiAuthenticatedVariableGuid, gVariableInfo);\r
- }\r
-}\r
-\r
-/**\r
- Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.\r
-\r
- This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.\r
-\r
- @param Event Event whose notification function is being invoked.\r
- @param Context Pointer to the notification function's context.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-OnEndOfDxe (\r
- EFI_EVENT Event,\r
- VOID *Context\r
- )\r
-{\r
- mEndOfDxe = TRUE;\r
-}\r
-\r
-/**\r
- Fault Tolerant Write protocol notification event handler.\r
-\r
- Non-Volatile variable write may needs FTW protocol to reclaim when\r
- writting variable.\r
-\r
- @param[in] Event Event whose notification function is being invoked.\r
- @param[in] Context Pointer to the notification function's context.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-FtwNotificationEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;\r
- EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;\r
- EFI_PHYSICAL_ADDRESS NvStorageVariableBase;\r
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r
- EFI_PHYSICAL_ADDRESS BaseAddress;\r
- UINT64 Length;\r
- EFI_PHYSICAL_ADDRESS VariableStoreBase;\r
- UINT64 VariableStoreLength;\r
-\r
- //\r
- // Ensure FTW protocol is installed.\r
- //\r
- Status = GetFtwProtocol ((VOID**) &FtwProtocol);\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
-\r
- //\r
- // Find the proper FVB protocol for variable.\r
- //\r
- NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);\r
- if (NvStorageVariableBase == 0) {\r
- NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);\r
- }\r
- Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
- mVariableModuleGlobal->FvbInstance = FvbProtocol;\r
-\r
- //\r
- // Mark the variable storage region of the FLASH as RUNTIME.\r
- //\r
- VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;\r
- VariableStoreLength = ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase)->Size;\r
- BaseAddress = VariableStoreBase & (~EFI_PAGE_MASK);\r
- Length = VariableStoreLength + (VariableStoreBase - BaseAddress);\r
- Length = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK);\r
-\r
- Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));\r
- } else {\r
- Status = gDS->SetMemorySpaceAttributes (\r
- BaseAddress,\r
- Length,\r
- GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));\r
- }\r
- }\r
-\r
- Status = VariableWriteServiceInitialize ();\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Install the Variable Write Architectural protocol.\r
- //\r
- Status = gBS->InstallProtocolInterface (\r
- &mHandle,\r
- &gEfiVariableWriteArchProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again.\r
- //\r
- gBS->CloseEvent (Event);\r
-\r
-}\r
-\r
-\r
-/**\r
- Variable Driver main entry point. The Variable driver places the 4 EFI\r
- runtime services in the EFI System Table and installs arch protocols\r
- for variable read and write services being available. It also registers\r
- a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
-\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
- @param[in] SystemTable A pointer to the EFI System Table.\r
-\r
- @retval EFI_SUCCESS Variable service successfully initialized.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-VariableServiceInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_EVENT ReadyToBootEvent;\r
- EFI_EVENT EndOfDxeEvent;\r
-\r
- Status = VariableCommonInitialize ();\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &mHandle,\r
- &gEdkiiVariableLockProtocolGuid,\r
- &mVariableLock,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable;\r
- SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;\r
- SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;\r
- SystemTable->RuntimeServices->QueryVariableInfo = VariableServiceQueryVariableInfo;\r
-\r
- //\r
- // Now install the Variable Runtime Architectural protocol on a new handle.\r
- //\r
- Status = gBS->InstallProtocolInterface (\r
- &mHandle,\r
- &gEfiVariableArchProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Register FtwNotificationEvent () notify function.\r
- //\r
- EfiCreateProtocolNotifyEvent (\r
- &gEfiFaultTolerantWriteProtocolGuid,\r
- TPL_CALLBACK,\r
- FtwNotificationEvent,\r
- (VOID *)SystemTable,\r
- &mFtwRegistration\r
- );\r
-\r
- Status = gBS->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- VariableClassAddressChangeEvent,\r
- NULL,\r
- &gEfiEventVirtualAddressChangeGuid,\r
- &mVirtualAddressChangeEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Register the event handling function to reclaim variable for OS usage.\r
- //\r
- Status = EfiCreateEventReadyToBootEx (\r
- TPL_NOTIFY,\r
- OnReadyToBoot,\r
- NULL,\r
- &ReadyToBootEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Register the event handling function to set the End Of DXE flag.\r
- //\r
- Status = gBS->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- OnEndOfDxe,\r
- NULL,\r
- &gEfiEndOfDxeEventGroupGuid,\r
- &EndOfDxeEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
+/** @file
+ Implement all four UEFI Runtime Variable services for the nonvolatile
+ and volatile storage space and install variable architecture protocol.
+
+Copyright (C) 2013, Red Hat, Inc.
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Variable.h"
+#include "AuthService.h"
+
+extern VARIABLE_STORE_HEADER *mNvVariableCache;
+extern VARIABLE_INFO_ENTRY *gVariableInfo;
+EFI_HANDLE mHandle = NULL;
+EFI_EVENT mVirtualAddressChangeEvent = NULL;
+EFI_EVENT mFtwRegistration = NULL;
+extern LIST_ENTRY mLockedVariableList;
+extern BOOLEAN mEndOfDxe;
+EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock = { VariableLockRequestToLock };
+
+/**
+ Return TRUE if ExitBootServices () has been called.
+
+ @retval TRUE If ExitBootServices () has been called.
+**/
+BOOLEAN
+AtRuntime (
+ VOID
+ )
+{
+ return EfiAtRuntime ();
+}
+
+
+/**
+ Initializes a basic mutual exclusion lock.
+
+ This function initializes a basic mutual exclusion lock to the released state
+ and returns the lock. Each lock provides mutual exclusion access at its task
+ priority level. Since there is no preemption or multiprocessor support in EFI,
+ acquiring the lock only consists of raising to the locks TPL.
+ If Lock is NULL, then ASSERT().
+ If Priority is not a valid TPL value, then ASSERT().
+
+ @param Lock A pointer to the lock data structure to initialize.
+ @param Priority EFI TPL is associated with the lock.
+
+ @return The lock.
+
+**/
+EFI_LOCK *
+InitializeLock (
+ IN OUT EFI_LOCK *Lock,
+ IN EFI_TPL Priority
+ )
+{
+ return EfiInitializeLock (Lock, Priority);
+}
+
+
+/**
+ Acquires lock only at boot time. Simply returns at runtime.
+
+ This is a temperary function that will be removed when
+ EfiAcquireLock() in UefiLib can handle the call in UEFI
+ Runtimer driver in RT phase.
+ It calls EfiAcquireLock() at boot time, and simply returns
+ at runtime.
+
+ @param Lock A pointer to the lock to acquire.
+
+**/
+VOID
+AcquireLockOnlyAtBootTime (
+ IN EFI_LOCK *Lock
+ )
+{
+ if (!AtRuntime ()) {
+ EfiAcquireLock (Lock);
+ }
+}
+
+
+/**
+ Releases lock only at boot time. Simply returns at runtime.
+
+ This is a temperary function which will be removed when
+ EfiReleaseLock() in UefiLib can handle the call in UEFI
+ Runtimer driver in RT phase.
+ It calls EfiReleaseLock() at boot time and simply returns
+ at runtime.
+
+ @param Lock A pointer to the lock to release.
+
+**/
+VOID
+ReleaseLockOnlyAtBootTime (
+ IN EFI_LOCK *Lock
+ )
+{
+ if (!AtRuntime ()) {
+ EfiReleaseLock (Lock);
+ }
+}
+
+/**
+ Retrive the Fault Tolerent Write protocol interface.
+
+ @param[out] FtwProtocol The interface of Ftw protocol
+
+ @retval EFI_SUCCESS The FTW protocol instance was found and returned in FtwProtocol.
+ @retval EFI_NOT_FOUND The FTW protocol instance was not found.
+ @retval EFI_INVALID_PARAMETER SarProtocol is NULL.
+
+**/
+EFI_STATUS
+GetFtwProtocol (
+ OUT VOID **FtwProtocol
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate Fault Tolerent Write protocol
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiFaultTolerantWriteProtocolGuid,
+ NULL,
+ FtwProtocol
+ );
+ return Status;
+}
+
+/**
+ Retrive the FVB protocol interface by HANDLE.
+
+ @param[in] FvBlockHandle The handle of FVB protocol that provides services for
+ reading, writing, and erasing the target block.
+ @param[out] FvBlock The interface of FVB protocol
+
+ @retval EFI_SUCCESS The interface information for the specified protocol was returned.
+ @retval EFI_UNSUPPORTED The device does not support the FVB protocol.
+ @retval EFI_INVALID_PARAMETER FvBlockHandle is not a valid EFI_HANDLE or FvBlock is NULL.
+
+**/
+EFI_STATUS
+GetFvbByHandle (
+ IN EFI_HANDLE FvBlockHandle,
+ OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock
+ )
+{
+ //
+ // To get the FVB protocol interface on the handle
+ //
+ return gBS->HandleProtocol (
+ FvBlockHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ (VOID **) FvBlock
+ );
+}
+
+
+/**
+ Function returns an array of handles that support the FVB protocol
+ in a buffer allocated from pool.
+
+ @param[out] NumberHandles The number of handles returned in Buffer.
+ @param[out] Buffer A pointer to the buffer to return the requested
+ array of handles that support FVB protocol.
+
+ @retval EFI_SUCCESS The array of handles was returned in Buffer, and the number of
+ handles in Buffer was returned in NumberHandles.
+ @retval EFI_NOT_FOUND No FVB handle was found.
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the matching results.
+ @retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.
+
+**/
+EFI_STATUS
+GetFvbCountAndBuffer (
+ OUT UINTN *NumberHandles,
+ OUT EFI_HANDLE **Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate all handles of Fvb protocol
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ NumberHandles,
+ Buffer
+ );
+ return Status;
+}
+
+
+/**
+ Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+
+ This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+ It convers pointer to new virtual address.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+VariableClassAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ LIST_ENTRY *Link;
+ VARIABLE_ENTRY *Entry;
+ EFI_STATUS Status;
+
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetAttributes);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->SetAttributes);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Read);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Write);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->EraseBlocks);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
+ EfiConvertPointer (0x0, (VOID **) &mHashCtx);
+ EfiConvertPointer (0x0, (VOID **) &mStorageArea);
+ EfiConvertPointer (0x0, (VOID **) &mSerializationRuntimeBuffer);
+ EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
+
+ //
+ // in the list of locked variables, convert the name pointers first
+ //
+ for ( Link = GetFirstNode (&mLockedVariableList)
+ ; !IsNull (&mLockedVariableList, Link)
+ ; Link = GetNextNode (&mLockedVariableList, Link)
+ ) {
+ Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);
+ Status = EfiConvertPointer (0x0, (VOID **) &Entry->Name);
+ ASSERT_EFI_ERROR (Status);
+ }
+ //
+ // second, convert the list itself using UefiRuntimeLib
+ //
+ Status = EfiConvertList (0x0, &mLockedVariableList);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+ Notification function of EVT_GROUP_READY_TO_BOOT event group.
+
+ This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.
+ When the Boot Manager is about to load and execute a boot option, it reclaims variable
+ storage if free size is below the threshold.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+OnReadyToBoot (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+{
+ //
+ // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled.
+ //
+ mEndOfDxe = TRUE;
+ ReclaimForOS ();
+ if (FeaturePcdGet (PcdVariableCollectStatistics)) {
+ gBS->InstallConfigurationTable (&gEfiAuthenticatedVariableGuid, gVariableInfo);
+ }
+}
+
+/**
+ Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
+
+ This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+OnEndOfDxe (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+{
+ mEndOfDxe = TRUE;
+}
+
+/**
+ Fault Tolerant Write protocol notification event handler.
+
+ Non-Volatile variable write may needs FTW protocol to reclaim when
+ writting variable.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+FtwNotificationEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;
+ EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
+ EFI_PHYSICAL_ADDRESS NvStorageVariableBase;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 Length;
+ EFI_PHYSICAL_ADDRESS VariableStoreBase;
+ UINT64 VariableStoreLength;
+
+ //
+ // Ensure FTW protocol is installed.
+ //
+ Status = GetFtwProtocol ((VOID**) &FtwProtocol);
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+
+ //
+ // Find the proper FVB protocol for variable.
+ //
+ NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);
+ if (NvStorageVariableBase == 0) {
+ NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);
+ }
+ Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+ mVariableModuleGlobal->FvbInstance = FvbProtocol;
+
+ //
+ // Mark the variable storage region of the FLASH as RUNTIME.
+ //
+ VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;
+ VariableStoreLength = ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase)->Size;
+ BaseAddress = VariableStoreBase & (~EFI_PAGE_MASK);
+ Length = VariableStoreLength + (VariableStoreBase - BaseAddress);
+ Length = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK);
+
+ Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));
+ } else {
+ Status = gDS->SetMemorySpaceAttributes (
+ BaseAddress,
+ Length,
+ GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));
+ }
+ }
+
+ Status = VariableWriteServiceInitialize ();
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install the Variable Write Architectural protocol.
+ //
+ Status = gBS->InstallProtocolInterface (
+ &mHandle,
+ &gEfiVariableWriteArchProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again.
+ //
+ gBS->CloseEvent (Event);
+
+}
+
+
+/**
+ Variable Driver main entry point. The Variable driver places the 4 EFI
+ runtime services in the EFI System Table and installs arch protocols
+ for variable read and write services being available. It also registers
+ a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS Variable service successfully initialized.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT ReadyToBootEvent;
+ EFI_EVENT EndOfDxeEvent;
+
+ Status = VariableCommonInitialize ();
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEdkiiVariableLockProtocolGuid,
+ &mVariableLock,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable;
+ SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
+ SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;
+ SystemTable->RuntimeServices->QueryVariableInfo = VariableServiceQueryVariableInfo;
+
+ //
+ // Now install the Variable Runtime Architectural protocol on a new handle.
+ //
+ Status = gBS->InstallProtocolInterface (
+ &mHandle,
+ &gEfiVariableArchProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register FtwNotificationEvent () notify function.
+ //
+ EfiCreateProtocolNotifyEvent (
+ &gEfiFaultTolerantWriteProtocolGuid,
+ TPL_CALLBACK,
+ FtwNotificationEvent,
+ (VOID *)SystemTable,
+ &mFtwRegistration
+ );
+
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ VariableClassAddressChangeEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mVirtualAddressChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register the event handling function to reclaim variable for OS usage.
+ //
+ Status = EfiCreateEventReadyToBootEx (
+ TPL_NOTIFY,
+ OnReadyToBoot,
+ NULL,
+ &ReadyToBootEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register the event handling function to set the End Of DXE flag.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ OnEndOfDxe,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+