mirror of https://github.com/acidanthera/audk.git
1. Don't assume that flush the HOB variable to flash must be successful.
2. When no DELETED variable found, no variable space could be reclaimed, so just give some debug info and return EFI_SUCCESS. Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14029 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
9690325d1e
commit
335e268133
|
@ -505,6 +505,7 @@ GetEndPointer (
|
||||||
@param IsVolatile The variable store is volatile or not;
|
@param IsVolatile The variable store is volatile or not;
|
||||||
if it is non-volatile, need FTW.
|
if it is non-volatile, need FTW.
|
||||||
@param UpdatingVariable Pointer to updating variable.
|
@param UpdatingVariable Pointer to updating variable.
|
||||||
|
@param ReclaimAnyway If TRUE, do reclaim anyway.
|
||||||
|
|
||||||
@return EFI_OUT_OF_RESOURCES
|
@return EFI_OUT_OF_RESOURCES
|
||||||
@return EFI_SUCCESS
|
@return EFI_SUCCESS
|
||||||
|
@ -516,7 +517,8 @@ Reclaim (
|
||||||
IN EFI_PHYSICAL_ADDRESS VariableBase,
|
IN EFI_PHYSICAL_ADDRESS VariableBase,
|
||||||
OUT UINTN *LastVariableOffset,
|
OUT UINTN *LastVariableOffset,
|
||||||
IN BOOLEAN IsVolatile,
|
IN BOOLEAN IsVolatile,
|
||||||
IN VARIABLE_HEADER *UpdatingVariable
|
IN VARIABLE_HEADER *UpdatingVariable,
|
||||||
|
IN BOOLEAN ReclaimAnyway
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
VARIABLE_HEADER *Variable;
|
VARIABLE_HEADER *Variable;
|
||||||
|
@ -539,7 +541,9 @@ Reclaim (
|
||||||
CHAR16 *UpdatingVariableNamePtr;
|
CHAR16 *UpdatingVariableNamePtr;
|
||||||
UINTN CommonVariableTotalSize;
|
UINTN CommonVariableTotalSize;
|
||||||
UINTN HwErrVariableTotalSize;
|
UINTN HwErrVariableTotalSize;
|
||||||
|
BOOLEAN NeedDoReclaim;
|
||||||
|
|
||||||
|
NeedDoReclaim = FALSE;
|
||||||
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
|
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
|
||||||
|
|
||||||
CommonVariableTotalSize = 0;
|
CommonVariableTotalSize = 0;
|
||||||
|
@ -558,11 +562,18 @@ Reclaim (
|
||||||
) {
|
) {
|
||||||
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
|
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
|
||||||
MaximumBufferSize += VariableSize;
|
MaximumBufferSize += VariableSize;
|
||||||
|
} else {
|
||||||
|
NeedDoReclaim = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable = NextVariable;
|
Variable = NextVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ReclaimAnyway && !NeedDoReclaim) {
|
||||||
|
DEBUG ((EFI_D_INFO, "Variable driver: no DELETED variable found, so no variable space could be reclaimed.\n"));
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reserve the 1 Bytes with Oxff to identify the
|
// Reserve the 1 Bytes with Oxff to identify the
|
||||||
// end of the variable buffer.
|
// end of the variable buffer.
|
||||||
|
@ -1468,6 +1479,7 @@ UpdateVariable (
|
||||||
UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, FALSE, TRUE, FALSE);
|
UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, FALSE, TRUE, FALSE);
|
||||||
if (!Variable->Volatile) {
|
if (!Variable->Volatile) {
|
||||||
CacheVariable->CurrPtr->State = State;
|
CacheVariable->CurrPtr->State = State;
|
||||||
|
FlushHobVariableToFlash (VariableName, VendorGuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto Done;
|
goto Done;
|
||||||
|
@ -1595,7 +1607,7 @@ UpdateVariable (
|
||||||
// Perform garbage collection & reclaim operation.
|
// Perform garbage collection & reclaim operation.
|
||||||
//
|
//
|
||||||
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
||||||
&mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr);
|
&mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr, FALSE);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
@ -1710,7 +1722,7 @@ UpdateVariable (
|
||||||
// Perform garbage collection & reclaim operation.
|
// Perform garbage collection & reclaim operation.
|
||||||
//
|
//
|
||||||
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,
|
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,
|
||||||
&mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr);
|
&mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr, FALSE);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
@ -1767,6 +1779,9 @@ UpdateVariable (
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE, FALSE, FALSE);
|
UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE, FALSE, FALSE);
|
||||||
|
if (!Volatile) {
|
||||||
|
FlushHobVariableToFlash (VariableName, VendorGuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Done:
|
Done:
|
||||||
|
@ -2383,12 +2398,102 @@ ReclaimForOS(
|
||||||
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
||||||
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL
|
NULL,
|
||||||
|
FALSE
|
||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flush the HOB variable to flash.
|
||||||
|
|
||||||
|
@param[in] VariableName Name of variable has been updated or deleted.
|
||||||
|
@param[in] VendorGuid Guid of variable has been updated or deleted.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
FlushHobVariableToFlash (
|
||||||
|
IN CHAR16 *VariableName,
|
||||||
|
IN EFI_GUID *VendorGuid
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
VARIABLE_STORE_HEADER *VariableStoreHeader;
|
||||||
|
VARIABLE_HEADER *Variable;
|
||||||
|
VOID *VariableData;
|
||||||
|
BOOLEAN ErrorFlag;
|
||||||
|
|
||||||
|
ErrorFlag = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Flush the HOB variable to flash.
|
||||||
|
//
|
||||||
|
if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) {
|
||||||
|
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase;
|
||||||
|
//
|
||||||
|
// Set HobVariableBase to 0, it can avoid SetVariable to call back.
|
||||||
|
//
|
||||||
|
mVariableModuleGlobal->VariableGlobal.HobVariableBase = 0;
|
||||||
|
for ( Variable = GetStartPointer (VariableStoreHeader)
|
||||||
|
; (Variable < GetEndPointer (VariableStoreHeader) && IsValidVariableHeader (Variable))
|
||||||
|
; Variable = GetNextVariablePtr (Variable)
|
||||||
|
) {
|
||||||
|
if (Variable->State != VAR_ADDED) {
|
||||||
|
//
|
||||||
|
// The HOB variable has been set to DELETED state in local.
|
||||||
|
//
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0);
|
||||||
|
if (VendorGuid == NULL || VariableName == NULL ||
|
||||||
|
!CompareGuid (VendorGuid, &Variable->VendorGuid) ||
|
||||||
|
StrCmp (VariableName, GetVariableNamePtr (Variable)) != 0) {
|
||||||
|
VariableData = GetVariableDataPtr (Variable);
|
||||||
|
Status = VariableServiceSetVariable (
|
||||||
|
GetVariableNamePtr (Variable),
|
||||||
|
&Variable->VendorGuid,
|
||||||
|
Variable->Attributes,
|
||||||
|
Variable->DataSize,
|
||||||
|
VariableData
|
||||||
|
);
|
||||||
|
DEBUG ((EFI_D_INFO, "Variable driver flush the HOB variable to flash: %g %s %r\n", &Variable->VendorGuid, GetVariableNamePtr (Variable), Status));
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// The updated or deleted variable is matched with the HOB variable.
|
||||||
|
// Don't break here because we will try to set other HOB variables
|
||||||
|
// since this variable could be set successfully.
|
||||||
|
//
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// If set variable successful, or the updated or deleted variable is matched with the HOB variable,
|
||||||
|
// set the HOB variable to DELETED state in local.
|
||||||
|
//
|
||||||
|
DEBUG ((EFI_D_INFO, "Variable driver set the HOB variable to DELETED state in local: %g %s\n", &Variable->VendorGuid, GetVariableNamePtr (Variable)));
|
||||||
|
Variable->State &= VAR_DELETED;
|
||||||
|
} else {
|
||||||
|
ErrorFlag = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ErrorFlag) {
|
||||||
|
//
|
||||||
|
// We still have HOB variable(s) not flushed in flash.
|
||||||
|
//
|
||||||
|
mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStoreHeader;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// All HOB variables have been flushed in flash.
|
||||||
|
//
|
||||||
|
DEBUG ((EFI_D_INFO, "Variable driver: all HOB variables have been flushed in flash.\n"));
|
||||||
|
if (!AtRuntime ()) {
|
||||||
|
FreePool ((VOID *) VariableStoreHeader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initializes variable write service after FVB was ready.
|
Initializes variable write service after FVB was ready.
|
||||||
|
@ -2407,8 +2512,6 @@ VariableWriteServiceInitialize (
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
UINT8 Data;
|
UINT8 Data;
|
||||||
EFI_PHYSICAL_ADDRESS VariableStoreBase;
|
EFI_PHYSICAL_ADDRESS VariableStoreBase;
|
||||||
VARIABLE_HEADER *Variable;
|
|
||||||
VOID *VariableData;
|
|
||||||
|
|
||||||
VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;
|
VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;
|
||||||
VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;
|
VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;
|
||||||
|
@ -2426,7 +2529,8 @@ VariableWriteServiceInitialize (
|
||||||
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
||||||
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL
|
NULL,
|
||||||
|
TRUE
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -2435,33 +2539,8 @@ VariableWriteServiceInitialize (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
FlushHobVariableToFlash (NULL, NULL);
|
||||||
// Flush the HOB variable to flash and invalidate HOB variable.
|
|
||||||
//
|
|
||||||
if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) {
|
|
||||||
//
|
|
||||||
// Clear the HobVariableBase to avoid SetVariable() updating the variable in HOB
|
|
||||||
//
|
|
||||||
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase;
|
|
||||||
mVariableModuleGlobal->VariableGlobal.HobVariableBase = 0;
|
|
||||||
|
|
||||||
for ( Variable = GetStartPointer (VariableStoreHeader)
|
|
||||||
; (Variable < GetEndPointer (VariableStoreHeader) && IsValidVariableHeader (Variable))
|
|
||||||
; Variable = GetNextVariablePtr (Variable)
|
|
||||||
) {
|
|
||||||
ASSERT (Variable->State == VAR_ADDED);
|
|
||||||
ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0);
|
|
||||||
VariableData = GetVariableDataPtr (Variable);
|
|
||||||
Status = VariableServiceSetVariable (
|
|
||||||
GetVariableNamePtr (Variable),
|
|
||||||
&Variable->VendorGuid,
|
|
||||||
Variable->Attributes,
|
|
||||||
Variable->DataSize,
|
|
||||||
VariableData
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2513,8 +2592,12 @@ VariableCommonInitialize (
|
||||||
GuidHob = GetFirstGuidHob (&gEfiVariableGuid);
|
GuidHob = GetFirstGuidHob (&gEfiVariableGuid);
|
||||||
if (GuidHob != NULL) {
|
if (GuidHob != NULL) {
|
||||||
VariableStoreHeader = GET_GUID_HOB_DATA (GuidHob);
|
VariableStoreHeader = GET_GUID_HOB_DATA (GuidHob);
|
||||||
|
VariableStoreLength = (UINT64) (GuidHob->Header.HobLength - sizeof (EFI_HOB_GUID_TYPE));
|
||||||
if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {
|
if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {
|
||||||
mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStoreHeader;
|
mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateRuntimeCopyPool ((UINTN) VariableStoreLength, (VOID *) VariableStoreHeader);
|
||||||
|
if (mVariableModuleGlobal->VariableGlobal.HobVariableBase == 0) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
DEBUG ((EFI_D_ERROR, "HOB Variable Store header is corrupted!\n"));
|
DEBUG ((EFI_D_ERROR, "HOB Variable Store header is corrupted!\n"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,19 @@ typedef struct {
|
||||||
VOID *Data;
|
VOID *Data;
|
||||||
} VARIABLE_CACHE_ENTRY;
|
} VARIABLE_CACHE_ENTRY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flush the HOB variable to flash.
|
||||||
|
|
||||||
|
@param[in] VariableName Name of variable has been updated or deleted.
|
||||||
|
@param[in] VendorGuid Guid of variable has been updated or deleted.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
FlushHobVariableToFlash (
|
||||||
|
IN CHAR16 *VariableName,
|
||||||
|
IN EFI_GUID *VendorGuid
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Writes a buffer to variable storage space, in the working block.
|
Writes a buffer to variable storage space, in the working block.
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Implement all four UEFI Runtime Variable services for the nonvolatile
|
Implement all four UEFI Runtime Variable services for the nonvolatile
|
||||||
and volatile storage space and install variable architecture protocol.
|
and volatile storage space and install variable architecture protocol.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -231,6 +231,7 @@ VariableClassAddressChangeEvent (
|
||||||
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);
|
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);
|
||||||
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
|
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
|
||||||
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
|
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
|
||||||
|
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.HobVariableBase);
|
||||||
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
|
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
|
||||||
EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
|
EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
|
||||||
}
|
}
|
||||||
|
|
|
@ -521,6 +521,7 @@ GetEndPointer (
|
||||||
@param IsVolatile The variable store is volatile or not;
|
@param IsVolatile The variable store is volatile or not;
|
||||||
if it is non-volatile, need FTW.
|
if it is non-volatile, need FTW.
|
||||||
@param UpdatingVariable Pointer to updating variable.
|
@param UpdatingVariable Pointer to updating variable.
|
||||||
|
@param ReclaimAnyway If TRUE, do reclaim anyway.
|
||||||
|
|
||||||
@return EFI_OUT_OF_RESOURCES
|
@return EFI_OUT_OF_RESOURCES
|
||||||
@return EFI_SUCCESS
|
@return EFI_SUCCESS
|
||||||
|
@ -532,7 +533,8 @@ Reclaim (
|
||||||
IN EFI_PHYSICAL_ADDRESS VariableBase,
|
IN EFI_PHYSICAL_ADDRESS VariableBase,
|
||||||
OUT UINTN *LastVariableOffset,
|
OUT UINTN *LastVariableOffset,
|
||||||
IN BOOLEAN IsVolatile,
|
IN BOOLEAN IsVolatile,
|
||||||
IN VARIABLE_HEADER *UpdatingVariable
|
IN VARIABLE_HEADER *UpdatingVariable,
|
||||||
|
IN BOOLEAN ReclaimAnyway
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
VARIABLE_HEADER *Variable;
|
VARIABLE_HEADER *Variable;
|
||||||
|
@ -555,7 +557,9 @@ Reclaim (
|
||||||
CHAR16 *UpdatingVariableNamePtr;
|
CHAR16 *UpdatingVariableNamePtr;
|
||||||
UINTN CommonVariableTotalSize;
|
UINTN CommonVariableTotalSize;
|
||||||
UINTN HwErrVariableTotalSize;
|
UINTN HwErrVariableTotalSize;
|
||||||
|
BOOLEAN NeedDoReclaim;
|
||||||
|
|
||||||
|
NeedDoReclaim = FALSE;
|
||||||
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
|
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
|
||||||
|
|
||||||
CommonVariableTotalSize = 0;
|
CommonVariableTotalSize = 0;
|
||||||
|
@ -574,11 +578,18 @@ Reclaim (
|
||||||
) {
|
) {
|
||||||
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
|
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
|
||||||
MaximumBufferSize += VariableSize;
|
MaximumBufferSize += VariableSize;
|
||||||
|
} else {
|
||||||
|
NeedDoReclaim = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable = NextVariable;
|
Variable = NextVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ReclaimAnyway && !NeedDoReclaim) {
|
||||||
|
DEBUG ((EFI_D_INFO, "Variable driver: no DELETED variable found, so no variable space could be reclaimed.\n"));
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reserve the 1 Bytes with Oxff to identify the
|
// Reserve the 1 Bytes with Oxff to identify the
|
||||||
// end of the variable buffer.
|
// end of the variable buffer.
|
||||||
|
@ -1524,6 +1535,7 @@ UpdateVariable (
|
||||||
UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, FALSE, TRUE, FALSE);
|
UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, FALSE, TRUE, FALSE);
|
||||||
if (!Variable->Volatile) {
|
if (!Variable->Volatile) {
|
||||||
CacheVariable->CurrPtr->State = State;
|
CacheVariable->CurrPtr->State = State;
|
||||||
|
FlushHobVariableToFlash (VariableName, VendorGuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto Done;
|
goto Done;
|
||||||
|
@ -1733,7 +1745,7 @@ UpdateVariable (
|
||||||
// Perform garbage collection & reclaim operation.
|
// Perform garbage collection & reclaim operation.
|
||||||
//
|
//
|
||||||
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
||||||
&mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr);
|
&mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr, FALSE);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
@ -1848,7 +1860,7 @@ UpdateVariable (
|
||||||
// Perform garbage collection & reclaim operation.
|
// Perform garbage collection & reclaim operation.
|
||||||
//
|
//
|
||||||
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,
|
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,
|
||||||
&mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr);
|
&mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr, FALSE);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
@ -1905,6 +1917,9 @@ UpdateVariable (
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE, FALSE, FALSE);
|
UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE, FALSE, FALSE);
|
||||||
|
if (!Volatile) {
|
||||||
|
FlushHobVariableToFlash (VariableName, VendorGuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Done:
|
Done:
|
||||||
|
@ -2613,12 +2628,102 @@ ReclaimForOS(
|
||||||
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
||||||
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL
|
NULL,
|
||||||
|
FALSE
|
||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flush the HOB variable to flash.
|
||||||
|
|
||||||
|
@param[in] VariableName Name of variable has been updated or deleted.
|
||||||
|
@param[in] VendorGuid Guid of variable has been updated or deleted.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
FlushHobVariableToFlash (
|
||||||
|
IN CHAR16 *VariableName,
|
||||||
|
IN EFI_GUID *VendorGuid
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
VARIABLE_STORE_HEADER *VariableStoreHeader;
|
||||||
|
VARIABLE_HEADER *Variable;
|
||||||
|
VOID *VariableData;
|
||||||
|
BOOLEAN ErrorFlag;
|
||||||
|
|
||||||
|
ErrorFlag = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Flush the HOB variable to flash.
|
||||||
|
//
|
||||||
|
if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) {
|
||||||
|
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase;
|
||||||
|
//
|
||||||
|
// Set HobVariableBase to 0, it can avoid SetVariable to call back.
|
||||||
|
//
|
||||||
|
mVariableModuleGlobal->VariableGlobal.HobVariableBase = 0;
|
||||||
|
for ( Variable = GetStartPointer (VariableStoreHeader)
|
||||||
|
; (Variable < GetEndPointer (VariableStoreHeader) && IsValidVariableHeader (Variable))
|
||||||
|
; Variable = GetNextVariablePtr (Variable)
|
||||||
|
) {
|
||||||
|
if (Variable->State != VAR_ADDED) {
|
||||||
|
//
|
||||||
|
// The HOB variable has been set to DELETED state in local.
|
||||||
|
//
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0);
|
||||||
|
if (VendorGuid == NULL || VariableName == NULL ||
|
||||||
|
!CompareGuid (VendorGuid, &Variable->VendorGuid) ||
|
||||||
|
StrCmp (VariableName, GetVariableNamePtr (Variable)) != 0) {
|
||||||
|
VariableData = GetVariableDataPtr (Variable);
|
||||||
|
Status = VariableServiceSetVariable (
|
||||||
|
GetVariableNamePtr (Variable),
|
||||||
|
&Variable->VendorGuid,
|
||||||
|
Variable->Attributes,
|
||||||
|
Variable->DataSize,
|
||||||
|
VariableData
|
||||||
|
);
|
||||||
|
DEBUG ((EFI_D_INFO, "Variable driver flush the HOB variable to flash: %g %s %r\n", &Variable->VendorGuid, GetVariableNamePtr (Variable), Status));
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// The updated or deleted variable is matched with the HOB variable.
|
||||||
|
// Don't break here because we will try to set other HOB variables
|
||||||
|
// since this variable could be set successfully.
|
||||||
|
//
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// If set variable successful, or the updated or deleted variable is matched with the HOB variable,
|
||||||
|
// set the HOB variable to DELETED state in local.
|
||||||
|
//
|
||||||
|
DEBUG ((EFI_D_INFO, "Variable driver set the HOB variable to DELETED state in local: %g %s\n", &Variable->VendorGuid, GetVariableNamePtr (Variable)));
|
||||||
|
Variable->State &= VAR_DELETED;
|
||||||
|
} else {
|
||||||
|
ErrorFlag = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ErrorFlag) {
|
||||||
|
//
|
||||||
|
// We still have HOB variable(s) not flushed in flash.
|
||||||
|
//
|
||||||
|
mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStoreHeader;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// All HOB variables have been flushed in flash.
|
||||||
|
//
|
||||||
|
DEBUG ((EFI_D_INFO, "Variable driver: all HOB variables have been flushed in flash.\n"));
|
||||||
|
if (!AtRuntime ()) {
|
||||||
|
FreePool ((VOID *) VariableStoreHeader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initializes variable write service after FVB was ready.
|
Initializes variable write service after FVB was ready.
|
||||||
|
@ -2637,8 +2742,6 @@ VariableWriteServiceInitialize (
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
UINT8 Data;
|
UINT8 Data;
|
||||||
EFI_PHYSICAL_ADDRESS VariableStoreBase;
|
EFI_PHYSICAL_ADDRESS VariableStoreBase;
|
||||||
VARIABLE_HEADER *Variable;
|
|
||||||
VOID *VariableData;
|
|
||||||
|
|
||||||
VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;
|
VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;
|
||||||
VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;
|
VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;
|
||||||
|
@ -2656,7 +2759,8 @@ VariableWriteServiceInitialize (
|
||||||
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
||||||
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL
|
NULL,
|
||||||
|
TRUE
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -2665,34 +2769,7 @@ VariableWriteServiceInitialize (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlushHobVariableToFlash (NULL, NULL);
|
||||||
//
|
|
||||||
// Flush the HOB variable to flash and invalidate HOB variable.
|
|
||||||
//
|
|
||||||
if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) {
|
|
||||||
//
|
|
||||||
// Clear the HobVariableBase to avoid SetVariable() updating the variable in HOB
|
|
||||||
//
|
|
||||||
VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase;
|
|
||||||
mVariableModuleGlobal->VariableGlobal.HobVariableBase = 0;
|
|
||||||
|
|
||||||
for ( Variable = GetStartPointer (VariableStoreHeader)
|
|
||||||
; (Variable < GetEndPointer (VariableStoreHeader) && IsValidVariableHeader (Variable))
|
|
||||||
; Variable = GetNextVariablePtr (Variable)
|
|
||||||
) {
|
|
||||||
ASSERT (Variable->State == VAR_ADDED);
|
|
||||||
ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0);
|
|
||||||
VariableData = GetVariableDataPtr (Variable);
|
|
||||||
Status = VariableServiceSetVariable (
|
|
||||||
GetVariableNamePtr (Variable),
|
|
||||||
&Variable->VendorGuid,
|
|
||||||
Variable->Attributes,
|
|
||||||
Variable->DataSize,
|
|
||||||
VariableData
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Authenticated variable initialize.
|
// Authenticated variable initialize.
|
||||||
|
@ -2750,8 +2827,12 @@ VariableCommonInitialize (
|
||||||
GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid);
|
GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid);
|
||||||
if (GuidHob != NULL) {
|
if (GuidHob != NULL) {
|
||||||
VariableStoreHeader = GET_GUID_HOB_DATA (GuidHob);
|
VariableStoreHeader = GET_GUID_HOB_DATA (GuidHob);
|
||||||
|
VariableStoreLength = (UINT64) (GuidHob->Header.HobLength - sizeof (EFI_HOB_GUID_TYPE));
|
||||||
if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {
|
if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {
|
||||||
mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStoreHeader;
|
mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateRuntimeCopyPool ((UINTN) VariableStoreLength, (VOID *) VariableStoreHeader);
|
||||||
|
if (mVariableModuleGlobal->VariableGlobal.HobVariableBase == 0) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
DEBUG ((EFI_D_ERROR, "HOB Variable Store header is corrupted!\n"));
|
DEBUG ((EFI_D_ERROR, "HOB Variable Store header is corrupted!\n"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,19 @@ typedef struct {
|
||||||
VOID *Data;
|
VOID *Data;
|
||||||
} VARIABLE_CACHE_ENTRY;
|
} VARIABLE_CACHE_ENTRY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flush the HOB variable to flash.
|
||||||
|
|
||||||
|
@param[in] VariableName Name of variable has been updated or deleted.
|
||||||
|
@param[in] VendorGuid Guid of variable has been updated or deleted.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
FlushHobVariableToFlash (
|
||||||
|
IN CHAR16 *VariableName,
|
||||||
|
IN EFI_GUID *VendorGuid
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Writes a buffer to variable storage space, in the working block.
|
Writes a buffer to variable storage space, in the working block.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue