]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
MdeModulePkg Variable: Enhance variable performance by reading from existed memory...
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / Variable.c
index 31e1937c2f19ed62daa1f29730548dbb4e34e441..e5ffb5a4e328412cbf1f715dc3345ffa71486d00 100644 (file)
@@ -17,6 +17,7 @@
   integer overflow. It should also check attribute to avoid authentication bypass.\r
 \r
 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<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
@@ -36,6 +37,11 @@ VARIABLE_MODULE_GLOBAL  *mVariableModuleGlobal;
 ///\r
 VARIABLE_STORE_HEADER  *mNvVariableCache      = NULL;\r
 \r
+///\r
+/// Memory cache of Fv Header.\r
+///\r
+EFI_FIRMWARE_VOLUME_HEADER *mNvFvHeaderCache  = NULL;\r
+\r
 ///\r
 /// The memory entry used for variable statistics data.\r
 ///\r
@@ -333,7 +339,7 @@ UpdateVariableStore (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {\r
+  for (PtrBlockMapEntry = mNvFvHeaderCache->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {\r
     for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) {\r
       //\r
       // Check to see if the Variable Writes are spanning through multiple\r
@@ -2209,7 +2215,8 @@ UpdateVariable (
     VariableStoreHeader  = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
     Variable = &NvVariable;\r
     Variable->StartPtr = GetStartPointer (VariableStoreHeader);\r
-    Variable->EndPtr   = GetEndPointer (VariableStoreHeader);\r
+    Variable->EndPtr   = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->EndPtr - (UINTN)CacheVariable->StartPtr));\r
+\r
     Variable->CurrPtr  = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->CurrPtr - (UINTN)CacheVariable->StartPtr));\r
     if (CacheVariable->InDeletedTransitionPtr != NULL) {\r
       Variable->InDeletedTransitionPtr = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->InDeletedTransitionPtr - (UINTN)CacheVariable->StartPtr));\r
