[Description]:

The patch enhanced variable services to support:
1) If adding variable does not execute completely, the state is in_deleted, the next time find variable should have to retrieve the in_deleted variable.
2) when Reclaiming the variable storage, the 1) variable should be considered.

[Impaction]:
This is backward-compatible update.

[Reference Info]:
9552, 8632

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4916 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
yshang1 2008-03-19 07:09:03 +00:00
parent 695f7e9856
commit 814bae5269
1 changed files with 131 additions and 41 deletions

View File

@ -574,7 +574,8 @@ EFI_STATUS
Reclaim (
IN EFI_PHYSICAL_ADDRESS VariableBase,
OUT UINTN *LastVariableOffset,
IN BOOLEAN IsVolatile
IN BOOLEAN IsVolatile,
IN VARIABLE_HEADER *UpdatingVariable
)
/*++
@ -596,12 +597,18 @@ Returns:
--*/
{
VARIABLE_HEADER *Variable;
VARIABLE_HEADER *AddedVariable;
VARIABLE_HEADER *NextVariable;
VARIABLE_HEADER *NextAddedVariable;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINT8 *ValidBuffer;
UINTN ValidBufferSize;
UINTN MaximumBufferSize;
UINTN VariableSize;
UINTN NameSize;
UINT8 *CurrPtr;
VOID *Point0;
VOID *Point1;
BOOLEAN FoundAdded;
EFI_STATUS Status;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
@ -609,39 +616,47 @@ Returns:
//
// Start Pointers for the variable.
//
Variable = GetStartPointer (VariableStoreHeader);
ValidBufferSize = sizeof (VARIABLE_STORE_HEADER);
Variable = GetStartPointer (VariableStoreHeader);
MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
if (Variable->State == VAR_ADDED) {
if (Variable->State == VAR_ADDED ||
Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)
) {
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
ValidBufferSize += VariableSize;
MaximumBufferSize += VariableSize;
}
Variable = NextVariable;
}
ValidBuffer = AllocatePool (ValidBufferSize);
//
// Reserve the 1 Bytes with Oxff to identify the
// end of the variable buffer.
//
MaximumBufferSize += 1;
ValidBuffer = AllocatePool (MaximumBufferSize);
if (ValidBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
SetMem (ValidBuffer, ValidBufferSize, 0xff);
CurrPtr = ValidBuffer;
SetMem (ValidBuffer, MaximumBufferSize, 0xff);
//
// Copy variable store header
//
CopyMem (CurrPtr, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));
CurrPtr = (UINT8 *) GetStartPointer ((VARIABLE_STORE_HEADER *) CurrPtr);
CopyMem (ValidBuffer, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));
CurrPtr = (UINT8 *) GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer);
//
// Start Pointers for the variable.
//
Variable = GetStartPointer (VariableStoreHeader);
//
// Reinstall all ADDED variables
//
Variable = GetStartPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
if (Variable->State == VAR_ADDED) {
@ -652,14 +667,61 @@ Returns:
Variable = NextVariable;
}
//
// Reinstall all in delete transition variables
//
Variable = GetStartPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
if (Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
//
// Buffer has cached all ADDED variable.
// Per IN_DELETED variable, we have to guarantee that
// no ADDED one in previous buffer.
//
FoundAdded = FALSE;
AddedVariable = GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer);
while (IsValidVariableHeader (AddedVariable)) {
NextAddedVariable = GetNextVariablePtr (AddedVariable);
NameSize = NameSizeOfVariable (AddedVariable);
if (CompareGuid (&AddedVariable->VendorGuid, &Variable->VendorGuid) &&
NameSize == NameSizeOfVariable (Variable)
) {
Point0 = (VOID *) GetVariableNamePtr (AddedVariable);
Point1 = (VOID *) GetVariableNamePtr (Variable);
if (!CompareMem (
Point0,
Point1,
NameSizeOfVariable (AddedVariable)
)
) {
FoundAdded = TRUE;
break;
}
}
AddedVariable = NextAddedVariable;
}
if (!FoundAdded) {
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
if (Variable != UpdatingVariable) {
((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED;
}
CurrPtr += VariableSize;
}
}
Variable = NextVariable;
}
if (IsVolatile) {
//
// If volatile variable store, just copy valid buffer
//
SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);
CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, ValidBufferSize);
*LastVariableOffset = ValidBufferSize;
CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - (UINT8 *) ValidBuffer));
Status = EFI_SUCCESS;
} else {
//
@ -668,19 +730,17 @@ Returns:
Status = FtwVariableSpace (
VariableBase,
ValidBuffer,
ValidBufferSize
(UINTN) (CurrPtr - (UINT8 *) ValidBuffer)
);
if (!EFI_ERROR (Status)) {
*LastVariableOffset = ValidBufferSize;
}
}
if (!EFI_ERROR (Status)) {
*LastVariableOffset = (UINTN) (CurrPtr - (UINT8 *) ValidBuffer);
} else {
*LastVariableOffset = 0;
}
FreePool (ValidBuffer);
if (EFI_ERROR (Status)) {
*LastVariableOffset = 0;
}
return Status;
}
@ -838,10 +898,12 @@ Returns:
--*/
{
VARIABLE_HEADER *Variable[2];
VARIABLE_STORE_HEADER *VariableStoreHeader[2];
UINTN Index;
VOID *Point;
VARIABLE_HEADER *Variable[2];
VARIABLE_HEADER *InDeletedVariable;
VARIABLE_STORE_HEADER *VariableStoreHeader[2];
UINTN InDeletedStorageIndex;
UINTN Index;
VOID *Point;
//
// 0: Volatile, 1: Non-Volatile
@ -861,29 +923,47 @@ Returns:
if (VariableName[0] != 0 && VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Find the variable by walk through volatile and then non-volatile variable store
//
InDeletedVariable = NULL;
InDeletedStorageIndex = 0;
for (Index = 0; Index < 2; Index++) {
PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[Index]);
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]);
while (IsValidVariableHeader (Variable[Index]) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) {
if (Variable[Index]->State == VAR_ADDED) {
if (Variable[Index]->State == VAR_ADDED ||
Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)
) {
if (!EfiAtRuntime () || (Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
if (VariableName[0] == 0) {
PtrTrack->CurrPtr = Variable[Index];
PtrTrack->Volatile = (BOOLEAN)(Index == 0);
return EFI_SUCCESS;
if (Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
InDeletedVariable = Variable[Index];
InDeletedStorageIndex = Index;
} else {
PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[Index]);
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]);
PtrTrack->CurrPtr = Variable[Index];
PtrTrack->Volatile = (BOOLEAN)(Index == 0);
return EFI_SUCCESS;
}
} else {
if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {
Point = (VOID *) GetVariableNamePtr (Variable[Index]);
ASSERT (NameSizeOfVariable (Variable[Index]) != 0);
if (!CompareMem (VariableName, Point, NameSizeOfVariable (Variable[Index]))) {
PtrTrack->CurrPtr = Variable[Index];
PtrTrack->Volatile = (BOOLEAN)(Index == 0);
return EFI_SUCCESS;
if (Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
InDeletedVariable = Variable[Index];
InDeletedStorageIndex = Index;
} else {
PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[Index]);
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]);
PtrTrack->CurrPtr = Variable[Index];
PtrTrack->Volatile = (BOOLEAN)(Index == 0);
return EFI_SUCCESS;
}
}
}
}
@ -892,6 +972,13 @@ Returns:
Variable[Index] = GetNextVariablePtr (Variable[Index]);
}
if (InDeletedVariable != NULL) {
PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[InDeletedStorageIndex]);
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[InDeletedStorageIndex]);
PtrTrack->CurrPtr = InDeletedVariable;
PtrTrack->Volatile = (BOOLEAN)(InDeletedStorageIndex == 0);
return EFI_SUCCESS;
}
}
PtrTrack->CurrPtr = NULL;
return EFI_NOT_FOUND;
@ -1279,6 +1366,7 @@ RuntimeServiceSetVariable (
goto Done;
} else if ((Variable.CurrPtr->State == VAR_ADDED) ||
(Variable.CurrPtr->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION))) {
//
// Mark the old variable as in delete transition
//
@ -1388,7 +1476,7 @@ RuntimeServiceSetVariable (
//
// Perform garbage collection & reclaim operation
//
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, NonVolatileOffset, FALSE);
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, NonVolatileOffset, FALSE, Variable.CurrPtr);
if (EFI_ERROR (Status)) {
goto Done;
}
@ -1492,7 +1580,7 @@ RuntimeServiceSetVariable (
//
// Perform garbage collection & reclaim operation
//
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase, VolatileOffset, TRUE);
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase, VolatileOffset, TRUE, Variable.CurrPtr);
if (EFI_ERROR (Status)) {
goto Done;
}
@ -1723,7 +1811,8 @@ ReclaimForOS(
Status = Reclaim (
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE
FALSE,
NULL
);
ASSERT_EFI_ERROR (Status);
}
@ -1912,7 +2001,8 @@ Returns:
Status = Reclaim (
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE
FALSE,
NULL
);
if (EFI_ERROR (Status)) {