diff options
author | Ruiyu Ni <ruiyu.ni@intel.com> | 2013-06-17 02:18:58 +0000 |
---|---|---|
committer | niruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524> | 2013-06-17 02:18:58 +0000 |
commit | e4b7e2c94f14f370edd07f58b6abbb5a614cabcd (patch) | |
tree | 8a7c70bd8a6c85f06ad777fcc3f748b0b91f1d6b /MdeModulePkg/Universal | |
parent | fd4ba547a13a4e3ddfb820de59887875bf86c5de (diff) | |
download | edk2-platforms-e4b7e2c94f14f370edd07f58b6abbb5a614cabcd.tar.xz |
Revert the changes made in 14403 because it incorrectly changed the EOL.
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14424 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal')
-rw-r--r-- | MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c | 981 |
1 files changed, 479 insertions, 502 deletions
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c index 2aa2946904..3cb2c6bcf3 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c @@ -1,502 +1,479 @@ -/** @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
+
+ Implement all four UEFI Runtime Variable services for the nonvolatile
+ and volatile storage space and install variable architecture protocol.
+
+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 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
+ )
+{
+ 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);
+}
+
+
+/**
+ 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;
+}
+
|