]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/Pei/Variable.c
refine VariablePei driver to unify the algorithm of access VariableIndexTable among...
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / Pei / Variable.c
index 39998f5f67126757babbbe4fa9d52d6b6850db99..4716eac9ec86746ca8b9d64887c197ab9fe78793 100644 (file)
@@ -366,10 +366,13 @@ FindVariable (
   EFI_HOB_GUID_TYPE       *GuidHob;\r
   VARIABLE_STORE_HEADER   *VariableStoreHeader;\r
   VARIABLE_HEADER         *Variable;\r
+  VARIABLE_HEADER         *LastVariable;\r
   VARIABLE_HEADER         *MaxIndex;\r
   VARIABLE_INDEX_TABLE    *IndexTable;\r
   UINT32                  Count;\r
+  UINT32                  Offset;\r
   UINT8                   *VariableBase;\r
+  BOOLEAN                 StopRecord;\r
 \r
   if (VariableName[0] != 0 && VendorGuid == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -378,9 +381,16 @@ FindVariable (
   // No Variable Address equals zero, so 0 as initial value is safe.\r
   //\r
   MaxIndex = 0;\r
+  StopRecord = FALSE;\r
 \r
   GuidHob = GetFirstGuidHob (&mEfiVariableIndexTableGuid);\r
   if (GuidHob == NULL) {\r
+    //\r
+    // If it's the first time to access variable region in flash, create a guid hob to record\r
+    // VAR_ADDED type variable info.\r
+    // Note that as the resource of PEI phase is limited, only store the number of \r
+    // VARIABLE_INDEX_TABLE_VOLUME of VAR_ADDED type variables to reduce access time.\r
+    //\r
     IndexTable = BuildGuidHob (&mEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));\r
     IndexTable->Length      = 0;\r
     IndexTable->StartPtr    = NULL;\r
@@ -388,9 +398,13 @@ FindVariable (
     IndexTable->GoneThrough = 0;\r
   } else {\r
     IndexTable = GET_GUID_HOB_DATA (GuidHob);\r
-    for (Count = 0; Count < IndexTable->Length; Count++) {\r
-      MaxIndex = GetVariableByIndex (IndexTable, Count);\r
-\r
+    for (Offset = 0, Count = 0; Count < IndexTable->Length; Count++) {\r
+      //\r
+      // traverse the variable info list to look for varible.\r
+      // The IndexTable->Index[Count] records the distance of two neighbouring VAR_ADDED type variables.\r
+      //\r
+      Offset   += IndexTable->Index[Count];\r
+      MaxIndex  = (VARIABLE_HEADER *)((CHAR8 *)(IndexTable->StartPtr) + Offset);\r
       if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r
         PtrTrack->StartPtr  = IndexTable->StartPtr;\r
         PtrTrack->EndPtr    = IndexTable->EndPtr;\r
@@ -407,7 +421,8 @@ FindVariable (
   // If not found in HOB, then let's start from the MaxIndex we've found.\r
   //\r
   if (MaxIndex != NULL) {\r
-    Variable = GetNextVariablePtr (MaxIndex);\r
+    Variable     = GetNextVariablePtr (MaxIndex);\r
+    LastVariable = MaxIndex;\r
   } else {\r
     if ((IndexTable->StartPtr != NULL) || (IndexTable->EndPtr != NULL)) {\r
       Variable = IndexTable->StartPtr;\r
@@ -435,6 +450,8 @@ FindVariable (
       //\r
       Variable = IndexTable->StartPtr;\r
     }\r
+\r
+    LastVariable = IndexTable->StartPtr;\r
   }\r
   //\r
   // Find the variable by walk through non-volatile variable store\r
@@ -447,8 +464,23 @@ FindVariable (
       //\r
       // Record Variable in VariableIndex HOB\r
       //\r
-      VariableIndexTableUpdate (IndexTable, Variable);\r
-      \r
+      if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME && StopRecord != TRUE) {\r
+        Offset = (UINT32)((UINTN)Variable - (UINTN)LastVariable);\r
+        //\r
+        // The distance of two neighbouring VAR_ADDED variable is larger than 2^16, \r
+        // which is beyond the allowable scope(UINT16) of record. In such case, need not to\r
+        // record the subsequent VAR_ADDED type variables again.\r
+        //\r
+        if ((Offset & 0xFFFF0000UL) != 0) {\r
+          StopRecord = TRUE;\r
+        }\r
+\r
+        if (StopRecord != TRUE) {\r
+          IndexTable->Index[IndexTable->Length++] = (UINT16) Offset;\r
+        }\r
+        LastVariable = Variable;\r
+      }\r
+\r
       if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r
         return EFI_SUCCESS;\r
       }\r