]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Revert the changes made in 14403 because it incorrectly changed the EOL.
authorRuiyu Ni <ruiyu.ni@intel.com>
Mon, 17 Jun 2013 02:18:58 +0000 (02:18 +0000)
committerniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 17 Jun 2013 02:18:58 +0000 (02:18 +0000)
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

MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c

index 2aa29469047adb535fc9b6656d710ad5bed758a4..3cb2c6bcf309dcc6d632017fbafc1ac9c838117c 100644 (file)
-/** @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
+\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
index e0c7ee13da0ca69a7cbdf254441e6c8df35debb4..a2e764cf610c5d4046e6c947fc2e2d46006fdd69 100644 (file)
-/** @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;
-}
-
+/** @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