INTERNAL_VAR_CHECK_FUNCTION CheckFunction;\r
} UEFI_DEFINED_VARIABLE_ENTRY;\r
\r
-typedef struct _EFI_LOAD_OPTION {\r
- UINT32 Attributes;\r
- UINT16 FilePathListLength;\r
-//CHAR16 Description[];\r
-//EFI_DEVICE_PATH_PROTOCOL FilePathList[];\r
-//UINT8 OptionalData[];\r
-} EFI_LOAD_OPTION;\r
-\r
/**\r
Internal check for load option.\r
\r
IN VOID *Data\r
)\r
{\r
- EFI_LOAD_OPTION *LoadOption;\r
+ UINT16 FilePathListLength;\r
CHAR16 *Description;\r
EFI_DEVICE_PATH_PROTOCOL *FilePathList;\r
\r
- LoadOption = (EFI_LOAD_OPTION *) Data;\r
+ FilePathListLength = *((UINT16 *) ((UINTN) Data + sizeof (UINT32)));\r
\r
//\r
// Check Description\r
//\r
- Description = (CHAR16 *) ((UINTN) Data + sizeof (EFI_LOAD_OPTION));\r
+ Description = (CHAR16 *) ((UINTN) Data + sizeof (UINT32) + sizeof (UINT16));\r
while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) {\r
if (*Description == L'\0') {\r
break;\r
// Check FilePathList\r
//\r
FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description;\r
- if ((UINTN) FilePathList > (MAX_ADDRESS - LoadOption->FilePathListLength)) {\r
+ if ((UINTN) FilePathList > (MAX_ADDRESS - FilePathListLength)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- if (((UINTN) FilePathList + LoadOption->FilePathListLength) > ((UINTN) Data + DataSize)) {\r
+ if (((UINTN) FilePathList + FilePathListLength) > ((UINTN) Data + DataSize)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- if (LoadOption->FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
+ if (FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- if (!IsDevicePathValid (FilePathList, LoadOption->FilePathListLength)) {\r
+ if (!IsDevicePathValid (FilePathList, FilePathListLength)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
0,\r
VARIABLE_ATTRIBUTE_NV_BS_RT,\r
- sizeof (EFI_LOAD_OPTION),\r
+ sizeof (UINT32) + sizeof (UINT16),\r
MAX_UINTN\r
},\r
InternalVarCheckLoadOption\r
VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
0,\r
VARIABLE_ATTRIBUTE_NV_BS_RT,\r
- sizeof (EFI_LOAD_OPTION),\r
+ sizeof (UINT32) + sizeof (UINT16),\r
MAX_UINTN\r
},\r
InternalVarCheckLoadOption\r
VARIABLE_ATTRIBUTE_NV_BS,\r
sizeof (UINT8),\r
sizeof (UINT8)\r
- },\r
- NULL\r
+ }\r
},\r
{\r
&gEfiCustomModeEnableGuid,\r
VARIABLE_ATTRIBUTE_NV_BS,\r
sizeof (UINT8),\r
sizeof (UINT8)\r
- },\r
- NULL\r
+ }\r
},\r
{\r
&gEfiVendorKeysNvGuid,\r
VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
sizeof (UINT8),\r
sizeof (UINT8)\r
- },\r
- NULL\r
+ }\r
},\r
{\r
&gEfiAuthenticatedVariableGuid,\r
VARIABLE_ATTRIBUTE_NV_BS_RT_AW,\r
sizeof (UINT8),\r
MAX_UINTN\r
- },\r
- NULL\r
+ }\r
},\r
{\r
&gEfiCertDbGuid,\r
VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
sizeof (UINT32),\r
MAX_UINTN\r
- },\r
- NULL\r
+ }\r
+ },\r
+ {\r
+ &gEdkiiVarErrorFlagGuid,\r
+ VAR_ERROR_FLAG_NAME,\r
+ {\r
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
+ VARIABLE_ATTRIBUTE_NV_BS_RT,\r
+ sizeof (VAR_ERROR_FLAG),\r
+ sizeof (VAR_ERROR_FLAG)\r
+ }\r
},\r
};\r
\r
UINTN Index;\r
UINTN NameLength;\r
\r
- if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)){\r
+ if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {\r
//\r
// Try list 1, exactly match.\r
//\r
*VariableProperty = &mGlobalVariableList2[Index].VariableProperty;\r
return EFI_SUCCESS;\r
}\r
- } else {\r
- if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) {\r
- if (VarCheckFunction != NULL) {\r
- *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;\r
- }\r
- *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;\r
- return EFI_SUCCESS;\r
+ }\r
+ if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) {\r
+ if (VarCheckFunction != NULL) {\r
+ *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;\r
}\r
+ *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;\r
+ return EFI_SUCCESS;\r
}\r
}\r
\r
\r
@param[in] VariableName Pointer to variable name.\r
@param[in] VendorGuid Variable Vendor Guid.\r
- @param[out] VarCheckFunction Pointer to check function.\r
\r
@return Pointer to variable property.\r
\r
VAR_CHECK_VARIABLE_PROPERTY *\r
GetVariableDriverVariableProperty (\r
IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- OUT INTERNAL_VAR_CHECK_FUNCTION *VarCheckFunction OPTIONAL\r
+ IN EFI_GUID *VendorGuid\r
)\r
{\r
UINTN Index;\r
\r
for (Index = 0; Index < sizeof (mVariableDriverVariableList)/sizeof (mVariableDriverVariableList[0]); Index++) {\r
if ((CompareGuid (mVariableDriverVariableList[Index].Guid, VendorGuid)) && (StrCmp (mVariableDriverVariableList[Index].Name, VariableName) == 0)) {\r
- if (VarCheckFunction != NULL) {\r
- *VarCheckFunction = mVariableDriverVariableList[Index].CheckFunction;\r
- }\r
return &mVariableDriverVariableList[Index].VariableProperty;\r
}\r
}\r
}\r
\r
Property = NULL;\r
- Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
- return Status;\r
+ VarCheckFunction = NULL;\r
+\r
+ for ( Link = GetFirstNode (&mVarCheckVariableList)\r
+ ; !IsNull (&mVarCheckVariableList, Link)\r
+ ; Link = GetNextNode (&mVarCheckVariableList, Link)\r
+ ) {\r
+ Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);\r
+ Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
+ if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {\r
+ Property = &Entry->VariableProperty;\r
+ break;\r
+ }\r
}\r
if (Property == NULL) {\r
- Property = GetVariableDriverVariableProperty (VariableName, VendorGuid, &VarCheckFunction);\r
+ Property = GetVariableDriverVariableProperty (VariableName, VendorGuid);\r
}\r
if (Property == NULL) {\r
- VarCheckFunction = NULL;\r
- for ( Link = GetFirstNode (&mVarCheckVariableList)\r
- ; !IsNull (&mVarCheckVariableList, Link)\r
- ; Link = GetNextNode (&mVarCheckVariableList, Link)\r
- ) {\r
- Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);\r
- Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
- if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {\r
- Property = &Entry->VariableProperty;\r
- break;\r
- }\r
+ Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
+ return Status;\r
}\r
}\r
if (Property != NULL) {\r
DEBUG ((EFI_D_INFO, "[Variable]: Var Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName));\r
return EFI_WRITE_PROTECTED;\r
}\r
- if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {\r
+ if (!((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0))) {\r
//\r
- // Do not check delete variable.\r
+ // Not to delete variable.\r
//\r
- return EFI_SUCCESS;\r
- }\r
- if ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes) {\r
- DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (DataSize != 0) {\r
- if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {\r
- DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
+ if ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes) {\r
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property->Attributes, Attributes, EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
return EFI_INVALID_PARAMETER;\r
}\r
- if (VarCheckFunction != NULL) {\r
- Status = VarCheckFunction (\r
- Property,\r
- DataSize,\r
- Data\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
- return Status;\r
+ if (DataSize != 0) {\r
+ if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {\r
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize, Property->MinSize, Property->MaxSize, EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (VarCheckFunction != NULL) {\r
+ Status = VarCheckFunction (\r
+ Property,\r
+ DataSize,\r
+ Data\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_INFO, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
+ return Status;\r
+ }\r
}\r
}\r
}\r
}\r
\r
/**\r
- Internal variable property get.\r
+ Variable property get function.\r
\r
- @param[in] Name Pointer to the variable name.\r
- @param[in] Guid Pointer to the vendor GUID.\r
+ @param[in] Name Pointer to the variable name.\r
+ @param[in] Guid Pointer to the vendor GUID.\r
+ @param[in] WildcardMatch Try wildcard match or not.\r
\r
@return Pointer to the property of variable specified by the Name and Guid.\r
\r
**/\r
VAR_CHECK_VARIABLE_PROPERTY *\r
-InternalVarCheckVariablePropertyGet (\r
- IN CHAR16 *Name,\r
- IN EFI_GUID *Guid\r
+VariablePropertyGetFunction (\r
+ IN CHAR16 *Name,\r
+ IN EFI_GUID *Guid,\r
+ IN BOOLEAN WildcardMatch\r
)\r
{\r
LIST_ENTRY *Link;\r
CHAR16 *VariableName;\r
VAR_CHECK_VARIABLE_PROPERTY *Property;\r
\r
- Property = NULL;\r
- GetUefiDefinedVariableProperty (Name, Guid, FALSE, &Property, NULL);\r
- if (Property == NULL) {\r
- Property = GetVariableDriverVariableProperty (Name, Guid, NULL);\r
- }\r
- if (Property != NULL) {\r
- return Property;\r
- } else {\r
- for ( Link = GetFirstNode (&mVarCheckVariableList)\r
- ; !IsNull (&mVarCheckVariableList, Link)\r
- ; Link = GetNextNode (&mVarCheckVariableList, Link)\r
- ) {\r
- Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);\r
- VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
- if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {\r
- return &Entry->VariableProperty;\r
- }\r
+ for ( Link = GetFirstNode (&mVarCheckVariableList)\r
+ ; !IsNull (&mVarCheckVariableList, Link)\r
+ ; Link = GetNextNode (&mVarCheckVariableList, Link)\r
+ ) {\r
+ Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);\r
+ VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
+ if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {\r
+ return &Entry->VariableProperty;\r
}\r
}\r
\r
- return NULL;\r
+ Property = GetVariableDriverVariableProperty (Name, Guid);\r
+ if (Property == NULL) {\r
+ GetUefiDefinedVariableProperty (Name, Guid, WildcardMatch, &Property, NULL);\r
+ }\r
+\r
+ return Property;\r
}\r
\r
/**\r
\r
AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
- Property = InternalVarCheckVariablePropertyGet (Name, Guid);\r
+ Property = VariablePropertyGetFunction (Name, Guid, FALSE);\r
if (Property != NULL) {\r
CopyMem (Property, VariableProperty, sizeof (*VariableProperty));\r
} else {\r
}\r
\r
/**\r
- Variable property get.\r
+ Internal variable property get.\r
\r
@param[in] Name Pointer to the variable name.\r
@param[in] Guid Pointer to the vendor GUID.\r
@param[out] VariableProperty Pointer to the output variable property.\r
\r
@retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.\r
- @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.\r
@retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-VarCheckVariablePropertyGet (\r
+InternalVarCheckVariablePropertyGet (\r
IN CHAR16 *Name,\r
IN EFI_GUID *Guid,\r
OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty\r
BOOLEAN Found;\r
VAR_CHECK_VARIABLE_PROPERTY *Property;\r
\r
- if (Name == NULL || Name[0] == 0 || Guid == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (VariableProperty == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
Found = FALSE;\r
\r
- AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
-\r
- Property = InternalVarCheckVariablePropertyGet (Name, Guid);\r
+ Property = VariablePropertyGetFunction (Name, Guid, TRUE);\r
if (Property != NULL) {\r
CopyMem (VariableProperty, Property, sizeof (*VariableProperty));\r
Found = TRUE;\r
}\r
}\r
\r
+ return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);\r
+}\r
+\r
+/**\r
+ Variable property get.\r
+\r
+ @param[in] Name Pointer to the variable name.\r
+ @param[in] Guid Pointer to the vendor GUID.\r
+ @param[out] VariableProperty Pointer to the output variable property.\r
+\r
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.\r
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.\r
+ @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VarCheckVariablePropertyGet (\r
+ IN CHAR16 *Name,\r
+ IN EFI_GUID *Guid,\r
+ OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if (Name == NULL || Name[0] == 0 || Guid == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (VariableProperty == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
+ Status = InternalVarCheckVariablePropertyGet (Name, Guid, VariableProperty);\r
+\r
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
- return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);\r
+ return Status;\r
}\r
\r
return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);\r
}\r
\r
+/**\r
+ Record variable error flag.\r
+\r
+ @param[in] Flag Variable error flag to record.\r
+ @param[in] VariableName Name of variable.\r
+ @param[in] VendorGuid Guid of variable.\r
+ @param[in] Attributes Attributes of the variable.\r
+ @param[in] VariableSize Size of the variable.\r
+\r
+**/\r
+VOID\r
+RecordVarErrorFlag (\r
+ IN VAR_ERROR_FLAG Flag,\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN UINT32 Attributes,\r
+ IN UINTN VariableSize\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VARIABLE_POINTER_TRACK Variable;\r
+ VAR_ERROR_FLAG *VarErrFlag;\r
+ VAR_ERROR_FLAG TempFlag;\r
+\r
+ DEBUG_CODE (\r
+ DEBUG ((EFI_D_ERROR, "RecordVarErrorFlag (0x%02x) %s:%g - 0x%08x - 0x%x\n", Flag, VariableName, VendorGuid, Attributes, VariableSize));\r
+ if (Flag == VAR_ERROR_FLAG_SYSTEM_ERROR) {\r
+ if (AtRuntime ()) {\r
+ DEBUG ((EFI_D_ERROR, "CommonRuntimeVariableSpace = 0x%x - CommonVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonRuntimeVariableSpace, mVariableModuleGlobal->CommonVariableTotalSize));\r
+ } else {\r
+ DEBUG ((EFI_D_ERROR, "CommonVariableSpace = 0x%x - CommonVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonVariableSpace, mVariableModuleGlobal->CommonVariableTotalSize));\r
+ }\r
+ } else {\r
+ DEBUG ((EFI_D_ERROR, "CommonMaxUserVariableSpace = 0x%x - CommonUserVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonMaxUserVariableSpace, mVariableModuleGlobal->CommonUserVariableTotalSize));\r
+ }\r
+ );\r
+\r
+ //\r
+ // Record error flag (it should have be initialized).\r
+ //\r
+ Status = FindVariable (\r
+ VAR_ERROR_FLAG_NAME,\r
+ &gEdkiiVarErrorFlagGuid,\r
+ &Variable,\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ VarErrFlag = (VAR_ERROR_FLAG *) GetVariableDataPtr (Variable.CurrPtr);\r
+ TempFlag = *VarErrFlag;\r
+ TempFlag &= Flag;\r
+ if (TempFlag == *VarErrFlag) {\r
+ return;\r
+ }\r
+ Status = UpdateVariableStore (\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE,\r
+ FALSE,\r
+ mVariableModuleGlobal->FvbInstance,\r
+ (UINTN) VarErrFlag - (UINTN) mNvVariableCache + (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,\r
+ sizeof (TempFlag),\r
+ &TempFlag\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Update the data in NV cache.\r
+ //\r
+ *VarErrFlag = Flag;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Initialize variable error flag.\r
+\r
+ Before EndOfDxe, the variable indicates the last boot variable error flag,\r
+ then it means the last boot variable error flag must be got before EndOfDxe.\r
+ After EndOfDxe, the variable indicates the current boot variable error flag,\r
+ then it means the current boot variable error flag must be got after EndOfDxe.\r
+\r
+**/\r
+VOID\r
+InitializeVarErrorFlag (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VARIABLE_POINTER_TRACK Variable;\r
+ VAR_ERROR_FLAG Flag;\r
+ VAR_ERROR_FLAG VarErrFlag;\r
+\r
+ if (!mEndOfDxe) {\r
+ return;\r
+ }\r
+\r
+ Flag = VAR_ERROR_FLAG_NO_ERROR;\r
+ DEBUG ((EFI_D_INFO, "Initialize variable error flag (%02x)\n", Flag));\r
+\r
+ Status = FindVariable (\r
+ VAR_ERROR_FLAG_NAME,\r
+ &gEdkiiVarErrorFlagGuid,\r
+ &Variable,\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ FALSE\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ VarErrFlag = *((VAR_ERROR_FLAG *) GetVariableDataPtr (Variable.CurrPtr));\r
+ if (VarErrFlag == Flag) {\r
+ return;\r
+ }\r
+ }\r
+\r
+ UpdateVariable (\r
+ VAR_ERROR_FLAG_NAME,\r
+ &gEdkiiVarErrorFlagGuid,\r
+ &Flag,\r
+ sizeof (Flag),\r
+ VARIABLE_ATTRIBUTE_NV_BS_RT,\r
+ 0,\r
+ 0,\r
+ &Variable,\r
+ NULL\r
+ );\r
+}\r
+\r
+/**\r
+ Is user variable?\r
+\r
+ @param[in] Variable Pointer to variable header.\r
+\r
+ @retval TRUE User variable.\r
+ @retval FALSE System variable.\r
+\r
+**/\r
+BOOLEAN\r
+IsUserVariable (\r
+ IN VARIABLE_HEADER *Variable\r
+ )\r
+{\r
+ VAR_CHECK_VARIABLE_PROPERTY Property;\r
+\r
+ //\r
+ // Only after End Of Dxe, the variables belong to system variable are fixed.\r
+ // If PcdMaxUserNvStorageVariableSize is 0, it means user variable share the same NV storage with system variable,\r
+ // then no need to check if the variable is user variable or not specially.\r
+ //\r
+ if (mEndOfDxe && (mVariableModuleGlobal->CommonMaxUserVariableSpace != mVariableModuleGlobal->CommonVariableSpace)) {\r
+ if (InternalVarCheckVariablePropertyGet (GetVariableNamePtr (Variable), &Variable->VendorGuid, &Property) == EFI_NOT_FOUND) {\r
+ return TRUE;\r
+ }\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Calculate common user variable total size.\r
+\r
+**/\r
+VOID\r
+CalculateCommonUserVariableTotalSize (\r
+ VOID\r
+ )\r
+{\r
+ VARIABLE_HEADER *Variable;\r
+ VARIABLE_HEADER *NextVariable;\r
+ UINTN VariableSize;\r
+ VAR_CHECK_VARIABLE_PROPERTY Property;\r
+\r
+ //\r
+ // Only after End Of Dxe, the variables belong to system variable are fixed.\r
+ // If PcdMaxUserNvStorageVariableSize is 0, it means user variable share the same NV storage with system variable,\r
+ // then no need to calculate the common user variable total size specially.\r
+ //\r
+ if (mEndOfDxe && (mVariableModuleGlobal->CommonMaxUserVariableSpace != mVariableModuleGlobal->CommonVariableSpace)) {\r
+ Variable = GetStartPointer (mNvVariableCache);\r
+ while (IsValidVariableHeader (Variable, GetEndPointer (mNvVariableCache))) {\r
+ NextVariable = GetNextVariablePtr (Variable);\r
+ VariableSize = (UINTN) NextVariable - (UINTN) Variable;\r
+ if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
+ if (InternalVarCheckVariablePropertyGet (GetVariableNamePtr (Variable), &Variable->VendorGuid, &Property) == EFI_NOT_FOUND) {\r
+ //\r
+ // No property, it is user variable.\r
+ //\r
+ mVariableModuleGlobal->CommonUserVariableTotalSize += VariableSize;\r
+ }\r
+ }\r
+\r
+ Variable = NextVariable;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Initialize variable quota.\r
+\r
+**/\r
+VOID\r
+InitializeVariableQuota (\r
+ VOID\r
+ )\r
+{\r
+ STATIC BOOLEAN Initialized;\r
+\r
+ if (!mEndOfDxe || Initialized) {\r
+ return;\r
+ }\r
+ Initialized = TRUE;\r
+\r
+ InitializeVarErrorFlag ();\r
+ CalculateCommonUserVariableTotalSize ();\r
+}\r
+\r
/**\r
\r
Check the PubKeyIndex is a valid key or not.\r
BOOLEAN FoundAdded;\r
EFI_STATUS Status;\r
UINTN CommonVariableTotalSize;\r
+ UINTN CommonUserVariableTotalSize;\r
UINTN HwErrVariableTotalSize;\r
UINT32 *NewPubKeyIndex;\r
UINT8 *NewPubKeyStore;\r
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);\r
\r
CommonVariableTotalSize = 0;\r
+ CommonUserVariableTotalSize = 0;\r
HwErrVariableTotalSize = 0;\r
NewPubKeyIndex = NULL;\r
NewPubKeyStore = NULL;\r
HwErrVariableTotalSize += VariableSize;\r
} else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
CommonVariableTotalSize += VariableSize;\r
+ if (IsUserVariable (Variable)) {\r
+ CommonUserVariableTotalSize += VariableSize;\r
}\r
}\r
+ }\r
Variable = NextVariable;\r
}\r
\r
CopyMem (GetVariableDataPtr (Variable), NewPubKeyStore, NewPubKeySize);\r
CurrPtr = (UINT8*) GetNextVariablePtr (Variable);\r
CommonVariableTotalSize += (UINTN) CurrPtr - (UINTN) Variable;\r
+ if (IsUserVariable (Variable)) {\r
+ CommonUserVariableTotalSize += (UINTN) CurrPtr - (UINTN) Variable;\r
+ }\r
} else {\r
//\r
// Reinstall all ADDED variables as long as they are not identical to Updating Variable.\r
HwErrVariableTotalSize += VariableSize;\r
} else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
CommonVariableTotalSize += VariableSize;\r
+ if (IsUserVariable (Variable)) {\r
+ CommonUserVariableTotalSize += VariableSize;\r
}\r
}\r
+ }\r
Variable = NextVariable;\r
}\r
\r
HwErrVariableTotalSize += VariableSize;\r
} else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
CommonVariableTotalSize += VariableSize;\r
+ if (IsUserVariable (Variable)) {\r
+ CommonUserVariableTotalSize += VariableSize;\r
}\r
}\r
}\r
+ }\r
\r
Variable = NextVariable;\r
}\r
HwErrVariableTotalSize += NewVariableSize;\r
} else if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
CommonVariableTotalSize += NewVariableSize;\r
+ if (IsUserVariable (NewVariable)) {\r
+ CommonUserVariableTotalSize += NewVariableSize;\r
}\r
+ }\r
if ((HwErrVariableTotalSize > PcdGet32 (PcdHwErrStorageSize)) ||\r
- (CommonVariableTotalSize > VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize))) {\r
+ (CommonVariableTotalSize > mVariableModuleGlobal->CommonVariableSpace) ||\r
+ (CommonUserVariableTotalSize > mVariableModuleGlobal->CommonMaxUserVariableSpace)) {\r
//\r
// No enough space to store the new variable by NV or NV+HR attribute.\r
//\r
*LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);\r
mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize;\r
mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize;\r
+ mVariableModuleGlobal->CommonUserVariableTotalSize = CommonUserVariableTotalSize;\r
} else {\r
- NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase);\r
- while (IsValidVariableHeader (NextVariable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase))) {\r
- VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);\r
+ Variable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase);\r
+ while (IsValidVariableHeader (Variable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase))) {\r
+ NextVariable = GetNextVariablePtr (Variable);\r
+ VariableSize = (UINTN) NextVariable - (UINTN) Variable;\r
if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
- mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);\r
+ mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize;\r
} else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
- mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);\r
+ mVariableModuleGlobal->CommonVariableTotalSize += VariableSize;\r
+ if (IsUserVariable (Variable)) {\r
+ mVariableModuleGlobal->CommonUserVariableTotalSize += VariableSize;\r
}\r
+ }\r
\r
- NextVariable = GetNextVariablePtr (NextVariable);\r
+ Variable = NextVariable;\r
}\r
- *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase;\r
+ *LastVariableOffset = (UINTN) Variable - (UINTN) VariableBase;\r
}\r
}\r
\r
VARIABLE_HEADER *NextVariable;\r
UINTN ScratchSize;\r
UINTN MaxDataSize;\r
- UINTN NonVolatileVarableStoreSize;\r
UINTN VarNameOffset;\r
UINTN VarDataOffset;\r
UINTN VarNameSize;\r
UINTN MergedBufSize;\r
BOOLEAN DataReady;\r
UINTN DataOffset;\r
+ BOOLEAN IsCommonVariable;\r
+ BOOLEAN IsCommonUserVariable;\r
\r
if (mVariableModuleGlobal->FvbInstance == NULL) {\r
//\r
// Create a nonvolatile variable.\r
//\r
Volatile = FALSE;\r
- NonVolatileVarableStoreSize = ((VARIABLE_STORE_HEADER *)(UINTN)(mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase))->Size;\r
+\r
+ IsCommonVariable = FALSE;\r
+ IsCommonUserVariable = FALSE;\r
+ if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) {\r
+ IsCommonVariable = TRUE;\r
+ IsCommonUserVariable = IsUserVariable (NextVariable);\r
+ }\r
if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0)\r
&& ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))\r
- || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0)\r
- && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) {\r
+ || (IsCommonVariable && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonVariableSpace))\r
+ || (IsCommonVariable && AtRuntime () && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonRuntimeVariableSpace))\r
+ || (IsCommonUserVariable && ((VarSize + mVariableModuleGlobal->CommonUserVariableTotalSize) > mVariableModuleGlobal->CommonMaxUserVariableSpace))) {\r
if (AtRuntime ()) {\r
+ if (IsCommonUserVariable && ((VarSize + mVariableModuleGlobal->CommonUserVariableTotalSize) > mVariableModuleGlobal->CommonMaxUserVariableSpace)) {\r
+ RecordVarErrorFlag (VAR_ERROR_FLAG_USER_ERROR, VariableName, VendorGuid, Attributes, VarSize);\r
+ }\r
+ if (IsCommonVariable && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonRuntimeVariableSpace)) {\r
+ RecordVarErrorFlag (VAR_ERROR_FLAG_SYSTEM_ERROR, VariableName, VendorGuid, Attributes, VarSize);\r
+ }\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
}\r
UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, FALSE, FALSE);\r
FlushHobVariableToFlash (VariableName, VendorGuid);\r
+ } else {\r
+ if (IsCommonUserVariable && ((VarSize + mVariableModuleGlobal->CommonUserVariableTotalSize) > mVariableModuleGlobal->CommonMaxUserVariableSpace)) {\r
+ RecordVarErrorFlag (VAR_ERROR_FLAG_USER_ERROR, VariableName, VendorGuid, Attributes, VarSize);\r
}\r
+ if (IsCommonVariable && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonVariableSpace)) {\r
+ RecordVarErrorFlag (VAR_ERROR_FLAG_SYSTEM_ERROR, VariableName, VendorGuid, Attributes, VarSize);\r
+ }\r
+ }\r
goto Done;\r
}\r
//\r
mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VarSize);\r
} else {\r
mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VarSize);\r
+ if (IsCommonUserVariable) {\r
+ mVariableModuleGlobal->CommonUserVariableTotalSize += HEADER_ALIGN (VarSize);\r
}\r
+ }\r
//\r
// update the memory copy of Flash region.\r
//\r
// 2. The only attribute differing is EFI_VARIABLE_APPEND_WRITE\r
//\r
Status = EFI_INVALID_PARAMETER;\r
- DEBUG ((EFI_D_INFO, "[Variable]: Rewritten a preexisting variable with different attributes - %g:%s\n", VendorGuid, VariableName));\r
+ DEBUG ((EFI_D_INFO, "[Variable]: Rewritten a preexisting variable(0x%08x) with different attributes(0x%08x) - %g:%s\n", Variable.CurrPtr->Attributes, Attributes, VendorGuid, VariableName));\r
goto Done;\r
}\r
}\r
*MaximumVariableSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER);\r
} else {\r
if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
- ASSERT (PcdGet32 (PcdHwErrStorageSize) < VariableStoreHeader->Size);\r
- *MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize);\r
+ if (AtRuntime ()) {\r
+ *MaximumVariableStorageSize = mVariableModuleGlobal->CommonRuntimeVariableSpace;\r
+ } else {\r
+ *MaximumVariableStorageSize = mVariableModuleGlobal->CommonVariableSpace;\r
+ }\r
}\r
\r
//\r
\r
if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD){\r
*RemainingVariableStorageSize = *MaximumVariableStorageSize - HwErrVariableTotalSize;\r
- }else {\r
- *RemainingVariableStorageSize = *MaximumVariableStorageSize - CommonVariableTotalSize;\r
+ } else {\r
+ if (*MaximumVariableStorageSize < CommonVariableTotalSize) {\r
+ *RemainingVariableStorageSize = 0;\r
+ } else {\r
+ *RemainingVariableStorageSize = *MaximumVariableStorageSize - CommonVariableTotalSize;\r
+ }\r
}\r
\r
if (*RemainingVariableStorageSize < sizeof (VARIABLE_HEADER)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {\r
+ if ((Attributes & VARIABLE_ATTRIBUTE_NV_BS_RT_AT_HR_AW) == 0) {\r
//\r
// Make sure the Attributes combination is supported by the platform.\r
//\r
)\r
{\r
EFI_STATUS Status;\r
- UINTN CommonVariableSpace;\r
- UINTN RemainingCommonVariableSpace;\r
+ UINTN RemainingCommonRuntimeVariableSpace;\r
UINTN RemainingHwErrVariableSpace;\r
\r
Status = EFI_SUCCESS;\r
\r
- CommonVariableSpace = ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase)))->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32(PcdHwErrStorageSize); //Allowable max size of common variable storage space\r
-\r
- RemainingCommonVariableSpace = CommonVariableSpace - mVariableModuleGlobal->CommonVariableTotalSize;\r
+ if (mVariableModuleGlobal->CommonRuntimeVariableSpace < mVariableModuleGlobal->CommonVariableTotalSize) {\r
+ RemainingCommonRuntimeVariableSpace = 0;\r
+ } else {\r
+ RemainingCommonRuntimeVariableSpace = mVariableModuleGlobal->CommonRuntimeVariableSpace - mVariableModuleGlobal->CommonVariableTotalSize;\r
+ }\r
\r
RemainingHwErrVariableSpace = PcdGet32 (PcdHwErrStorageSize) - mVariableModuleGlobal->HwErrVariableTotalSize;\r
//\r
- // Check if the free area is blow a threshold.\r
+ // Check if the free area is below a threshold.\r
//\r
- if ((RemainingCommonVariableSpace < PcdGet32 (PcdMaxVariableSize))\r
+ if ((RemainingCommonRuntimeVariableSpace < PcdGet32 (PcdMaxVariableSize))\r
|| ((PcdGet32 (PcdHwErrStorageSize) != 0) &&\r
(RemainingHwErrVariableSpace < PcdGet32 (PcdMaxHardwareErrorVariableSize)))){\r
Status = Reclaim (\r
)\r
{\r
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
+ VARIABLE_HEADER *Variable;\r
VARIABLE_HEADER *NextVariable;\r
EFI_PHYSICAL_ADDRESS VariableStoreBase;\r
UINT64 VariableStoreLength;\r
FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *FtwLastWriteData;\r
UINT32 BackUpOffset;\r
UINT32 BackUpSize;\r
+ UINT32 HwErrStorageSize;\r
+ UINT32 MaxUserNvVariableSpaceSize;\r
+ UINT32 BoottimeReservedNvVariableSpaceSize;\r
\r
mVariableModuleGlobal->FvbInstance = NULL;\r
\r
- //\r
- // Note that in EdkII variable driver implementation, Hardware Error Record type variable\r
- // is stored with common variable in the same NV region. So the platform integrator should\r
- // ensure that the value of PcdHwErrStorageSize is less than or equal to the value of\r
- // PcdFlashNvStorageVariableSize.\r
- //\r
- ASSERT (PcdGet32 (PcdHwErrStorageSize) <= PcdGet32 (PcdFlashNvStorageVariableSize));\r
-\r
//\r
// Allocate runtime memory used for a memory copy of the FLASH region.\r
// Keep the memory and the FLASH in sync as updates occur.\r
}\r
ASSERT(mNvVariableCache->Size == VariableStoreLength);\r
\r
+\r
+ ASSERT (sizeof (VARIABLE_STORE_HEADER) <= VariableStoreLength);\r
+\r
+ HwErrStorageSize = PcdGet32 (PcdHwErrStorageSize);\r
+ MaxUserNvVariableSpaceSize = PcdGet32 (PcdMaxUserNvVariableSpaceSize);\r
+ BoottimeReservedNvVariableSpaceSize = PcdGet32 (PcdBoottimeReservedNvVariableSpaceSize);\r
+\r
+ //\r
+ // Note that in EdkII variable driver implementation, Hardware Error Record type variable\r
+ // is stored with common variable in the same NV region. So the platform integrator should\r
+ // ensure that the value of PcdHwErrStorageSize is less than the value of\r
+ // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)).\r
+ //\r
+ ASSERT (HwErrStorageSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)));\r
+ //\r
+ // Ensure that the value of PcdMaxUserNvVariableSpaceSize is less than the value of\r
+ // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize).\r
+ //\r
+ ASSERT (MaxUserNvVariableSpaceSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize));\r
+ //\r
+ // Ensure that the value of PcdBoottimeReservedNvVariableSpaceSize is less than the value of\r
+ // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize).\r
+ //\r
+ ASSERT (BoottimeReservedNvVariableSpaceSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize));\r
+\r
+ mVariableModuleGlobal->CommonVariableSpace = ((UINTN) VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize);\r
+ mVariableModuleGlobal->CommonMaxUserVariableSpace = ((MaxUserNvVariableSpaceSize != 0) ? MaxUserNvVariableSpaceSize : mVariableModuleGlobal->CommonVariableSpace);\r
+ mVariableModuleGlobal->CommonRuntimeVariableSpace = mVariableModuleGlobal->CommonVariableSpace - BoottimeReservedNvVariableSpaceSize;\r
+\r
+ DEBUG ((EFI_D_INFO, "Variable driver common space: 0x%x 0x%x 0x%x\n", mVariableModuleGlobal->CommonVariableSpace, mVariableModuleGlobal->CommonMaxUserVariableSpace, mVariableModuleGlobal->CommonRuntimeVariableSpace));\r
+\r
//\r
// The max variable or hardware error variable size should be < variable store size.\r
//\r
//\r
// Parse non-volatile variable data and get last variable offset.\r
//\r
- NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase);\r
- while (IsValidVariableHeader (NextVariable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase))) {\r
- VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);\r
- if ((NextVariable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
- mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);\r
+ Variable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase);\r
+ while (IsValidVariableHeader (Variable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase))) {\r
+ NextVariable = GetNextVariablePtr (Variable);\r
+ VariableSize = (UINTN) NextVariable - (UINTN) Variable;\r
+ if ((Variable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
+ mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize;\r
} else {\r
- mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);\r
+ mVariableModuleGlobal->CommonVariableTotalSize += VariableSize;\r
}\r
\r
- NextVariable = GetNextVariablePtr (NextVariable);\r
+ Variable = NextVariable;\r
}\r
- mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) VariableStoreBase;\r
+ mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) Variable - (UINTN) VariableStoreBase;\r
\r
return EFI_SUCCESS;\r
}\r