]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add Profiling support for Variable store and added a specialized caching algorithm
authorAJFISH <AJFISH@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 4 Oct 2007 21:01:21 +0000 (21:01 +0000)
committerAJFISH <AJFISH@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 4 Oct 2007 21:01:21 +0000 (21:01 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4015 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Include/Guid/VariableInfo.h [new file with mode: 0644]
MdeModulePkg/MdeModulePkg.dec
MdeModulePkg/Universal/Variable/Application/VariableInfo.c [new file with mode: 0644]
MdeModulePkg/Universal/Variable/Application/VariableInfo.inf [new file with mode: 0644]
MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf

diff --git a/MdeModulePkg/Include/Guid/VariableInfo.h b/MdeModulePkg/Include/Guid/VariableInfo.h
new file mode 100644 (file)
index 0000000..d6eb734
--- /dev/null
@@ -0,0 +1,44 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, 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
+\r
+\r
+--*/\r
+\r
+#ifndef __VARIABLE_INFO_GUID_H__\r
+#define __VARIABLE_INFO_GUID_H__\r
+\r
+// {DDCF3616-3275-4164-98B6-FE85707FFE7D}\r
+#define EFI_VARIABLE_INFO_GUID \\r
+  { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d } }\r
+\r
+extern EFI_GUID gEfiVariableInfoGuid;\r
+\r
+\r
+typedef struct _VARIABLE_INFO_ENTRY  VARIABLE_INFO_ENTRY;\r
+\r
+//\r
+// This list gets put in the EFI system table. It is produced by the Variable driver at\r
+// Boot Services time and records read and write access to a given variable\r
+//\r
+struct _VARIABLE_INFO_ENTRY {\r
+  VARIABLE_INFO_ENTRY *Next;\r
+  EFI_GUID            VendorGuid;\r
+  CHAR16              *Name;\r
+  UINT32              Attributes;\r
+  UINT32              ReadCount;\r
+  UINT32              WriteCount;\r
+  UINT32              DeleteCount;\r
+  UINT32              CacheCount;\r
+  BOOLEAN             Volatile;\r
+};\r
+\r
+\r
+#endif\r
index 4ed02e1a864dcf68abff3b033d333c620904df79..851f934c97dffc5956e032f0701dcb700210e292 100644 (file)
   gEfiCapsuleVendorGuid          = { 0x711C703F, 0xC285, 0x4B10, { 0xA3, 0xB0, 0x36, 0xEC, 0xBD, 0x3C, 0x8B, 0xE2 }}\r
   gPeiPerformanceHobGuid         = { 0xEC4DF5AF, 0x4395, 0x4CC9, { 0x94, 0xDE, 0x77, 0x50, 0x6D, 0x12, 0xC7, 0xB8 }}\r
   gEfiGenericPlatformVariableGuid = { 0x59d1c24f, 0x50f1, 0x401a, { 0xb1, 0x01, 0xf3, 0x3e, 0x0d, 0xae, 0xd4, 0x43 }}\r
-\r
   gEfiShellFileGuid              = { 0xC57AD6B7, 0x0515, 0x40A8, { 0x9D, 0x21, 0x55, 0x16, 0x52, 0x85, 0x4E, 0x37 }}\r
   gEfiFlashMapHobGuid            = { 0xB091E7D2, 0x05A0, 0x4198, { 0x94, 0xF0, 0x74, 0xB7, 0xB8, 0xC5, 0x54, 0x59 }}\r
   gEfiStandardErrorDeviceGuid    = { 0xD3B36F2D, 0xD551, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}\r
-\r
   gEfiPeiPeCoffLoaderGuid        = { 0xD8117CFF, 0x94A6, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}\r
+  gEfiVariableInfoGuid           = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}\r
 \r
 [Protocols.common]\r
 \r
   gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText|FALSE|BOOLEAN|0x00010038\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildShareCodeHobs|FALSE|BOOLEAN|0x0001003c\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdNtEmulatorEnable|FALSE|BOOLEAN|0x0001003e\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|FALSE|BOOLEAN|0x0001003f\r
 \r
 [PcdsFixedAtBuild.common]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPcdCallBackNumberPerPcdEntry|0x08|UINT32|0x0001000f\r
