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
// 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
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
// 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
//\r
Variable = IndexTable->StartPtr;\r
}\r
+\r
+ LastVariable = IndexTable->StartPtr;\r
}\r
//\r
// Find the variable by walk through non-volatile variable store\r
//\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