@@ -2247,7 +2254,7 @@ UpdateVariable (
       //\r
       // Only variable that have NV attributes can be updated/deleted in Runtime.\r
       //\r
-      if ((Variable->CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {\r
+      if ((CacheVariable->CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {\r
         Status = EFI_INVALID_PARAMETER;\r
         goto Done;\r
       }\r
@@ -2255,7 +2262,7 @@ UpdateVariable (
       //\r
       // Only variable that have RT attributes can be updated/deleted in Runtime.\r
       //\r
-      if ((Variable->CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) {\r
+      if ((CacheVariable->CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) {\r
         Status = EFI_INVALID_PARAMETER;\r
         goto Done;\r
       }\r
@@ -2273,7 +2280,7 @@ UpdateVariable (
         // Both ADDED and IN_DELETED_TRANSITION variable are present,\r
         // set IN_DELETED_TRANSITION one to DELETED state first.\r
         //\r
-        State = Variable->InDeletedTransitionPtr->State;\r
+        State = CacheVariable->InDeletedTransitionPtr->State;\r
         State &= VAR_DELETED;\r
         Status = UpdateVariableStore (\r
                    &mVariableModuleGlobal->VariableGlobal,\r
@@ -2294,7 +2301,7 @@ UpdateVariable (
         }\r
       }\r
 \r
-      State = Variable->CurrPtr->State;\r
+      State = CacheVariable->CurrPtr->State;\r
       State &= VAR_DELETED;\r
 \r
       Status = UpdateVariableStore (\r
@@ -2319,8 +2326,8 @@ UpdateVariable (
     // If the variable is marked valid, and the same data has been passed in,\r
     // then return to the caller immediately.\r
     //\r
-    if (DataSizeOfVariable (Variable->CurrPtr) == DataSize &&\r
-        (CompareMem (Data, GetVariableDataPtr (Variable->CurrPtr), DataSize) == 0) &&\r
+    if (DataSizeOfVariable (CacheVariable->CurrPtr) == DataSize &&\r
+        (CompareMem (Data, GetVariableDataPtr (CacheVariable->CurrPtr), DataSize) == 0) &&\r
         ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) &&\r
         (TimeStamp == NULL)) {\r
       //\r
@@ -2329,8 +2336,8 @@ UpdateVariable (
       UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, TRUE, FALSE, FALSE);\r
       Status = EFI_SUCCESS;\r
       goto Done;\r
-    } else if ((Variable->CurrPtr->State == VAR_ADDED) ||\r
-               (Variable->CurrPtr->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION))) {\r
+    } else if ((CacheVariable->CurrPtr->State == VAR_ADDED) ||\r
+               (CacheVariable->CurrPtr->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION))) {\r
 \r
       //\r
       // EFI_VARIABLE_APPEND_WRITE attribute only effects for existing variable.\r
@@ -2340,9 +2347,9 @@ UpdateVariable (
         // NOTE: From 0 to DataOffset of NextVariable is reserved for Variable Header and Name.\r
         // From DataOffset of NextVariable is to save the existing variable data.\r
         //\r
-        DataOffset = GetVariableDataOffset (Variable->CurrPtr);\r
+        DataOffset = GetVariableDataOffset (CacheVariable->CurrPtr);\r
         BufferForMerge = (UINT8 *) ((UINTN) NextVariable + DataOffset);\r
-        CopyMem (BufferForMerge, (UINT8 *) ((UINTN) Variable->CurrPtr + DataOffset), DataSizeOfVariable (Variable->CurrPtr));\r
+        CopyMem (BufferForMerge, (UINT8 *) ((UINTN) CacheVariable->CurrPtr + DataOffset), DataSizeOfVariable (CacheVariable->CurrPtr));\r
 \r
         //\r
         // Set Max Common/Auth Variable Data Size as default MaxDataSize.\r
@@ -2361,15 +2368,15 @@ UpdateVariable (
           MaxDataSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - DataOffset;\r
         }\r
 \r
-        if (DataSizeOfVariable (Variable->CurrPtr) + DataSize > MaxDataSize) {\r
+        if (DataSizeOfVariable (CacheVariable->CurrPtr) + DataSize > MaxDataSize) {\r
           //\r
           // Existing data size + new data size exceed maximum variable size limitation.\r
           //\r
           Status = EFI_INVALID_PARAMETER;\r
           goto Done;\r
         }\r
-        CopyMem ((UINT8*) ((UINTN) BufferForMerge + DataSizeOfVariable (Variable->CurrPtr)), Data, DataSize);\r
-        MergedBufSize = DataSizeOfVariable (Variable->CurrPtr) + DataSize;\r
+        CopyMem ((UINT8*) ((UINTN) BufferForMerge + DataSizeOfVariable (CacheVariable->CurrPtr)), Data, DataSize);\r
+        MergedBufSize = DataSizeOfVariable (CacheVariable->CurrPtr) + DataSize;\r
 \r
         //\r
         // BufferForMerge(from DataOffset of NextVariable) has included the merged existing and new data.\r
@@ -2382,7 +2389,7 @@ UpdateVariable (
       //\r
       // Mark the old variable as in delete transition.\r
       //\r
-      State = Variable->CurrPtr->State;\r
+      State = CacheVariable->CurrPtr->State;\r
       State &= VAR_IN_DELETED_TRANSITION;\r
 \r
       Status = UpdateVariableStore (\r
@@ -2456,7 +2463,7 @@ UpdateVariable (
         // with the variable, we need associate the new timestamp with the updated value.\r
         //\r
         if (Variable->CurrPtr != NULL) {\r
-          if (VariableCompareTimeStampInternal (&(((AUTHENTICATED_VARIABLE_HEADER *) Variable->CurrPtr)->TimeStamp), TimeStamp)) {\r
+          if (VariableCompareTimeStampInternal (&(((AUTHENTICATED_VARIABLE_HEADER *) CacheVariable->CurrPtr)->TimeStamp), TimeStamp)) {\r
             CopyMem (&AuthVariable->TimeStamp, TimeStamp, sizeof (EFI_TIME));\r
           }\r
         }\r
@@ -2712,7 +2719,7 @@ UpdateVariable (
       // Both ADDED and IN_DELETED_TRANSITION old variable are present,\r
       // set IN_DELETED_TRANSITION one to DELETED state first.\r
       //\r
-      State = Variable->InDeletedTransitionPtr->State;\r
+      State = CacheVariable->InDeletedTransitionPtr->State;\r
       State &= VAR_DELETED;\r
       Status = UpdateVariableStore (\r
                  &mVariableModuleGlobal->VariableGlobal,\r
@@ -3679,10 +3686,13 @@ InitNonVolatileVariableStore (
   VariableStoreBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) FvHeader + FvHeader->HeaderLength);\r
   VariableStoreLength = (UINT64) (NvStorageSize - FvHeader->HeaderLength);\r
 \r
+  mNvFvHeaderCache = FvHeader;\r
   mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;\r
   mNvVariableCache = (VARIABLE_STORE_HEADER *) (UINTN) VariableStoreBase;\r
   if (GetVariableStoreStatus (mNvVariableCache) != EfiValid) {\r
     FreePool (NvStorageData);\r
+    mNvFvHeaderCache = NULL;\r
+    mNvVariableCache = NULL;\r
     DEBUG((EFI_D_ERROR, "Variable Store header is corrupted\n"));\r
     return EFI_VOLUME_CORRUPTED;\r
   }\r
@@ -3858,7 +3868,6 @@ VariableWriteServiceInitialize (
   )\r
 {\r
   EFI_STATUS                      Status;\r
-  VARIABLE_STORE_HEADER           *VariableStoreHeader;\r
   UINTN                           Index;\r
   UINT8                           Data;\r
   EFI_PHYSICAL_ADDRESS            VariableStoreBase;\r
@@ -3871,18 +3880,17 @@ VariableWriteServiceInitialize (
   if (NvStorageBase == 0) {\r
     NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);\r
   }\r
-  VariableStoreBase = NvStorageBase + (((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(NvStorageBase))->HeaderLength);\r
+  VariableStoreBase = NvStorageBase + (mNvFvHeaderCache->HeaderLength);\r
 \r
   //\r
   // Let NonVolatileVariableBase point to flash variable store base directly after FTW ready.\r
   //\r
   mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;\r
-  VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;\r
 \r
   //\r
   // Check if the free area is really free.\r
   //\r
-  for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < VariableStoreHeader->Size; Index++) {\r
+  for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < mNvVariableCache->Size; Index++) {\r
     Data = ((UINT8 *) mNvVariableCache)[Index];\r
     if (Data != 0xff) {\r
       //\r