diff --git a/MdeModulePkg/Universal/Variable/Application/VariableInfo.c b/MdeModulePkg/Universal/Variable/Application/VariableInfo.c
new file mode 100644 (file)
index 0000000..8986626
--- /dev/null
@@ -0,0 +1,90 @@
+/** @file\r
+  If the Variable services have PcdVariableCollectStatistics set to TRUE then \r
+  the EFI system table will contain statistical information about variable usage\r
+  an this utility will print out the information. You can use console redirection\r
+  to capture the data.\r
+  \r
+  Copyright (c) 2006 - 2007, 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
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiApplicationEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Guid/VariableInfo.h>\r
+\r
+\r
+/**\r
+  The user Entry Point for Application. The user code starts with this function\r
+  as the real entry point for the image goes into a library that calls this \r
+  function.\r
+\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       The entry point is executed successfully.\r
+  @retval other             Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UefiMain (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  VARIABLE_INFO_ENTRY   *VariableInfo;\r
+  VARIABLE_INFO_ENTRY   *Entry;\r
+\r
+  Status = EfiGetSystemConfigurationTable (&gEfiVariableInfoGuid, (VOID **)&Entry);\r
+  if (!EFI_ERROR (Status) && (Entry != NULL)) {\r
+    Print (L"Non-Volatile EFI Variables:\n");\r
+    VariableInfo = Entry;\r
+    do {\r
+      if (!VariableInfo->Volatile) {\r
+        Print (\r
+          L"%g R%03d(%03d) W%03d D%03d:%s\n", \r
+          &VariableInfo->VendorGuid,  \r
+          VariableInfo->ReadCount,\r
+          VariableInfo->CacheCount,\r
+          VariableInfo->WriteCount,\r
+          VariableInfo->DeleteCount,\r
+          VariableInfo->Name\r
+          );\r
+      }\r
+\r
+      VariableInfo = VariableInfo->Next;\r
+    } while (VariableInfo != NULL);\r
+\r
+    Print (L"Volatile EFI Variables:\n");\r
+    VariableInfo = Entry;\r
+    do {\r
+      if (VariableInfo->Volatile) {\r
+        Print (\r
+          L"%g R%03d(%03d) W%03d D%03d:%s\n", \r
+          &VariableInfo->VendorGuid,  \r
+          VariableInfo->ReadCount,\r
+          VariableInfo->CacheCount,\r
+          VariableInfo->WriteCount,\r
+          VariableInfo->DeleteCount,\r
+          VariableInfo->Name\r
+          );\r
+      }\r
+      VariableInfo = VariableInfo->Next;\r
+    } while (VariableInfo != NULL);\r
+\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/MdeModulePkg/Universal/Variable/Application/VariableInfo.inf b/MdeModulePkg/Universal/Variable/Application/VariableInfo.inf
new file mode 100644 (file)
index 0000000..4f4e608
--- /dev/null
@@ -0,0 +1,50 @@
+#/** @file\r
+# Sample UEFI Application Reference Module\r
+#\r
+# This is a shell application that will display Hello World.\r
+# Copyright (c) 2007, Intel Corporation.\r
+#\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
+#  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
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = VariableInfo\r
+  FILE_GUID                      = 202A2922-8C27-4943-9855-26180BF9F113\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = UefiMain\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  VariableInfo.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  UefiApplicationEntryPoint\r
+  UefiLib\r
+  DebugLib\r
+\r
+[Guids]\r
+  gEfiVariableInfoGuid\r
index ef8f72d38a777f1e914f0fdbe53fd524a49b5efe..8627c7dd9da6f32351cf8f750271b351a9fe45ad 100644 (file)
@@ -22,18 +22,23 @@ Revision History
 \r
 #include "Variable.h"\r
 #include <Guid/FlashMapHob.h>\r
+#include <Guid/VariableInfo.h>\r
+#include <Guid/GlobalVariable.h>\r
+\r
+\r
+\r
 \r
 //\r
 // Don't use module globals after the SetVirtualAddress map is signaled\r
 //\r
 ESAL_VARIABLE_GLOBAL  *mVariableModuleGlobal;\r
 \r
+\r
 //\r
 // This is a temperary function which will be removed\r
 // when EfiAcquireLock in UefiLib can handle the\r
 // the call in UEFI Runtimer driver in RT phase.\r
 //\r
-STATIC\r
 VOID\r
 AcquireLockOnlyAtBootTime (\r
   IN EFI_LOCK  *Lock\r
@@ -49,7 +54,6 @@ AcquireLockOnlyAtBootTime (
 // when EfiAcquireLock in UefiLib can handle the\r
 // the call in UEFI Runtimer driver in RT phase.\r
 //\r
-STATIC\r
 VOID\r
 ReleaseLockOnlyAtBootTime (\r
   IN EFI_LOCK  *Lock\r
@@ -60,6 +64,76 @@ ReleaseLockOnlyAtBootTime (
   }\r
 }\r
 \r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED VARIABLE_INFO_ENTRY *gVariableInfo = NULL;\r
+\r
+\r
+VOID\r
+UpdateVariableInfo (\r
+  IN  CHAR16                  *VariableName,\r
+  IN  EFI_GUID                *VendorGuid,\r
+  IN  BOOLEAN                 Volatile,\r
+  IN  BOOLEAN                 Read,\r
+  IN  BOOLEAN                 Write,\r
+  IN  BOOLEAN                 Delete,\r
+  IN  BOOLEAN                 Cache\r
+  )\r
+{\r
+  VARIABLE_INFO_ENTRY   *Entry;\r
+\r
+  if (FeaturePcdGet (PcdVariableCollectStatistics)) {\r
+\r
+    if (EfiAtRuntime ()) {\r
+      // Don't collect statistics at runtime\r
+      return;\r
+    }\r
+\r
+    if (gVariableInfo == NULL) {\r
+      gVariableInfo = AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY));\r
+      CopyGuid (&gVariableInfo->VendorGuid, VendorGuid);\r
+      gVariableInfo->Name = AllocatePool (StrLen (VariableName));\r
+      StrCpy (gVariableInfo->Name, VariableName);\r
+      gVariableInfo->Volatile = Volatile;\r
+\r
+      gBS->InstallConfigurationTable (&gEfiVariableInfoGuid, gVariableInfo);\r
+    }\r
+\r
+    \r
+    for (Entry = gVariableInfo; Entry != NULL; Entry = Entry->Next) {\r
+      if (CompareGuid (VendorGuid, &Entry->VendorGuid)) {\r
+        if (StrCmp (VariableName, Entry->Name) == 0) {\r
+          if (Read) {\r
+            Entry->ReadCount++;\r
+          }\r
+          if (Write) {\r
+            Entry->WriteCount++;\r
+          }\r
+          if (Delete) {\r
+            Entry->DeleteCount++;\r
+          }\r
+          if (Cache) {\r
+            Entry->CacheCount++;\r
+          }\r
+\r
+          return;\r
+        }\r
+      }\r
+\r
+      if (Entry->Next == NULL) {\r
+        Entry->Next = AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY));\r
+\r
+        CopyGuid (&Entry->Next->VendorGuid, VendorGuid);\r
+        Entry->Next->Name = AllocatePool (StrLen (VariableName));\r
+        StrCpy (Entry->Next->Name, VariableName);\r
+        Entry->Next->Volatile = Volatile;\r
+      }\r
+\r
+    }\r
+  }\r
+}\r
+\r
+\r
+\r
 STATIC\r
 BOOLEAN\r
 EFIAPI\r
@@ -485,9 +559,111 @@ Returns:
   return Status;\r
 }\r
 \r
-STATIC\r
+typedef struct {\r
+  EFI_GUID    *Guid;\r
+  CHAR16      *Name;\r
+  UINT32      Attributes;\r
+  UINTN       DataSize;\r
+  VOID        *Data;\r
+} VARIABLE_CACHE_ENTRY;\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
+VOID\r
+UpdateVariableCache (\r
+  IN      CHAR16            *VariableName,\r
+  IN      EFI_GUID          *VendorGuid,\r
+  OUT     UINT32            Attributes,\r
+  IN OUT  UINTN             DataSize,\r
+  OUT     VOID              *Data\r
+  )\r
+{\r
+  VARIABLE_CACHE_ENTRY      *Entry;\r
+  UINTN                     Index;\r
+\r
+  if (EfiAtRuntime ()) {\r
+    // Don't use the cache at runtime\r
+    return;\r
+  }\r
+\r
+  for (Index = 0, Entry = mVariableCache; Index < sizeof (mVariableCache)/sizeof (VARIABLE_CACHE_ENTRY); Index++, Entry++) {\r
+    if (CompareGuid (VendorGuid, Entry->Guid)) {\r
+      if (StrCmp (VariableName, Entry->Name) == 0) { \r
+        Entry->Attributes = Attributes;\r
+        if (DataSize == 0) {\r
+          // Delete Case\r
+          if (Entry->DataSize != 0) {\r
+            FreePool (Entry->Data);\r
+          }\r
+          Entry->DataSize = DataSize;\r
+        } else if (DataSize == Entry->DataSize) {\r
+          CopyMem (Entry->Data, Data, DataSize);\r
+        } else {\r
+          Entry->Data = AllocatePool (DataSize);\r
+          Entry->DataSize = DataSize;\r
+          CopyMem (Entry->Data, Data, DataSize);\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+\r
+EFI_STATUS\r
+FindVariableInCache (\r
+  IN      CHAR16            *VariableName,\r
+  IN      EFI_GUID          *VendorGuid,\r
+  OUT     UINT32            *Attributes OPTIONAL,\r
+  IN OUT  UINTN             *DataSize,\r
+  OUT     VOID              *Data\r
+  )\r
+{\r
+  VARIABLE_CACHE_ENTRY      *Entry;\r
+  UINTN                     Index;\r
+\r
+  if (EfiAtRuntime ()) {\r
+    // Don't use the cache at runtime\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  for (Index = 0, Entry = mVariableCache; Index < sizeof (mVariableCache)/sizeof (VARIABLE_CACHE_ENTRY); Index++, Entry++) {\r
+    if (CompareGuid (VendorGuid, Entry->Guid)) {\r
+      if (StrCmp (VariableName, Entry->Name) == 0) {\r
+        if (Entry->DataSize == 0) {\r
+          return EFI_NOT_FOUND;\r
+        } else if (Entry->DataSize != *DataSize) {\r
+          *DataSize = Entry->DataSize;\r
+          return EFI_BUFFER_TOO_SMALL;\r
+        } else {\r
+          CopyMem (Data, Entry->Data, Entry->DataSize);\r
+          if (Attributes != NULL) {\r
+            *Attributes = Entry->Attributes;\r
+          }\r
+          return EFI_SUCCESS;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  \r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
 EFI_STATUS\r
-EFIAPI\r
 FindVariable (\r
   IN  CHAR16                  *VariableName,\r
   IN  EFI_GUID                *VendorGuid,\r
@@ -527,10 +703,10 @@ Returns:
   AcquireLockOnlyAtBootTime(&Global->VariableServicesLock);\r
 \r
   //\r
-  // 0: Non-Volatile, 1: Volatile\r
+  // 0: Volatile, 1: Non-Volatile\r
   //\r
-  VariableStoreHeader[0]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);\r
-  VariableStoreHeader[1]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);\r
+  VariableStoreHeader[0]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);\r
+  VariableStoreHeader[1]  = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);\r
 \r
   //\r
   // Start Pointers for the variable.\r
@@ -543,7 +719,7 @@ Returns:
     return EFI_INVALID_PARAMETER;\r
   }\r
   //\r
-  // Find the variable by walk through non-volatile and volatile variable store\r
+  // Find the variable by walk through volatile and then non-volatile variable store\r
   //\r
   for (Index = 0; Index < 2; Index++) {\r
     PtrTrack->StartPtr  = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1);\r
@@ -554,13 +730,13 @@ Returns:
         if (!EfiAtRuntime () || (Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {\r
           if (VariableName[0] == 0) {\r
             PtrTrack->CurrPtr   = Variable[Index];\r
-            PtrTrack->Volatile  = (BOOLEAN) Index;\r
+            PtrTrack->Volatile  = (BOOLEAN)(Index == 0);\r
             return EFI_SUCCESS;\r
           } else {\r
             if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {\r
               if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), Variable[Index]->NameSize)) {\r
                 PtrTrack->CurrPtr   = Variable[Index];\r
-                PtrTrack->Volatile  = (BOOLEAN) Index;\r
+                PtrTrack->Volatile  = (BOOLEAN)(Index == 0);\r
                 return EFI_SUCCESS;\r
               }\r
             }\r
@@ -570,17 +746,12 @@ Returns:
 \r
       Variable[Index] = GetNextVariablePtr (Variable[Index]);\r
     }\r
-    //\r
-    // While (...)\r
-    //\r
   }\r
-  //\r
-  // for (...)\r
-  //\r
   PtrTrack->CurrPtr = NULL;\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
+\r
 EFI_STATUS\r
 EFIAPI\r
 GetVariable (\r
@@ -626,14 +797,22 @@ Returns:
   if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   //\r
   // Find existing variable\r
   //\r
+  Status = FindVariableInCache (VariableName, VendorGuid, Attributes, DataSize, Data);\r
+  if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_SUCCESS)){\r
+    // Hit in the Cache\r
+    UpdateVariableInfo (VariableName, VendorGuid, FALSE, TRUE, FALSE, FALSE, TRUE);\r
+    return Status;\r
+  }\r
+  \r
   Status = FindVariable (VariableName, VendorGuid, &Variable, Global);\r
-\r
   if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
     goto Done;\r
   }\r
+\r
   //\r
   // Get data size\r
   //\r
@@ -650,6 +829,9 @@ Returns:
     }\r
 \r
     *DataSize = VarDataSize;\r
+    UpdateVariableInfo (VariableName, VendorGuid, Variable.Volatile, TRUE, FALSE, FALSE, FALSE);\r
+    UpdateVariableCache (VariableName, VendorGuid, Variable.CurrPtr->Attributes, VarDataSize, Data);\r
\r
     Status = EFI_SUCCESS;\r
     goto Done;\r
   } else {\r
@@ -901,6 +1083,10 @@ Returns:
                  sizeof (UINT8),\r
                  &State\r
                  ); \r
+      if (!EFI_ERROR (Status)) {\r
+        UpdateVariableInfo (VariableName, VendorGuid, Variable.Volatile, FALSE, FALSE, TRUE, FALSE);\r
+        UpdateVariableCache (VariableName, VendorGuid, Attributes, DataSize, Data);\r
+      }\r
       goto Done;     \r
     }\r
     //\r
@@ -909,6 +1095,8 @@ Returns:
     //\r
     if (Variable.CurrPtr->DataSize == DataSize &&\r
         (CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize) == 0)) {\r
+      \r
+      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
@@ -930,7 +1118,7 @@ Returns:
                  );      \r
       if (EFI_ERROR (Status)) {\r
         goto Done;  \r
-      }\r
+      } \r
     }    \r
   } else if (Status == EFI_NOT_FOUND) {\r
     //\r
@@ -1010,6 +1198,7 @@ Returns:
     //\r
     // Create a nonvolatile variable\r
     //\r
+    Variable.Volatile = FALSE;\r
     \r
     if ((UINT32) (VarSize +*NonVolatileOffset) >\r
           ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size\r
@@ -1099,6 +1288,7 @@ Returns:
     //\r
     // Create a volatile variable\r
     //      \r
+    Variable.Volatile = TRUE;\r
 \r
     if ((UINT32) (VarSize +*VolatileOffset) >\r
         ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size) {\r
@@ -1155,10 +1345,18 @@ Returns:
                sizeof (UINT8),\r
                &State\r
                );\r
+    \r
+    if (!EFI_ERROR (Status)) {\r
+      UpdateVariableInfo (VariableName, VendorGuid, Variable.Volatile, FALSE, TRUE, FALSE, FALSE);\r
+      UpdateVariableCache (VariableName, VendorGuid, Attributes, DataSize, Data);\r
+    }\r
     goto Done;      \r
   }\r
 \r
   Status = EFI_SUCCESS;\r
+  UpdateVariableInfo (VariableName, VendorGuid, Variable.Volatile, FALSE, TRUE, FALSE, FALSE);\r
+  UpdateVariableCache (VariableName, VendorGuid, Attributes, DataSize, Data);\r
+\r
 Done:\r
   ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);\r
   return Status;\r
index 954f6a20b6870e9146494b4e2a50dee9786a8c04..8c3e1d8c029b8766f0194cb9870e962f8a9d865f 100644 (file)
   gEfiVariableWriteArchProtocolGuid             # PROTOCOL ALWAYS_PRODUCED\r
   gEfiVariableArchProtocolGuid                  # PROTOCOL ALWAYS_PRODUCED\r
 \r
+[Guids]\r
+  gEfiVariableInfoGuid\r
+  gEfiGlobalVariableGuid\r
+\r
 [Pcd.common]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase\r
+  \r
+[FeaturePcd.IA32]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics\r
 \r
 [Depex]\r
   gEfiFirmwareVolumeBlockProtocolGuid AND gEfiAlternateFvBlockGuid AND gEfiFaultTolerantWriteLiteProtocolGuid\r