mirror of https://github.com/acidanthera/audk.git
[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:
parent
695f7e9856
commit
814bae5269
|
@ -574,7 +574,8 @@ EFI_STATUS
|
||||||
Reclaim (
|
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
|
||||||
)
|
)
|
||||||
/*++
|
/*++
|
||||||
|
|
||||||
|
@ -596,12 +597,18 @@ Returns:
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
VARIABLE_HEADER *Variable;
|
VARIABLE_HEADER *Variable;
|
||||||
|
VARIABLE_HEADER *AddedVariable;
|
||||||
VARIABLE_HEADER *NextVariable;
|
VARIABLE_HEADER *NextVariable;
|
||||||
|
VARIABLE_HEADER *NextAddedVariable;
|
||||||
VARIABLE_STORE_HEADER *VariableStoreHeader;
|
VARIABLE_STORE_HEADER *VariableStoreHeader;
|
||||||
UINT8 *ValidBuffer;
|
UINT8 *ValidBuffer;
|
||||||
UINTN ValidBufferSize;
|
UINTN MaximumBufferSize;
|
||||||
UINTN VariableSize;
|
UINTN VariableSize;
|
||||||
|
UINTN NameSize;
|
||||||
UINT8 *CurrPtr;
|
UINT8 *CurrPtr;
|
||||||
|
VOID *Point0;
|
||||||
|
VOID *Point1;
|
||||||
|
BOOLEAN FoundAdded;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
|
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
|
||||||
|
@ -609,39 +616,47 @@ Returns:
|
||||||
//
|
//
|
||||||
// Start Pointers for the variable.
|
// Start Pointers for the variable.
|
||||||
//
|
//
|
||||||
Variable = GetStartPointer (VariableStoreHeader);
|
Variable = GetStartPointer (VariableStoreHeader);
|
||||||
ValidBufferSize = sizeof (VARIABLE_STORE_HEADER);
|
MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER);
|
||||||
|
|
||||||
while (IsValidVariableHeader (Variable)) {
|
while (IsValidVariableHeader (Variable)) {
|
||||||
NextVariable = GetNextVariablePtr (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;
|
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
|
||||||
ValidBufferSize += VariableSize;
|
MaximumBufferSize += VariableSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable = NextVariable;
|
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) {
|
if (ValidBuffer == NULL) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetMem (ValidBuffer, ValidBufferSize, 0xff);
|
SetMem (ValidBuffer, MaximumBufferSize, 0xff);
|
||||||
|
|
||||||
CurrPtr = ValidBuffer;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copy variable store header
|
// Copy variable store header
|
||||||
//
|
//
|
||||||
CopyMem (CurrPtr, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));
|
CopyMem (ValidBuffer, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));
|
||||||
CurrPtr = (UINT8 *) GetStartPointer ((VARIABLE_STORE_HEADER *) CurrPtr);
|
CurrPtr = (UINT8 *) GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Start Pointers for the variable.
|
// Start Pointers for the variable.
|
||||||
//
|
//
|
||||||
Variable = GetStartPointer (VariableStoreHeader);
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reinstall all ADDED variables
|
||||||
|
//
|
||||||
|
Variable = GetStartPointer (VariableStoreHeader);
|
||||||
while (IsValidVariableHeader (Variable)) {
|
while (IsValidVariableHeader (Variable)) {
|
||||||
NextVariable = GetNextVariablePtr (Variable);
|
NextVariable = GetNextVariablePtr (Variable);
|
||||||
if (Variable->State == VAR_ADDED) {
|
if (Variable->State == VAR_ADDED) {
|
||||||
|
@ -652,14 +667,61 @@ Returns:
|
||||||
|
|
||||||
Variable = NextVariable;
|
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 (IsVolatile) {
|
||||||
//
|
//
|
||||||
// If volatile variable store, just copy valid buffer
|
// If volatile variable store, just copy valid buffer
|
||||||
//
|
//
|
||||||
SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);
|
SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);
|
||||||
CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, ValidBufferSize);
|
CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - (UINT8 *) ValidBuffer));
|
||||||
*LastVariableOffset = ValidBufferSize;
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
|
@ -668,19 +730,17 @@ Returns:
|
||||||
Status = FtwVariableSpace (
|
Status = FtwVariableSpace (
|
||||||
VariableBase,
|
VariableBase,
|
||||||
ValidBuffer,
|
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);
|
FreePool (ValidBuffer);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
*LastVariableOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -838,10 +898,12 @@ Returns:
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
VARIABLE_HEADER *Variable[2];
|
VARIABLE_HEADER *Variable[2];
|
||||||
VARIABLE_STORE_HEADER *VariableStoreHeader[2];
|
VARIABLE_HEADER *InDeletedVariable;
|
||||||
UINTN Index;
|
VARIABLE_STORE_HEADER *VariableStoreHeader[2];
|
||||||
VOID *Point;
|
UINTN InDeletedStorageIndex;
|
||||||
|
UINTN Index;
|
||||||
|
VOID *Point;
|
||||||
|
|
||||||
//
|
//
|
||||||
// 0: Volatile, 1: Non-Volatile
|
// 0: Volatile, 1: Non-Volatile
|
||||||
|
@ -861,29 +923,47 @@ Returns:
|
||||||
if (VariableName[0] != 0 && VendorGuid == NULL) {
|
if (VariableName[0] != 0 && VendorGuid == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find the variable by walk through volatile and then non-volatile variable store
|
// Find the variable by walk through volatile and then non-volatile variable store
|
||||||
//
|
//
|
||||||
|
InDeletedVariable = NULL;
|
||||||
|
InDeletedStorageIndex = 0;
|
||||||
for (Index = 0; Index < 2; Index++) {
|
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]))) {
|
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 (!EfiAtRuntime () || (Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
|
||||||
if (VariableName[0] == 0) {
|
if (VariableName[0] == 0) {
|
||||||
PtrTrack->CurrPtr = Variable[Index];
|
if (Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
|
||||||
PtrTrack->Volatile = (BOOLEAN)(Index == 0);
|
InDeletedVariable = Variable[Index];
|
||||||
return EFI_SUCCESS;
|
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 {
|
} else {
|
||||||
if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {
|
if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {
|
||||||
Point = (VOID *) GetVariableNamePtr (Variable[Index]);
|
Point = (VOID *) GetVariableNamePtr (Variable[Index]);
|
||||||
|
|
||||||
ASSERT (NameSizeOfVariable (Variable[Index]) != 0);
|
ASSERT (NameSizeOfVariable (Variable[Index]) != 0);
|
||||||
if (!CompareMem (VariableName, Point, NameSizeOfVariable (Variable[Index]))) {
|
if (!CompareMem (VariableName, Point, NameSizeOfVariable (Variable[Index]))) {
|
||||||
PtrTrack->CurrPtr = Variable[Index];
|
if (Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
|
||||||
PtrTrack->Volatile = (BOOLEAN)(Index == 0);
|
InDeletedVariable = Variable[Index];
|
||||||
return EFI_SUCCESS;
|
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]);
|
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;
|
PtrTrack->CurrPtr = NULL;
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
|
@ -1279,6 +1366,7 @@ RuntimeServiceSetVariable (
|
||||||
goto Done;
|
goto Done;
|
||||||
} else if ((Variable.CurrPtr->State == VAR_ADDED) ||
|
} else if ((Variable.CurrPtr->State == VAR_ADDED) ||
|
||||||
(Variable.CurrPtr->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION))) {
|
(Variable.CurrPtr->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION))) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Mark the old variable as in delete transition
|
// Mark the old variable as in delete transition
|
||||||
//
|
//
|
||||||
|
@ -1388,7 +1476,7 @@ RuntimeServiceSetVariable (
|
||||||
//
|
//
|
||||||
// Perform garbage collection & reclaim operation
|
// 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)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
@ -1492,7 +1580,7 @@ RuntimeServiceSetVariable (
|
||||||
//
|
//
|
||||||
// Perform garbage collection & reclaim operation
|
// 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)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
@ -1723,7 +1811,8 @@ ReclaimForOS(
|
||||||
Status = Reclaim (
|
Status = Reclaim (
|
||||||
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
||||||
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
||||||
FALSE
|
FALSE,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
}
|
}
|
||||||
|
@ -1912,7 +2001,8 @@ Returns:
|
||||||
Status = Reclaim (
|
Status = Reclaim (
|
||||||
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
|
||||||
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
|
||||||
FALSE
|
FALSE,
|
||||||
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
|
Loading…
Reference in New Issue