]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
Change EFI_OPTIONAL_POINTER to EFI_OPTIONAL_PTR
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / Variable.c
index 9f6a9acd5010740e206f8baad07149b13cb29720..694de8da599d5a035dc4650c540e308f90112339 100644 (file)
@@ -1,14 +1,16 @@
 /** @file\r
-  EFI Runtime Variable services.\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 - 2008, Intel Corporation                                                         \r
-  All rights reserved. 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
+Copyright (c) 2006 - 2008, Intel Corporation                                                         \r
+All rights reserved. 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
+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
@@ -19,6 +21,25 @@ VARIABLE_MODULE_GLOBAL  *mVariableModuleGlobal;
 EFI_EVENT   mVirtualAddressChangeEvent = NULL;\r
 EFI_HANDLE  mHandle = NULL;\r
 \r
+//\r
+// The current Hii implementation accesses this variable a larg # of times on every boot.\r
+// Other common variables are only accessed a single time. This is why this cache algorithm\r
+// only targets a single variable. Probably to get an performance improvement out of\r
+// a Cache you would need a cache that improves the search performance for a variable.\r
+//\r
+VARIABLE_CACHE_ENTRY mVariableCache[] = {\r
+  {\r
+    &gEfiGlobalVariableGuid,\r
+    L"Lang",\r
+    0x00000000,\r
+    0x00,\r
+    NULL\r
+  }\r
+};\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED VARIABLE_INFO_ENTRY *gVariableInfo = NULL;\r
+\r
+\r
 \r
 //\r
 // This is a temperary function which will be removed\r
@@ -51,9 +72,6 @@ ReleaseLockOnlyAtBootTime (
 }\r
 \r
 \r
-GLOBAL_REMOVE_IF_UNREFERENCED VARIABLE_INFO_ENTRY *gVariableInfo = NULL;\r
-\r
-\r
 /**\r
   Routine used to track statistical information about variable usage. \r
   The data is stored in the EFI system table so it can be accessed later.\r
@@ -604,12 +622,16 @@ Returns:
   UINT8                 *ValidBuffer;\r
   UINTN                 MaximumBufferSize;\r
   UINTN                 VariableSize;\r
+  UINTN                 VariableNameSize;\r
+  UINTN                 UpdatingVariableNameSize;\r
   UINTN                 NameSize;\r
   UINT8                 *CurrPtr;\r
   VOID                  *Point0;\r
   VOID                  *Point1;\r
   BOOLEAN               FoundAdded;\r
   EFI_STATUS            Status;\r
+  CHAR16                *VariableNamePtr;\r
+  CHAR16                *UpdatingVariableNamePtr;\r
 \r
   VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);\r
 \r
@@ -654,26 +676,53 @@ Returns:
   //\r
 \r
   //\r
-  // Reinstall all ADDED variables\r
+  // Reinstall all ADDED variables as long as they are not identical to Updating Variable\r
   // \r
   Variable = GetStartPointer (VariableStoreHeader);\r
   while (IsValidVariableHeader (Variable)) {\r
     NextVariable = GetNextVariablePtr (Variable);\r
     if (Variable->State == VAR_ADDED) {\r
+      if (UpdatingVariable != NULL) {\r
+        if (UpdatingVariable == Variable) {\r
+          Variable = NextVariable;\r
+          continue;\r
+        }\r
+\r
+        VariableNameSize         = NameSizeOfVariable(Variable);\r
+        UpdatingVariableNameSize = NameSizeOfVariable(UpdatingVariable);\r
+\r
+        VariableNamePtr         = GetVariableNamePtr (Variable);\r
+        UpdatingVariableNamePtr = GetVariableNamePtr (UpdatingVariable);\r
+        if (CompareGuid (&Variable->VendorGuid, &UpdatingVariable->VendorGuid)    &&\r
+            VariableNameSize == UpdatingVariableNameSize &&\r
+            CompareMem (VariableNamePtr, UpdatingVariableNamePtr, VariableNameSize) == 0 ) {\r
+          Variable = NextVariable;\r
+          continue;\r
+        }\r
+      }\r
       VariableSize = (UINTN) NextVariable - (UINTN) Variable;\r
       CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);\r
       CurrPtr += VariableSize;\r
     }\r
-\r
     Variable = NextVariable;\r
   }\r
+\r
+  //\r
+  // Reinstall the variable being updated if it is not NULL\r
+  //\r
+  if (UpdatingVariable != NULL) {\r
+    VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - (UINTN)UpdatingVariable;\r
+    CopyMem (CurrPtr, (UINT8 *) UpdatingVariable, VariableSize);\r
+    CurrPtr += VariableSize;\r
+  }\r
+\r
   //\r
   // Reinstall all in delete transition variables\r
   // \r
   Variable      = GetStartPointer (VariableStoreHeader);\r
   while (IsValidVariableHeader (Variable)) {\r
     NextVariable = GetNextVariablePtr (Variable);\r
-    if (Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
+    if (Variable != UpdatingVariable && Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
 \r
       //\r
       // Buffer has cached all ADDED variable. \r
@@ -691,12 +740,7 @@ Returns:
            ) {\r
           Point0 = (VOID *) GetVariableNamePtr (AddedVariable);\r
           Point1 = (VOID *) GetVariableNamePtr (Variable);\r
-          if (!CompareMem (\r
-                Point0,\r
-                Point1,\r
-                NameSizeOfVariable (AddedVariable)\r
-                )\r
-             ) {\r
+          if (CompareMem (Point0, Point1, NameSizeOfVariable (AddedVariable)) == 0) {\r
             FoundAdded = TRUE;\r
             break;\r
           }\r
@@ -704,11 +748,12 @@ Returns:
         AddedVariable = NextAddedVariable;\r
       }\r
       if (!FoundAdded) {\r
+        //\r
+        // Promote VAR_IN_DELETED_TRANSITION to VAR_ADDED\r
+        //\r
         VariableSize = (UINTN) NextVariable - (UINTN) Variable;\r
         CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);\r
-        if (Variable != UpdatingVariable) {\r
-          ((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED;\r
-        }\r
+        ((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED;\r
         CurrPtr += VariableSize;\r
       }\r
     }\r
@@ -745,23 +790,6 @@ Returns:
 }\r
 \r
 \r
-//\r
-// The current Hii implementation accesses this variable a larg # of times on every boot.\r
-// Other common variables are only accessed a single time. This is why this cache algorithm\r
-// only targets a single variable. Probably to get an performance improvement out of\r
-// a Cache you would need a cache that improves the search performance for a variable.\r
-//\r
-VARIABLE_CACHE_ENTRY mVariableCache[] = {\r
-  {\r
-    &gEfiGlobalVariableGuid,\r
-    L"Lang",\r
-    0x00000000,\r
-    0x00,\r
-    NULL\r
-  }\r
-};\r
-\r
-\r
 /**\r
   Update the Cache with Variable information. These are the same \r
   arguments as the EFI Variable services.\r