summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal
diff options
context:
space:
mode:
authoreric_tian <eric_tian@6f19259b-4bc3-4df7-8a09-765794883524>2009-04-07 06:42:12 +0000
committereric_tian <eric_tian@6f19259b-4bc3-4df7-8a09-765794883524>2009-04-07 06:42:12 +0000
commit2fcdca1d73deaaae32ba75223b102194e9382a82 (patch)
tree05a2e0ef9b1d54e8a7d59eb90c62b379833f476e /MdeModulePkg/Universal
parent8a67d804b3b660b233ba58e24fee81c76786001b (diff)
downloadedk2-2fcdca1d73deaaae32ba75223b102194e9382a82.zip
edk2-2fcdca1d73deaaae32ba75223b102194e9382a82.tar.gz
edk2-2fcdca1d73deaaae32ba75223b102194e9382a82.tar.bz2
1. The original code has a bug on calculate the size of SCRATCH_SIZE. It should be maximum value between PcdMaxVariableSize and PcdMaxHardwareErrorVariableSize.
2. Boot time variable reclaim issue is caused by incorrect flash layout. Platform integrator should ensure that the size of variable region must less than FTW spare space size. 3. Per UEFI Specification, variables of attribute HARDWARE_ERROR_RECORD are guaranteed to have its own storage space size.original implementation doesn’t meet this requirement git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8029 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal')
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c138
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h2
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf1
3 files changed, 112 insertions, 29 deletions
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
index 0e5735e..62025c9 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 41b4a95..85e7f70 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 be9385f..64246a7 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.)