diff options
-rw-r--r-- | MdeModulePkg/MdeModulePkg.dec | 27 | ||||
-rw-r--r-- | MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c | 138 | ||||
-rw-r--r-- | MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h | 2 | ||||
-rw-r--r-- | MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf | 1 |
4 files changed, 131 insertions, 37 deletions
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 366a4be8d9..a5e348f95b 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -268,21 +268,32 @@ ## Maximum PPI count is supported by PeiCore's PPI database.
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPpiSupported|64|UINT32|0x00010033
- ## Size of the NV variable range.
+ ## Size of the NV variable range. Note that this value should less than or equal to PcdFlashNvStorageFtwSpareSize
+ # The root cause is that variable driver will use FTW protocol to reclaim variable region.
+ # If the length of variable region is larger than FTW spare size, it means the whole variable region can not
+ # be reflushed through the manner of fault tolerant write.
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x0|UINT32|0x30000002
- ## Maximum allowable size of a common type variable, that is, non-hardware error type variable.
+ ## The maximum size of single common variable, that is non-HwErr type varible.
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x400|UINT32|0x30000003
- ## Maximum allowable size of a single hardware error record variable.
+ ## The maximum size of single hardware error record variable.
+ # In IA32/X64 platforms, this value should be larger than 1KB.
+ # In IA64 platforms, this value should be larger than 128KB.
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000|UINT32|0x30000004
- ## Size of allocated memory for volatile variable store. Variables are stored in such region and
- # total length of all variables should not larger than this value.
- ##
+ ## The size of reserved HwErr variable space. This space is located at NV variable range.
+ # HwErr type variable is stored with common non-volatile variables in NV region.
+ # this value is used to guarantee the space of HwErr type variable and not populated by common variable.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x8000|UINT32|0x30000006
+
+ ## The size of volatile buffer. This buffer is used to store VOLATILE attribute variable.
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x10000|UINT32|0x30000005
-
- ## Size of the FTW spare block range.
+
+ ## Size of the FTW spare block range. Note that this value should larger than PcdFlashNvStorageVariableSize
+ # The root cause is that variable driver will use FTW protocol to reclaim variable region.
+ # If the length of variable region is larger than FTW spare size, it means the whole variable region can not
+ # be reflushed through the manner of fault tolerant write.
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x0|UINT32|0x30000014
## Size of the FTW working block range.
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c index 0e5735e941..62025c9ee1 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -596,6 +596,13 @@ Reclaim ( CHAR16 *UpdatingVariableNamePtr;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
+ //
+ // recaluate the total size of Common/HwErr type variables in non-volatile area.
+ //
+ if (!IsVolatile) {
+ mVariableModuleGlobal->CommonVariableTotalSize = 0;
+ mVariableModuleGlobal->HwErrVariableTotalSize = 0;
+ }
//
// Start Pointers for the variable.
@@ -661,6 +668,11 @@ Reclaim ( VariableSize = (UINTN) NextVariable - (UINTN) Variable;
CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
CurrPtr += VariableSize;
+ if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+ mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize;
+ } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+ mVariableModuleGlobal->CommonVariableTotalSize += VariableSize;
+ }
}
Variable = NextVariable;
}
@@ -672,6 +684,11 @@ Reclaim ( VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - (UINTN)UpdatingVariable;
CopyMem (CurrPtr, (UINT8 *) UpdatingVariable, VariableSize);
CurrPtr += VariableSize;
+ if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+ mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize;
+ } else if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+ mVariableModuleGlobal->CommonVariableTotalSize += VariableSize;
+ }
}
//
@@ -713,6 +730,11 @@ Reclaim ( CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED;
CurrPtr += VariableSize;
+ if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+ mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize;
+ } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+ mVariableModuleGlobal->CommonVariableTotalSize += VariableSize;
+ }
}
}
@@ -1216,6 +1238,8 @@ RuntimeServiceSetVariable ( EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
BOOLEAN Volatile;
EFI_PHYSICAL_ADDRESS Point;
+ UINTN ScratchSize;
+ UINTN NonVolatileVarableStoreSize;
//
// Check input parameters
@@ -1397,8 +1421,9 @@ RuntimeServiceSetVariable ( // as a temporary storage.
//
NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));
+ ScratchSize = MAX(FixedPcdGet32(PcdMaxVariableSize), FixedPcdGet32(PcdMaxHardwareErrorVariableSize));
- SetMem (NextVariable, FixedPcdGet32(PcdMaxVariableSize), 0xff);
+ SetMem (NextVariable, ScratchSize, 0xff);
NextVariable->StartId = VARIABLE_DATA;
NextVariable->Attributes = Attributes;
@@ -1438,10 +1463,11 @@ RuntimeServiceSetVariable ( // Create a nonvolatile variable
//
Volatile = FALSE;
-
- if ((UINT32) (VarSize +*NonVolatileOffset) >
- ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase)))->Size
- ) {
+ NonVolatileVarableStoreSize = ((VARIABLE_STORE_HEADER *)(UINTN)(mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase))->Size;
+ if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0)
+ && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > FixedPcdGet32(PcdHwErrStorageSize)))
+ || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0)
+ && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - FixedPcdGet32(PcdHwErrStorageSize)))) {
if (EfiAtRuntime ()) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
@@ -1456,9 +1482,10 @@ RuntimeServiceSetVariable ( //
// If still no enough space, return out of resources
//
- if ((UINT32) (VarSize +*NonVolatileOffset) >
- ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase)))->Size
- ) {
+ if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0)
+ && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > FixedPcdGet32(PcdHwErrStorageSize)))
+ || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0)
+ && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - FixedPcdGet32(PcdHwErrStorageSize)))) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
@@ -1542,6 +1569,11 @@ RuntimeServiceSetVariable ( *NonVolatileOffset = HEADER_ALIGN (*NonVolatileOffset + VarSize);
+ if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) {
+ mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VarSize);
+ } else {
+ mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VarSize);
+ }
} else {
//
// Create a volatile variable
@@ -1653,11 +1685,16 @@ RuntimeServiceQueryVariableInfo ( VARIABLE_HEADER *NextVariable;
UINT64 VariableSize;
VARIABLE_STORE_HEADER *VariableStoreHeader;
+ UINT64 CommonVariableTotalSize;
+ UINT64 HwErrVariableTotalSize;
+
+ CommonVariableTotalSize = 0;
+ HwErrVariableTotalSize = 0;
if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
return EFI_INVALID_PARAMETER;
}
-
+
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.
@@ -1673,6 +1710,11 @@ RuntimeServiceQueryVariableInfo ( // Make sure RT Attribute is set if we are in Runtime phase.
//
return EFI_INVALID_PARAMETER;
+ } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ //
+ // Make sure Hw Attribute is set with NV.
+ //
+ return EFI_INVALID_PARAMETER;
}
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
@@ -1694,18 +1736,23 @@ RuntimeServiceQueryVariableInfo ( // with the storage size (excluding the storage header size).
//
*MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER);
- *RemainingVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER);
-
- //
- // Let *MaximumVariableSize be FixedPcdGet32(PcdMaxVariableSize) with the exception of the variable header size.
- //
- *MaximumVariableSize = FixedPcdGet32(PcdMaxVariableSize) - sizeof (VARIABLE_HEADER);
//
// Harware error record variable needs larger size.
//
- if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+ *MaximumVariableStorageSize = FixedPcdGet32(PcdHwErrStorageSize);
*MaximumVariableSize = FixedPcdGet32(PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER);
+ } else {
+ if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
+ ASSERT (FixedPcdGet32(PcdHwErrStorageSize) < VariableStoreHeader->Size);
+ *MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - FixedPcdGet32(PcdHwErrStorageSize);
+ }
+
+ //
+ // Let *MaximumVariableSize be FixedPcdGet32(PcdMaxVariableSize) with the exception of the variable header size.
+ //
+ *MaximumVariableSize = FixedPcdGet32(PcdMaxVariableSize) - sizeof (VARIABLE_HEADER);
}
//
@@ -1727,14 +1774,22 @@ RuntimeServiceQueryVariableInfo ( // since the space occupied by variables not marked with
// VAR_ADDED is not allowed to be reclaimed in Runtime.
//
- *RemainingVariableStorageSize -= VariableSize;
+ if ((NextVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ HwErrVariableTotalSize += VariableSize;
+ } else {
+ CommonVariableTotalSize += VariableSize;
+ }
} else {
//
// Only care about Variables with State VAR_ADDED,because
// the space not marked as VAR_ADDED is reclaimable now.
//
if (Variable->State == VAR_ADDED) {
- *RemainingVariableStorageSize -= VariableSize;
+ if ((NextVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ HwErrVariableTotalSize += VariableSize;
+ } else {
+ CommonVariableTotalSize += VariableSize;
+ }
}
}
@@ -1744,6 +1799,12 @@ RuntimeServiceQueryVariableInfo ( Variable = NextVariable;
}
+ if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD){
+ *RemainingVariableStorageSize = *MaximumVariableStorageSize - HwErrVariableTotalSize;
+ }else {
+ *RemainingVariableStorageSize = *MaximumVariableStorageSize - CommonVariableTotalSize;
+ }
+
if (*RemainingVariableStorageSize < sizeof (VARIABLE_HEADER)) {
*MaximumVariableSize = 0;
} else if ((*RemainingVariableStorageSize - sizeof (VARIABLE_HEADER)) < *MaximumVariableSize) {
@@ -1773,22 +1834,29 @@ ReclaimForOS( VOID *Context
)
{
- UINT32 VarSize;
EFI_STATUS Status;
+ UINTN CommonVariableSpace;
+ UINTN RemainingCommonVariableSpace;
+ UINTN RemainingHwErrVariableSpace;
- VarSize = ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase))->Size;
Status = EFI_SUCCESS;
+ CommonVariableSpace = ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase)))->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32(PcdHwErrStorageSize); //Allowable max size of common variable storage space
+
+ RemainingCommonVariableSpace = CommonVariableSpace - mVariableModuleGlobal->CommonVariableTotalSize;
+
+ RemainingHwErrVariableSpace = PcdGet32 (PcdHwErrStorageSize) - mVariableModuleGlobal->HwErrVariableTotalSize;
//
// Check if the free area is blow a threshold
//
- if ((VarSize - mVariableModuleGlobal->NonVolatileLastVariableOffset) < VARIABLE_RECLAIM_THRESHOLD) {
+ if ((RemainingCommonVariableSpace < PcdGet32 (PcdMaxVariableSize))
+ || (RemainingHwErrVariableSpace < PcdGet32 (PcdMaxHardwareErrorVariableSize))){
Status = Reclaim (
- mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
- &mVariableModuleGlobal->NonVolatileLastVariableOffset,
- FALSE,
- NULL
- );
+ mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
+ &mVariableModuleGlobal->NonVolatileLastVariableOffset,
+ FALSE,
+ NULL
+ );
ASSERT_EFI_ERROR (Status);
}
}
@@ -1820,6 +1888,7 @@ VariableCommonInitialize ( EFI_PHYSICAL_ADDRESS VariableStoreBase;
UINT64 VariableStoreLength;
EFI_EVENT ReadyToBootEvent;
+ UINTN ScratchSize;
Status = EFI_SUCCESS;
//
@@ -1832,17 +1901,20 @@ VariableCommonInitialize ( EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock, TPL_NOTIFY);
mVariableModuleGlobal->VariableGlobal.ReentrantState = 0;
+ mVariableModuleGlobal->CommonVariableTotalSize = 0;
+ mVariableModuleGlobal->HwErrVariableTotalSize = 0;
//
- // Allocate memory for volatile variable store
+ // Allocate memory for volatile variable store, note that there is a scratch space to store scratch data.
//
- VolatileVariableStore = AllocateRuntimePool (FixedPcdGet32(PcdVariableStoreSize) + FixedPcdGet32(PcdMaxVariableSize));
+ ScratchSize = MAX(FixedPcdGet32(PcdMaxVariableSize), FixedPcdGet32(PcdMaxHardwareErrorVariableSize));
+ VolatileVariableStore = AllocateRuntimePool (FixedPcdGet32(PcdVariableStoreSize) + ScratchSize);
if (VolatileVariableStore == NULL) {
FreePool (mVariableModuleGlobal);
return EFI_OUT_OF_RESOURCES;
}
- SetMem (VolatileVariableStore, FixedPcdGet32(PcdVariableStoreSize) + FixedPcdGet32(PcdMaxVariableSize), 0xff);
+ SetMem (VolatileVariableStore, FixedPcdGet32(PcdVariableStoreSize) + ScratchSize, 0xff);
//
// Variable Specific Data
@@ -1925,6 +1997,14 @@ VariableCommonInitialize ( Status = EFI_SUCCESS;
while (IsValidVariableHeader (NextVariable)) {
+ UINTN VariableSize = 0;
+ VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);
+ if ((NextVariable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+ mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);
+ } else {
+ mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);
+ }
+
NextVariable = GetNextVariablePtr (NextVariable);
}
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h index 41b4a95e26..85e7f70ed5 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h @@ -57,6 +57,8 @@ typedef struct { VARIABLE_GLOBAL VariableGlobal;
UINTN VolatileLastVariableOffset;
UINTN NonVolatileLastVariableOffset;
+ UINTN CommonVariableTotalSize;
+ UINTN HwErrVariableTotalSize;
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbInstance;
} VARIABLE_MODULE_GLOBAL;
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf index be9385fe5b..64246a707f 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -69,6 +69,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
[FeaturePcd.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)
|