1. Uefi2.1 feature - Add Hardware Error Record Persistence Support

2. Fix the return status accoring to approved UEFI ECRs.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3866 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qhuang8 2007-09-17 03:50:40 +00:00
parent 4aad654298
commit c649283953
3 changed files with 548 additions and 437 deletions

View File

@ -59,3 +59,12 @@ EDK_3773: Non-Compatible: qwang12
3) The gEfiFirmwareVolumeProtocolGuid in [Depex] section of INF file should updated. 3) The gEfiFirmwareVolumeProtocolGuid in [Depex] section of INF file should updated.
And the package dependency should also be changed if needed due to this protocol And the package dependency should also be changed if needed due to this protocol
GUID change. GUID change.
==========================================================================================
EDK_3865: Compatible: qhuang8
Class_UefiEnable[0]: Uefi2.1 feature - Add Hardware Error Record Persistence Support
Code Change :
1) Modify MdeModulePkg/Universal/Variable/RuntimeDxe
2) Modify MdeModulePkg/Universal/Variable/EmuRuntimeDxe

View File

@ -60,7 +60,6 @@ ReleaseLockOnlyAtBootTime (
STATIC STATIC
UINT8 * UINT8 *
EFIAPI
GetVariableDataPtr ( GetVariableDataPtr (
IN VARIABLE_HEADER *Variable IN VARIABLE_HEADER *Variable
) )
@ -91,7 +90,6 @@ Returns:
STATIC STATIC
VARIABLE_HEADER * VARIABLE_HEADER *
EFIAPI
GetNextVariablePtr ( GetNextVariablePtr (
IN VARIABLE_HEADER *Variable IN VARIABLE_HEADER *Variable
) )
@ -132,7 +130,6 @@ Returns:
STATIC STATIC
VARIABLE_HEADER * VARIABLE_HEADER *
EFIAPI
GetEndPointer ( GetEndPointer (
IN VARIABLE_STORE_HEADER *VolHeader IN VARIABLE_STORE_HEADER *VolHeader
) )
@ -160,7 +157,6 @@ Returns:
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI
FindVariable ( FindVariable (
IN CHAR16 *VariableName, IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid, IN EFI_GUID *VendorGuid,
@ -278,7 +274,11 @@ Arguments:
Returns: Returns:
EFI STATUS EFI_INVALID_PARAMETER - Invalid parameter
EFI_SUCCESS - Find the specified variable
EFI_NOT_FOUND - Not found
EFI_BUFFER_TO_SMALL - DataSize is too small for the result
--*/ --*/
{ {
@ -463,7 +463,12 @@ Arguments:
Returns: Returns:
EFI STATUS EFI_INVALID_PARAMETER - Invalid parameter
EFI_SUCCESS - Set successfully
EFI_OUT_OF_RESOURCES - Resource not enough to set variable
EFI_NOT_FOUND - Not found
EFI_DEVICE_ERROR - Variable can not be saved due to hardware failure
EFI_WRITE_PROTECTED - Variable is read-only
--*/ --*/
{ {
@ -475,147 +480,188 @@ Returns:
UINTN VarDataOffset; UINTN VarDataOffset;
UINTN VarSize; UINTN VarSize;
//
// Check input parameters
//
if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) { if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
}
//
// Make sure if runtime bit is set, boot service bit is set also
//
if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
return EFI_INVALID_PARAMETER;
} }
//
// The size of the VariableName, including the Unicode Null in bytes plus
// the DataSize is limited to maximum size of MAX_HARDWARE_ERROR_VARIABLE_SIZE (32K)
// bytes for HwErrRec, and MAX_VARIABLE_SIZE (1024) bytes for the others.
//
if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
if ((DataSize > MAX_HARDWARE_ERROR_VARIABLE_SIZE) ||
(sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > MAX_HARDWARE_ERROR_VARIABLE_SIZE)) {
return EFI_INVALID_PARAMETER;
}
} else {
//
// The size of the VariableName, including the Unicode Null in bytes plus
// the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes.
//
if ((DataSize > MAX_VARIABLE_SIZE) ||
(sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > MAX_VARIABLE_SIZE)) {
return EFI_INVALID_PARAMETER;
}
}
//
// Check whether the input variable is already existed
//
Status = FindVariable (VariableName, VendorGuid, &Variable, Global); Status = FindVariable (VariableName, VendorGuid, &Variable, Global);
if (Status == EFI_INVALID_PARAMETER) { if (Status == EFI_SUCCESS && Variable.CurrPtr != NULL) {
goto Done;
} else if (!EFI_ERROR (Status) && Variable.Volatile && EfiAtRuntime()) {
// //
// If EfiAtRuntime and the variable is Volatile and Runtime Access, // Update/Delete existing variable
// the volatile is ReadOnly, and SetVariable should be aborted and
// return EFI_WRITE_PROTECTED.
// //
Status = EFI_WRITE_PROTECTED;
goto Done; if (EfiAtRuntime ()) {
} else if (sizeof (VARIABLE_HEADER) + (StrSize (VariableName) + DataSize) > MAX_VARIABLE_SIZE) { //
// // If EfiAtRuntime and the variable is Volatile and Runtime Access,
// The size of the VariableName, including the Unicode Null in bytes plus // the volatile is ReadOnly, and SetVariable should be aborted and
// the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes. // return EFI_WRITE_PROTECTED.
// //
Status = EFI_INVALID_PARAMETER; if (Variable.Volatile) {
goto Done; Status = EFI_WRITE_PROTECTED;
} else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS goto Done;
) { }
// //
// Make sure if runtime bit is set, boot service bit is set also // Only variable have NV attribute can be updated/deleted in Runtime
// //
Status = EFI_INVALID_PARAMETER; if (!(Variable.CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE)) {
goto Done; Status = EFI_INVALID_PARAMETER;
} else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) { goto Done;
// }
// Runtime but Attribute is not Runtime }
//
Status = EFI_INVALID_PARAMETER;
goto Done;
} else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {
//
// Cannot set volatile variable in Runtime
//
Status = EFI_INVALID_PARAMETER;
goto Done;
} else if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {
// //
// Setting a data variable with no access, or zero DataSize attributes // Setting a data variable with no access, or zero DataSize attributes
// specified causes it to be deleted. // specified causes it to be deleted.
// //
if (!EFI_ERROR (Status)) { if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {
Variable.CurrPtr->State &= VAR_DELETED; Variable.CurrPtr->State &= VAR_DELETED;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
goto Done; goto Done;
} }
Status = EFI_NOT_FOUND; //
goto Done; // If the variable is marked valid and the same data has been passed in
// then return to the caller immediately.
//
if (Variable.CurrPtr->DataSize == DataSize &&
!CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize)
) {
Status = EFI_SUCCESS;
goto Done;
} else if (Variable.CurrPtr->State == VAR_ADDED) {
//
// Mark the old variable as in delete transition
//
Variable.CurrPtr->State &= VAR_IN_DELETED_TRANSITION;
}
} else if (Status == EFI_NOT_FOUND) {
//
// Create a new variable
//
//
// Make sure we are trying to create a new variable.
// Setting a data variable with no access, or zero DataSize attributes means to delete it.
//
if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {
Status = EFI_NOT_FOUND;
goto Done;
}
//
// Only variable have NV|RT attribute can be created in Runtime
//
if (EfiAtRuntime () &&
(!(Attributes & EFI_VARIABLE_RUNTIME_ACCESS) || !(Attributes & EFI_VARIABLE_NON_VOLATILE))) {
Status = EFI_INVALID_PARAMETER;
goto Done;
}
} else { } else {
if (!EFI_ERROR (Status)) {
//
// If the variable is marked valid and the same data has been passed in
// then return to the caller immediately.
//
if (Variable.CurrPtr->DataSize == DataSize &&
!CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize)
) {
Status = EFI_SUCCESS;
goto Done;
} else if (Variable.CurrPtr->State == VAR_ADDED) {
//
// Mark the old variable as in delete transition
//
Variable.CurrPtr->State &= VAR_IN_DELETED_TRANSITION;
}
}
// //
// Create a new variable and copy the data. // Status should be EFI_INVALID_PARAMETER here according to return status of FindVariable().
// //
VarNameOffset = sizeof (VARIABLE_HEADER); ASSERT (Status == EFI_INVALID_PARAMETER);
VarNameSize = StrSize (VariableName); goto Done;
VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize); }
VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize);
//
// Function part - create a new variable and copy the data.
// Both update a variable and create a variable will come here.
//
VarNameOffset = sizeof (VARIABLE_HEADER);
VarNameSize = StrSize (VariableName);
VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize);
VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize);
if (Attributes & EFI_VARIABLE_NON_VOLATILE) { if (Attributes & EFI_VARIABLE_NON_VOLATILE) {
if ((UINT32) (VarSize +*NonVolatileOffset) > if ((UINT32) (VarSize +*NonVolatileOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size
) { ) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto Done; goto Done;
}
NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*NonVolatileOffset + (UINTN) Global->NonVolatileVariableBase);
*NonVolatileOffset = *NonVolatileOffset + VarSize;
} else {
if (EfiAtRuntime ()) {
Status = EFI_INVALID_PARAMETER;
goto Done;
}
if ((UINT32) (VarSize +*VolatileOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size
) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*VolatileOffset + (UINTN) Global->VolatileVariableBase);
*VolatileOffset = *VolatileOffset + VarSize;
} }
NextVariable->StartId = VARIABLE_DATA; NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*NonVolatileOffset + (UINTN) Global->NonVolatileVariableBase);
NextVariable->Attributes = Attributes; *NonVolatileOffset = *NonVolatileOffset + VarSize;
NextVariable->State = VAR_ADDED; } else {
NextVariable->Reserved = 0; if ((UINT32) (VarSize +*VolatileOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size
// ) {
// There will be pad bytes after Data, the NextVariable->NameSize and Status = EFI_OUT_OF_RESOURCES;
// NextVariable->NameSize should not include pad size so that variable goto Done;
// service can get actual size in GetVariable
//
NextVariable->NameSize = (UINT32)VarNameSize;
NextVariable->DataSize = (UINT32)DataSize;
CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));
CopyMem (
(UINT8 *) ((UINTN) NextVariable + VarNameOffset),
VariableName,
VarNameSize
);
CopyMem (
(UINT8 *) ((UINTN) NextVariable + VarDataOffset),
Data,
DataSize
);
//
// Mark the old variable as deleted
//
if (!EFI_ERROR (Status)) {
Variable.CurrPtr->State &= VAR_DELETED;
} }
NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*VolatileOffset + (UINTN) Global->VolatileVariableBase);
*VolatileOffset = *VolatileOffset + VarSize;
} }
NextVariable->StartId = VARIABLE_DATA;
NextVariable->Attributes = Attributes;
NextVariable->State = VAR_ADDED;
NextVariable->Reserved = 0;
//
// There will be pad bytes after Data, the NextVariable->NameSize and
// NextVariable->NameSize should not include pad size so that variable
// service can get actual size in GetVariable
//
NextVariable->NameSize = (UINT32)VarNameSize;
NextVariable->DataSize = (UINT32)DataSize;
CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));
CopyMem (
(UINT8 *) ((UINTN) NextVariable + VarNameOffset),
VariableName,
VarNameSize
);
CopyMem (
(UINT8 *) ((UINTN) NextVariable + VarDataOffset),
Data,
DataSize
);
//
// Mark the old variable as deleted
//
if (!EFI_ERROR (Status)) {
Variable.CurrPtr->State &= VAR_DELETED;
}
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
Done: Done:
ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);
@ -645,8 +691,8 @@ Arguments:
MaximumVariableStorageSize Pointer to the maximum size of the storage space available MaximumVariableStorageSize Pointer to the maximum size of the storage space available
for the EFI variables associated with the attributes specified. for the EFI variables associated with the attributes specified.
RemainingVariableStorageSize Pointer to the remaining size of the storage space available RemainingVariableStorageSize Pointer to the remaining size of the storage space available
for the EFI variables associated with the attributes specified. for EFI variables associated with the attributes specified.
MaximumVariableSize Pointer to the maximum size of the individual EFI variables MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified. associated with the attributes specified.
Global Pointer to VARIABLE_GLOBAL structure. Global Pointer to VARIABLE_GLOBAL structure.
Instance Instance of the Firmware Volume. Instance Instance of the Firmware Volume.
@ -665,15 +711,15 @@ Returns:
UINT64 VariableSize; UINT64 VariableSize;
VARIABLE_STORE_HEADER *VariableStoreHeader; VARIABLE_STORE_HEADER *VariableStoreHeader;
if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL) { if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)) == 0) { if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
// //
// Make sure the Attributes combination is supported by the platform. // Make sure the Attributes combination is supported by the platform.
// //
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) { } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
// //
// Make sure if runtime bit is set, boot service bit is set also. // Make sure if runtime bit is set, boot service bit is set also.
@ -713,9 +759,16 @@ Returns:
*RemainingVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER); *RemainingVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER);
// //
// Let *MaximumVariableSize be MAX_VARIABLE_SIZE // Let *MaximumVariableSize be MAX_VARIABLE_SIZE with the exception of the variable header size.
// //
*MaximumVariableSize = MAX_VARIABLE_SIZE; *MaximumVariableSize = MAX_VARIABLE_SIZE - sizeof (VARIABLE_HEADER);
//
// Harware error record variable needs larger size.
//
if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
*MaximumVariableSize = MAX_HARDWARE_ERROR_VARIABLE_SIZE - sizeof (VARIABLE_HEADER);
}
// //
// Point to the starting address of the variables. // Point to the starting address of the variables.
@ -743,13 +796,18 @@ Returns:
Variable = NextVariable; Variable = NextVariable;
} }
if (*RemainingVariableStorageSize < sizeof (VARIABLE_HEADER)) {
*MaximumVariableSize = 0;
} else if ((*RemainingVariableStorageSize - sizeof (VARIABLE_HEADER)) < *MaximumVariableSize) {
*MaximumVariableSize = *RemainingVariableStorageSize - sizeof (VARIABLE_HEADER);
}
ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI
InitializeVariableStore ( InitializeVariableStore (
OUT EFI_PHYSICAL_ADDRESS *VariableBase, OUT EFI_PHYSICAL_ADDRESS *VariableBase,
OUT UINTN *LastVariableOffset OUT UINTN *LastVariableOffset

View File

@ -112,19 +112,20 @@ Routine Description:
Arguments: Arguments:
Global Pointer to VARAIBLE_GLOBAL structure Global - Pointer to VARAIBLE_GLOBAL structure
Volatile If the Variable is Volatile or Non-Volatile Volatile - If the Variable is Volatile or Non-Volatile
SetByIndex TRUE: Target pointer is given as index SetByIndex - TRUE: Target pointer is given as index
FALSE: Target pointer is absolute FALSE: Target pointer is absolute
Instance Instance of FV Block services Instance - Instance of FV Block services
DataPtrIndex Pointer to the Data from the end of VARIABLE_STORE_HEADER DataPtrIndex - Pointer to the Data from the end of VARIABLE_STORE_HEADER
structure structure
DataSize Size of data to be written. DataSize - Size of data to be written.
Buffer Pointer to the buffer from which data is written Buffer - Pointer to the buffer from which data is written
Returns: Returns:
EFI STATUS EFI_INVALID_PARAMETER - Parameters not valid
EFI_SUCCESS - Variable store successfully updated
--*/ --*/
{ {
@ -175,14 +176,14 @@ Returns:
if ((DataPtr + DataSize) >= ((UINTN) ((UINT8 *) VolatileBase + VolatileBase->Size))) { if ((DataPtr + DataSize) >= ((UINTN) ((UINT8 *) VolatileBase + VolatileBase->Size))) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
}
// //
// If Volatile Variable just do a simple mem copy. // If Volatile Variable just do a simple mem copy.
// //
if (Volatile) { CopyMem ((UINT8 *)(UINTN)DataPtr, Buffer, DataSize);
CopyMem ((UINT8 *) ((UINTN) DataPtr), Buffer, DataSize);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
// //
// If we are here we are dealing with Non-Volatile Variables // If we are here we are dealing with Non-Volatile Variables
// //
@ -211,9 +212,7 @@ Returns:
&CurrWriteSize, &CurrWriteSize,
CurrBuffer CurrBuffer
); );
if (EFI_ERROR (Status)) {
return Status; return Status;
}
} else { } else {
Size = (UINT32) (LinearOffset + PtrBlockMapEntry->Length - CurrWritePtr); Size = (UINT32) (LinearOffset + PtrBlockMapEntry->Length - CurrWritePtr);
Status = EfiFvbWriteBlock ( Status = EfiFvbWriteBlock (
@ -313,7 +312,6 @@ Returns:
STATIC STATIC
VARIABLE_HEADER * VARIABLE_HEADER *
EFIAPI
GetNextVariablePtr ( GetNextVariablePtr (
IN VARIABLE_HEADER *Variable IN VARIABLE_HEADER *Variable
) )
@ -553,7 +551,7 @@ Returns:
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) {
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]; PtrTrack->CurrPtr = Variable[Index];
PtrTrack->Volatile = (BOOLEAN) Index; PtrTrack->Volatile = (BOOLEAN) Index;
@ -587,11 +585,11 @@ EFI_STATUS
EFIAPI EFIAPI
GetVariable ( GetVariable (
IN CHAR16 *VariableName, IN CHAR16 *VariableName,
IN EFI_GUID * VendorGuid, IN EFI_GUID *VendorGuid,
OUT UINT32 *Attributes OPTIONAL, OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize, IN OUT UINTN *DataSize,
OUT VOID *Data, OUT VOID *Data,
IN VARIABLE_GLOBAL * Global, IN VARIABLE_GLOBAL *Global,
IN UINT32 Instance IN UINT32 Instance
) )
/*++ /*++
@ -602,18 +600,22 @@ Routine Description:
Arguments: Arguments:
VariableName Name of Variable to be found VariableName Name of Variable to be found
VendorGuid Variable vendor GUID VendorGuid Variable vendor GUID
Attributes OPTIONAL Attribute value of the variable found Attributes OPTIONAL Attribute value of the variable found
DataSize Size of Data found. If size is less than the DataSize Size of Data found. If size is less than the
data, this value contains the required size. data, this value contains the required size.
Data Data pointer Data Data pointer
Global Pointer to VARIABLE_GLOBAL structure Global Pointer to VARIABLE_GLOBAL structure
Instance Instance of the Firmware Volume. Instance Instance of the Firmware Volume.
Returns: Returns:
EFI STATUS EFI_INVALID_PARAMETER - Invalid parameter
EFI_SUCCESS - Find the specified variable
EFI_NOT_FOUND - Not found
EFI_BUFFER_TO_SMALL - DataSize is too small for the result
--*/ --*/
{ {
@ -800,11 +802,12 @@ Arguments:
Returns: Returns:
EFI STATUS
EFI_INVALID_PARAMETER - Invalid parameter EFI_INVALID_PARAMETER - Invalid parameter
EFI_SUCCESS - Set successfully EFI_SUCCESS - Set successfully
EFI_OUT_OF_RESOURCES - Resource not enough to set variable EFI_OUT_OF_RESOURCES - Resource not enough to set variable
EFI_NOT_FOUND - Not found EFI_NOT_FOUND - Not found
EFI_DEVICE_ERROR - Variable can not be saved due to hardware failure
EFI_WRITE_PROTECTED - Variable is read-only
--*/ --*/
{ {
@ -820,309 +823,339 @@ Returns:
Reclaimed = FALSE; Reclaimed = FALSE;
//
// Check input parameters
//
if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) { if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
}
//
// Make sure if runtime bit is set, boot service bit is set also
//
if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
return EFI_INVALID_PARAMETER;
} }
//
// The size of the VariableName, including the Unicode Null in bytes plus
// the DataSize is limited to maximum size of MAX_HARDWARE_ERROR_VARIABLE_SIZE (32K)
// bytes for HwErrRec, and MAX_VARIABLE_SIZE (1024) bytes for the others.
//
if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
if ((DataSize > MAX_HARDWARE_ERROR_VARIABLE_SIZE) ||
(sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > MAX_HARDWARE_ERROR_VARIABLE_SIZE)) {
return EFI_INVALID_PARAMETER;
}
} else {
//
// The size of the VariableName, including the Unicode Null in bytes plus
// the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes.
//
if ((DataSize > MAX_VARIABLE_SIZE) ||
(sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > MAX_VARIABLE_SIZE)) {
return EFI_INVALID_PARAMETER;
}
}
//
// Check whether the input variable is already existed
//
Status = FindVariable (VariableName, VendorGuid, &Variable, Global); Status = FindVariable (VariableName, VendorGuid, &Variable, Global);
if (Status == EFI_INVALID_PARAMETER) { if (Status == EFI_SUCCESS && Variable.CurrPtr != NULL) {
goto Done;
} else if (!EFI_ERROR (Status) && Variable.Volatile && EfiAtRuntime()) {
// //
// If EfiAtRuntime and the variable is Volatile and Runtime Access, // Update/Delete existing variable
// the volatile is ReadOnly, and SetVariable should be aborted and
// return EFI_WRITE_PROTECTED.
// //
Status = EFI_WRITE_PROTECTED;
goto Done; if (EfiAtRuntime ()) {
} else if (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > MAX_VARIABLE_SIZE) { //
// // If EfiAtRuntime and the variable is Volatile and Runtime Access,
// The size of the VariableName, including the Unicode Null in bytes plus // the volatile is ReadOnly, and SetVariable should be aborted and
// the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes. // return EFI_WRITE_PROTECTED.
// //
Status = EFI_INVALID_PARAMETER; if (Variable.Volatile) {
goto Done; Status = EFI_WRITE_PROTECTED;
} else if (Attributes == EFI_VARIABLE_NON_VOLATILE) { goto Done;
// }
// Make sure not only EFI_VARIABLE_NON_VOLATILE is set //
// // Only variable have NV attribute can be updated/deleted in Runtime
Status = EFI_INVALID_PARAMETER; //
goto Done; if (!(Variable.CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE)) {
} else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == Status = EFI_INVALID_PARAMETER;
EFI_VARIABLE_RUNTIME_ACCESS) { goto Done;
// }
// Make sure if runtime bit is set, boot service bit is set also }
//
Status = EFI_INVALID_PARAMETER;
goto Done;
} else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
//
// Runtime but Attribute is not Runtime
//
Status = EFI_INVALID_PARAMETER;
goto Done;
} else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {
//
// Cannot set volatile variable in Runtime
//
Status = EFI_INVALID_PARAMETER;
goto Done;
} else if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {
// //
// Setting a data variable with no access, or zero DataSize attributes // Setting a data variable with no access, or zero DataSize attributes
// specified causes it to be deleted. // specified causes it to be deleted.
// //
if (!EFI_ERROR (Status)) { if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {
State = Variable.CurrPtr->State; State = Variable.CurrPtr->State;
State &= VAR_DELETED; State &= VAR_DELETED;
Status = UpdateVariableStore ( Status = UpdateVariableStore (
Global, Global,
Variable.Volatile, Variable.Volatile,
FALSE, FALSE,
Instance, Instance,
(UINTN) &Variable.CurrPtr->State, (UINTN) &Variable.CurrPtr->State,
sizeof (UINT8), sizeof (UINT8),
&State &State
); );
goto Done;
}
//
// If the variable is marked valid and the same data has been passed in
// then return to the caller immediately.
//
if (Variable.CurrPtr->DataSize == DataSize &&
(CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize) == 0)) {
Status = EFI_SUCCESS;
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
//
State = Variable.CurrPtr->State;
State &= VAR_IN_DELETED_TRANSITION;
Status = UpdateVariableStore (
Global,
Variable.Volatile,
FALSE,
Instance,
(UINTN) &Variable.CurrPtr->State,
sizeof (UINT8),
&State
);
if (EFI_ERROR (Status)) {
goto Done;
}
}
} else if (Status == EFI_NOT_FOUND) {
//
// Create a new variable
//
//
// Make sure we are trying to create a new variable.
// Setting a data variable with no access, or zero DataSize attributes means to delete it.
//
if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {
Status = EFI_NOT_FOUND;
goto Done;
}
//
// Only variable have NV|RT attribute can be created in Runtime
//
if (EfiAtRuntime () &&
(!(Attributes & EFI_VARIABLE_RUNTIME_ACCESS) || !(Attributes & EFI_VARIABLE_NON_VOLATILE))) {
Status = EFI_INVALID_PARAMETER;
goto Done;
}
} else {
//
// Status should be EFI_INVALID_PARAMETER here according to return status of FindVariable().
//
ASSERT (Status == EFI_INVALID_PARAMETER);
goto Done;
}
//
// Function part - create a new variable and copy the data.
// Both update a variable and create a variable will come here.
//
// Tricky part: Use scratch data area at the end of volatile variable store
// as a temporary storage.
//
NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));
SetMem (NextVariable, SCRATCH_SIZE, 0xff);
NextVariable->StartId = VARIABLE_DATA;
NextVariable->Attributes = Attributes;
//
// NextVariable->State = VAR_ADDED;
//
NextVariable->Reserved = 0;
VarNameOffset = sizeof (VARIABLE_HEADER);
VarNameSize = StrSize (VariableName);
CopyMem (
(UINT8 *) ((UINTN) NextVariable + VarNameOffset),
VariableName,
VarNameSize
);
VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize);
CopyMem (
(UINT8 *) ((UINTN) NextVariable + VarDataOffset),
Data,
DataSize
);
CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));
//
// There will be pad bytes after Data, the NextVariable->NameSize and
// NextVariable->DataSize should not include pad size so that variable
// service can get actual size in GetVariable
//
NextVariable->NameSize = (UINT32)VarNameSize;
NextVariable->DataSize = (UINT32)DataSize;
//
// The actual size of the variable that stores in storage should
// include pad size.
//
VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize);
if (Attributes & EFI_VARIABLE_NON_VOLATILE) {
//
// Create a nonvolatile variable
//
if ((UINT32) (VarSize +*NonVolatileOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size
) {
if (EfiAtRuntime ()) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
//
// Perform garbage collection & reclaim operation
//
Status = Reclaim (Global->NonVolatileVariableBase, NonVolatileOffset, FALSE);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto Done; goto Done;
} }
Status = EFI_SUCCESS;
goto Done;
}
Status = EFI_NOT_FOUND;
goto Done;
} else {
if (!EFI_ERROR (Status)) {
// //
// If the variable is marked valid and the same data has been passed in // If still no enough space, return out of resources
// then return to the caller immediately.
// //
if (Variable.CurrPtr->DataSize == DataSize &&
!CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize)
) {
Status = EFI_SUCCESS;
goto Done;
} else if (Variable.CurrPtr->State == VAR_ADDED) {
//
// Mark the old variable as in delete transition
//
State = Variable.CurrPtr->State;
State &= VAR_IN_DELETED_TRANSITION;
Status = UpdateVariableStore (
Global,
Variable.Volatile,
FALSE,
Instance,
(UINTN) &Variable.CurrPtr->State,
sizeof (UINT8),
&State
);
if (EFI_ERROR (Status)) {
goto Done;
}
}
}
//
// Create a new variable and copy the data.
//
// Tricky part: Use scratch data area at the end of volatile variable store
// as a temporary storage.
//
NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));
SetMem (NextVariable, SCRATCH_SIZE, 0xff);
NextVariable->StartId = VARIABLE_DATA;
NextVariable->Attributes = Attributes;
//
// NextVariable->State = VAR_ADDED;
//
NextVariable->Reserved = 0;
VarNameOffset = sizeof (VARIABLE_HEADER);
VarNameSize = StrSize (VariableName);
CopyMem (
(UINT8 *) ((UINTN) NextVariable + VarNameOffset),
VariableName,
VarNameSize
);
VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize);
CopyMem (
(UINT8 *) ((UINTN) NextVariable + VarDataOffset),
Data,
DataSize
);
CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));
//
// There will be pad bytes after Data, the NextVariable->NameSize and
// NextVariable->DataSize should not include pad size so that variable
// service can get actual size in GetVariable
//
NextVariable->NameSize = (UINT32)VarNameSize;
NextVariable->DataSize = (UINT32)DataSize;
//
// The actual size of the variable that stores in storage should
// include pad size.
//
VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize);
if (Attributes & EFI_VARIABLE_NON_VOLATILE) {
if ((UINT32) (VarSize +*NonVolatileOffset) > if ((UINT32) (VarSize +*NonVolatileOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size
) { ) {
if (EfiAtRuntime ()) { Status = EFI_OUT_OF_RESOURCES;
Status = EFI_OUT_OF_RESOURCES; goto Done;
goto Done;
}
//
// Perform garbage collection & reclaim operation
//
Status = Reclaim (Global->NonVolatileVariableBase, NonVolatileOffset, FALSE);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// If still no enough space, return out of resources
//
if ((UINT32) (VarSize +*NonVolatileOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size
) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
Reclaimed = TRUE;
} }
//
// Three steps Reclaimed = TRUE;
// 1. Write variable header }
// 2. Write variable data //
// 3. Set variable state to valid // Three steps
// // 1. Write variable header
// // 2. Write variable data
// Step 1: // 3. Set variable state to valid
// //
Status = UpdateVariableStore ( //
Global, // Step 1:
FALSE, //
TRUE, Status = UpdateVariableStore (
Instance, Global,
*NonVolatileOffset, FALSE,
sizeof (VARIABLE_HEADER), TRUE,
(UINT8 *) NextVariable Instance,
); *NonVolatileOffset,
sizeof (VARIABLE_HEADER),
(UINT8 *) NextVariable
);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// Step 2:
//
Status = UpdateVariableStore (
Global,
FALSE,
TRUE,
Instance,
*NonVolatileOffset + sizeof (VARIABLE_HEADER),
(UINT32) VarSize - sizeof (VARIABLE_HEADER),
(UINT8 *) NextVariable + sizeof (VARIABLE_HEADER)
);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// Step 3:
//
NextVariable->State = VAR_ADDED;
Status = UpdateVariableStore (
Global,
FALSE,
TRUE,
Instance,
*NonVolatileOffset,
sizeof (VARIABLE_HEADER),
(UINT8 *) NextVariable
);
if (EFI_ERROR (Status)) {
goto Done;
}
*NonVolatileOffset = *NonVolatileOffset + VarSize;
} else {
//
// Create a volatile variable
//
if ((UINT32) (VarSize +*VolatileOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size) {
//
// Perform garbage collection & reclaim operation
//
Status = Reclaim (Global->VolatileVariableBase, VolatileOffset, TRUE);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto Done; goto Done;
} }
// //
// Step 2: // If still no enough space, return out of resources
// //
Status = UpdateVariableStore (
Global,
FALSE,
TRUE,
Instance,
*NonVolatileOffset + sizeof (VARIABLE_HEADER),
(UINT32) VarSize - sizeof (VARIABLE_HEADER),
(UINT8 *) NextVariable + sizeof (VARIABLE_HEADER)
);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// Step 3:
//
NextVariable->State = VAR_ADDED;
Status = UpdateVariableStore (
Global,
FALSE,
TRUE,
Instance,
*NonVolatileOffset,
sizeof (VARIABLE_HEADER),
(UINT8 *) NextVariable
);
if (EFI_ERROR (Status)) {
goto Done;
}
*NonVolatileOffset = *NonVolatileOffset + VarSize;
} else {
if (EfiAtRuntime ()) {
Status = EFI_INVALID_PARAMETER;
goto Done;
}
if ((UINT32) (VarSize +*VolatileOffset) > if ((UINT32) (VarSize +*VolatileOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size
) { ) {
// Status = EFI_OUT_OF_RESOURCES;
// Perform garbage collection & reclaim operation
//
Status = Reclaim (Global->VolatileVariableBase, VolatileOffset, TRUE);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// If still no enough space, return out of resources
//
if ((UINT32) (VarSize +*VolatileOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size
) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
Reclaimed = TRUE;
}
NextVariable->State = VAR_ADDED;
Status = UpdateVariableStore (
Global,
TRUE,
TRUE,
Instance,
*VolatileOffset,
(UINT32) VarSize,
(UINT8 *) NextVariable
);
if (EFI_ERROR (Status)) {
goto Done; goto Done;
} }
*VolatileOffset = *VolatileOffset + VarSize; Reclaimed = TRUE;
} }
//
// Mark the old variable as deleted
//
if (!Reclaimed && !EFI_ERROR (Status) && Variable.CurrPtr != NULL) {
State = Variable.CurrPtr->State;
State &= VAR_DELETED;
Status = UpdateVariableStore ( NextVariable->State = VAR_ADDED;
Global, Status = UpdateVariableStore (
Variable.Volatile, Global,
FALSE, TRUE,
Instance, TRUE,
(UINTN) &Variable.CurrPtr->State, Instance,
sizeof (UINT8), *VolatileOffset,
&State (UINT32) VarSize,
); (UINT8 *) NextVariable
);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto Done; goto Done;
}
} }
*VolatileOffset = *VolatileOffset + VarSize;
}
//
// Mark the old variable as deleted
//
if (!Reclaimed && !EFI_ERROR (Status) && Variable.CurrPtr != NULL) {
State = Variable.CurrPtr->State;
State &= VAR_DELETED;
Status = UpdateVariableStore (
Global,
Variable.Volatile,
FALSE,
Instance,
(UINTN) &Variable.CurrPtr->State,
sizeof (UINT8),
&State
);
goto Done;
} }
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
@ -1154,8 +1187,8 @@ Arguments:
MaximumVariableStorageSize Pointer to the maximum size of the storage space available MaximumVariableStorageSize Pointer to the maximum size of the storage space available
for the EFI variables associated with the attributes specified. for the EFI variables associated with the attributes specified.
RemainingVariableStorageSize Pointer to the remaining size of the storage space available RemainingVariableStorageSize Pointer to the remaining size of the storage space available
for the EFI variables associated with the attributes specified. for EFI variables associated with the attributes specified.
MaximumVariableSize Pointer to the maximum size of the individual EFI variables MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified. associated with the attributes specified.
Global Pointer to VARIABLE_GLOBAL structure. Global Pointer to VARIABLE_GLOBAL structure.
Instance Instance of the Firmware Volume. Instance Instance of the Firmware Volume.
@ -1174,15 +1207,15 @@ Returns:
UINT64 VariableSize; UINT64 VariableSize;
VARIABLE_STORE_HEADER *VariableStoreHeader; VARIABLE_STORE_HEADER *VariableStoreHeader;
if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL) { if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)) == 0) { if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
// //
// Make sure the Attributes combination is supported by the platform. // Make sure the Attributes combination is supported by the platform.
// //
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) { } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
// //
// Make sure if runtime bit is set, boot service bit is set also. // Make sure if runtime bit is set, boot service bit is set also.
@ -1217,9 +1250,16 @@ Returns:
*RemainingVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER); *RemainingVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER);
// //
// Let *MaximumVariableSize be MAX_VARIABLE_SIZE. // Let *MaximumVariableSize be MAX_VARIABLE_SIZE with the exception of the variable header size.
// //
*MaximumVariableSize = MAX_VARIABLE_SIZE; *MaximumVariableSize = MAX_VARIABLE_SIZE - sizeof (VARIABLE_HEADER);
//
// Harware error record variable needs larger size.
//
if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
*MaximumVariableSize = MAX_HARDWARE_ERROR_VARIABLE_SIZE - sizeof (VARIABLE_HEADER);
}
// //
// Point to the starting address of the variables. // Point to the starting address of the variables.
@ -1257,6 +1297,12 @@ Returns:
Variable = NextVariable; Variable = NextVariable;
} }
if (*RemainingVariableStorageSize < sizeof (VARIABLE_HEADER)) {
*MaximumVariableSize = 0;
} else if ((*RemainingVariableStorageSize - sizeof (VARIABLE_HEADER)) < *MaximumVariableSize) {
*MaximumVariableSize = *RemainingVariableStorageSize - sizeof (VARIABLE_HEADER);
}
ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -1295,9 +1341,7 @@ Returns:
VARIABLE_HEADER *NextVariable; VARIABLE_HEADER *NextVariable;
UINT32 Instance; UINT32 Instance;
EFI_PHYSICAL_ADDRESS FvVolHdr; EFI_PHYSICAL_ADDRESS FvVolHdr;
UINT64 TempVariableStoreHeader; UINT64 TempVariableStoreHeader;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
EFI_FLASH_SUBAREA_ENTRY VariableStoreEntry; EFI_FLASH_SUBAREA_ENTRY VariableStoreEntry;
UINT64 BaseAddress; UINT64 BaseAddress;