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:
parent
4aad654298
commit
c649283953
|
@ -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
|
||||||
|
|
|
@ -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,63 +480,78 @@ 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()) {
|
// Update/Delete existing variable
|
||||||
|
//
|
||||||
|
|
||||||
|
if (EfiAtRuntime ()) {
|
||||||
//
|
//
|
||||||
// If EfiAtRuntime and the variable is Volatile and Runtime Access,
|
// If EfiAtRuntime and the variable is Volatile and Runtime Access,
|
||||||
// the volatile is ReadOnly, and SetVariable should be aborted and
|
// the volatile is ReadOnly, and SetVariable should be aborted and
|
||||||
// return EFI_WRITE_PROTECTED.
|
// return EFI_WRITE_PROTECTED.
|
||||||
//
|
//
|
||||||
|
if (Variable.Volatile) {
|
||||||
Status = EFI_WRITE_PROTECTED;
|
Status = EFI_WRITE_PROTECTED;
|
||||||
goto Done;
|
goto Done;
|
||||||
} else if (sizeof (VARIABLE_HEADER) + (StrSize (VariableName) + DataSize) > MAX_VARIABLE_SIZE) {
|
}
|
||||||
//
|
//
|
||||||
// The size of the VariableName, including the Unicode Null in bytes plus
|
// Only variable have NV attribute can be updated/deleted in Runtime
|
||||||
// the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes.
|
|
||||||
//
|
//
|
||||||
|
if (!(Variable.CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE)) {
|
||||||
Status = EFI_INVALID_PARAMETER;
|
Status = EFI_INVALID_PARAMETER;
|
||||||
goto Done;
|
goto Done;
|
||||||
} 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
|
|
||||||
//
|
|
||||||
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) {
|
||||||
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;
|
|
||||||
} else {
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
//
|
//
|
||||||
// If the variable is marked valid and the same data has been passed in
|
// If the variable is marked valid and the same data has been passed in
|
||||||
// then return to the caller immediately.
|
// then return to the caller immediately.
|
||||||
|
@ -547,10 +567,42 @@ Returns:
|
||||||
//
|
//
|
||||||
Variable.CurrPtr->State &= VAR_IN_DELETED_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create a new variable and copy the data.
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
VarNameOffset = sizeof (VARIABLE_HEADER);
|
VarNameOffset = sizeof (VARIABLE_HEADER);
|
||||||
VarNameSize = StrSize (VariableName);
|
VarNameSize = StrSize (VariableName);
|
||||||
VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize);
|
VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize);
|
||||||
|
@ -567,11 +619,6 @@ Returns:
|
||||||
NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*NonVolatileOffset + (UINTN) Global->NonVolatileVariableBase);
|
NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*NonVolatileOffset + (UINTN) Global->NonVolatileVariableBase);
|
||||||
*NonVolatileOffset = *NonVolatileOffset + VarSize;
|
*NonVolatileOffset = *NonVolatileOffset + VarSize;
|
||||||
} else {
|
} 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
|
||||||
) {
|
) {
|
||||||
|
@ -614,7 +661,6 @@ Returns:
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
Variable.CurrPtr->State &= VAR_DELETED;
|
Variable.CurrPtr->State &= VAR_DELETED;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
Done:
|
Done:
|
||||||
|
@ -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,11 +711,11 @@ 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.
|
||||||
//
|
//
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
/*++
|
/*++
|
||||||
|
@ -613,7 +611,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
|
||||||
|
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
|
@ -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,60 +823,72 @@ 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()) {
|
// Update/Delete existing variable
|
||||||
|
//
|
||||||
|
|
||||||
|
if (EfiAtRuntime ()) {
|
||||||
//
|
//
|
||||||
// If EfiAtRuntime and the variable is Volatile and Runtime Access,
|
// If EfiAtRuntime and the variable is Volatile and Runtime Access,
|
||||||
// the volatile is ReadOnly, and SetVariable should be aborted and
|
// the volatile is ReadOnly, and SetVariable should be aborted and
|
||||||
// return EFI_WRITE_PROTECTED.
|
// return EFI_WRITE_PROTECTED.
|
||||||
//
|
//
|
||||||
|
if (Variable.Volatile) {
|
||||||
Status = EFI_WRITE_PROTECTED;
|
Status = EFI_WRITE_PROTECTED;
|
||||||
goto Done;
|
goto Done;
|
||||||
} else if (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > MAX_VARIABLE_SIZE) {
|
}
|
||||||
//
|
//
|
||||||
// The size of the VariableName, including the Unicode Null in bytes plus
|
// Only variable have NV attribute can be updated/deleted in Runtime
|
||||||
// the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes.
|
|
||||||
//
|
//
|
||||||
|
if (!(Variable.CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE)) {
|
||||||
Status = EFI_INVALID_PARAMETER;
|
Status = EFI_INVALID_PARAMETER;
|
||||||
goto Done;
|
goto Done;
|
||||||
} else if (Attributes == EFI_VARIABLE_NON_VOLATILE) {
|
}
|
||||||
//
|
}
|
||||||
// Make sure not only EFI_VARIABLE_NON_VOLATILE is set
|
|
||||||
//
|
|
||||||
Status = EFI_INVALID_PARAMETER;
|
|
||||||
goto Done;
|
|
||||||
} 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
|
|
||||||
//
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -886,28 +901,18 @@ Returns:
|
||||||
sizeof (UINT8),
|
sizeof (UINT8),
|
||||||
&State
|
&State
|
||||||
);
|
);
|
||||||
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 the variable is marked valid and the same data has been passed in
|
||||||
// then return to the caller immediately.
|
// then return to the caller immediately.
|
||||||
//
|
//
|
||||||
if (Variable.CurrPtr->DataSize == DataSize &&
|
if (Variable.CurrPtr->DataSize == DataSize &&
|
||||||
!CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize)
|
(CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize) == 0)) {
|
||||||
) {
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
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))) {
|
||||||
//
|
//
|
||||||
// Mark the old variable as in delete transition
|
// Mark the old variable as in delete transition
|
||||||
//
|
//
|
||||||
|
@ -927,9 +932,39 @@ Returns:
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (Status == EFI_NOT_FOUND) {
|
||||||
//
|
//
|
||||||
// Create a new variable and copy the data.
|
// 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
|
// Tricky part: Use scratch data area at the end of volatile variable store
|
||||||
// as a temporary storage.
|
// as a temporary storage.
|
||||||
|
@ -972,6 +1007,10 @@ Returns:
|
||||||
//
|
//
|
||||||
VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize);
|
VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize);
|
||||||
if (Attributes & EFI_VARIABLE_NON_VOLATILE) {
|
if (Attributes & EFI_VARIABLE_NON_VOLATILE) {
|
||||||
|
//
|
||||||
|
// Create a nonvolatile variable
|
||||||
|
//
|
||||||
|
|
||||||
if ((UINT32) (VarSize +*NonVolatileOffset) >
|
if ((UINT32) (VarSize +*NonVolatileOffset) >
|
||||||
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size
|
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size
|
||||||
) {
|
) {
|
||||||
|
@ -1057,14 +1096,12 @@ Returns:
|
||||||
*NonVolatileOffset = *NonVolatileOffset + VarSize;
|
*NonVolatileOffset = *NonVolatileOffset + VarSize;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (EfiAtRuntime ()) {
|
//
|
||||||
Status = EFI_INVALID_PARAMETER;
|
// Create a volatile variable
|
||||||
goto Done;
|
//
|
||||||
}
|
|
||||||
|
|
||||||
if ((UINT32) (VarSize +*VolatileOffset) >
|
if ((UINT32) (VarSize +*VolatileOffset) >
|
||||||
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size
|
((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size) {
|
||||||
) {
|
|
||||||
//
|
//
|
||||||
// Perform garbage collection & reclaim operation
|
// Perform garbage collection & reclaim operation
|
||||||
//
|
//
|
||||||
|
@ -1118,12 +1155,8 @@ Returns:
|
||||||
sizeof (UINT8),
|
sizeof (UINT8),
|
||||||
&State
|
&State
|
||||||
);
|
);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
Done:
|
Done:
|
||||||
|
@ -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,11 +1207,11 @@ 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.
|
||||||
//
|
//
|
||||||
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue