summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c')
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c317
1 files changed, 1 insertions, 316 deletions
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
index 2e32905dfe..0bd2f22e1a 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
@@ -23,6 +23,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "Variable.h"
+#include "VariableNonVolatile.h"
#include "VariableParsing.h"
VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;
@@ -3080,25 +3081,6 @@ ReclaimForOS(
}
/**
- Get non-volatile maximum variable size.
-
- @return Non-volatile maximum variable size.
-
-**/
-UINTN
-GetNonVolatileMaxVariableSize (
- VOID
- )
-{
- if (PcdGet32 (PcdHwErrStorageSize) != 0) {
- return MAX (MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxAuthVariableSize)),
- PcdGet32 (PcdMaxHardwareErrorVariableSize));
- } else {
- return MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxAuthVariableSize));
- }
-}
-
-/**
Get maximum variable size, covering both non-volatile and volatile variables.
@return Maximum variable size.
@@ -3123,303 +3105,6 @@ GetMaxVariableSize (
}
/**
- Init real non-volatile variable store.
-
- @param[out] VariableStoreBase Output pointer to real non-volatile variable store base.
-
- @retval EFI_SUCCESS Function successfully executed.
- @retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resource.
- @retval EFI_VOLUME_CORRUPTED Variable Store or Firmware Volume for Variable Store is corrupted.
-
-**/
-EFI_STATUS
-InitRealNonVolatileVariableStore (
- OUT EFI_PHYSICAL_ADDRESS *VariableStoreBase
- )
-{
- EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
- VARIABLE_STORE_HEADER *VariableStore;
- UINT32 VariableStoreLength;
- EFI_HOB_GUID_TYPE *GuidHob;
- EFI_PHYSICAL_ADDRESS NvStorageBase;
- UINT8 *NvStorageData;
- UINT32 NvStorageSize;
- FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *FtwLastWriteData;
- UINT32 BackUpOffset;
- UINT32 BackUpSize;
- UINT32 HwErrStorageSize;
- UINT32 MaxUserNvVariableSpaceSize;
- UINT32 BoottimeReservedNvVariableSpaceSize;
- EFI_STATUS Status;
- VOID *FtwProtocol;
-
- mVariableModuleGlobal->FvbInstance = NULL;
-
- //
- // Allocate runtime memory used for a memory copy of the FLASH region.
- // Keep the memory and the FLASH in sync as updates occur.
- //
- NvStorageSize = PcdGet32 (PcdFlashNvStorageVariableSize);
- NvStorageData = AllocateRuntimeZeroPool (NvStorageSize);
- if (NvStorageData == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- NvStorageBase = NV_STORAGE_VARIABLE_BASE;
- ASSERT (NvStorageBase != 0);
-
- //
- // Copy NV storage data to the memory buffer.
- //
- CopyMem (NvStorageData, (UINT8 *) (UINTN) NvStorageBase, NvStorageSize);
-
- Status = GetFtwProtocol ((VOID **)&FtwProtocol);
- //
- // If FTW protocol has been installed, no need to check FTW last write data hob.
- //
- if (EFI_ERROR (Status)) {
- //
- // Check the FTW last write data hob.
- //
- GuidHob = GetFirstGuidHob (&gEdkiiFaultTolerantWriteGuid);
- if (GuidHob != NULL) {
- FtwLastWriteData = (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *) GET_GUID_HOB_DATA (GuidHob);
- if (FtwLastWriteData->TargetAddress == NvStorageBase) {
- DEBUG ((EFI_D_INFO, "Variable: NV storage is backed up in spare block: 0x%x\n", (UINTN) FtwLastWriteData->SpareAddress));
- //
- // Copy the backed up NV storage data to the memory buffer from spare block.
- //
- CopyMem (NvStorageData, (UINT8 *) (UINTN) (FtwLastWriteData->SpareAddress), NvStorageSize);
- } else if ((FtwLastWriteData->TargetAddress > NvStorageBase) &&
- (FtwLastWriteData->TargetAddress < (NvStorageBase + NvStorageSize))) {
- //
- // Flash NV storage from the Offset is backed up in spare block.
- //
- BackUpOffset = (UINT32) (FtwLastWriteData->TargetAddress - NvStorageBase);
- BackUpSize = NvStorageSize - BackUpOffset;
- DEBUG ((EFI_D_INFO, "Variable: High partial NV storage from offset: %x is backed up in spare block: 0x%x\n", BackUpOffset, (UINTN) FtwLastWriteData->SpareAddress));
- //
- // Copy the partial backed up NV storage data to the memory buffer from spare block.
- //
- CopyMem (NvStorageData + BackUpOffset, (UINT8 *) (UINTN) FtwLastWriteData->SpareAddress, BackUpSize);
- }
- }
- }
-
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) NvStorageData;
-
- //
- // Check if the Firmware Volume is not corrupted
- //
- if ((FvHeader->Signature != EFI_FVH_SIGNATURE) || (!CompareGuid (&gEfiSystemNvDataFvGuid, &FvHeader->FileSystemGuid))) {
- FreePool (NvStorageData);
- DEBUG ((EFI_D_ERROR, "Firmware Volume for Variable Store is corrupted\n"));
- return EFI_VOLUME_CORRUPTED;
- }
-
- VariableStore = (VARIABLE_STORE_HEADER *) ((UINTN) FvHeader + FvHeader->HeaderLength);
- VariableStoreLength = NvStorageSize - FvHeader->HeaderLength;
- ASSERT (sizeof (VARIABLE_STORE_HEADER) <= VariableStoreLength);
- ASSERT (VariableStore->Size == VariableStoreLength);
-
- //
- // Check if the Variable Store header is not corrupted
- //
- if (GetVariableStoreStatus (VariableStore) != EfiValid) {
- FreePool (NvStorageData);
- DEBUG((EFI_D_ERROR, "Variable Store header is corrupted\n"));
- return EFI_VOLUME_CORRUPTED;
- }
-
- mNvFvHeaderCache = FvHeader;
-
- *VariableStoreBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore;
-
- HwErrStorageSize = PcdGet32 (PcdHwErrStorageSize);
- MaxUserNvVariableSpaceSize = PcdGet32 (PcdMaxUserNvVariableSpaceSize);
- BoottimeReservedNvVariableSpaceSize = PcdGet32 (PcdBoottimeReservedNvVariableSpaceSize);
-
- //
- // Note that in EdkII variable driver implementation, Hardware Error Record type variable
- // is stored with common variable in the same NV region. So the platform integrator should
- // ensure that the value of PcdHwErrStorageSize is less than the value of
- // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)).
- //
- ASSERT (HwErrStorageSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)));
- //
- // Ensure that the value of PcdMaxUserNvVariableSpaceSize is less than the value of
- // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize).
- //
- ASSERT (MaxUserNvVariableSpaceSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize));
- //
- // Ensure that the value of PcdBoottimeReservedNvVariableSpaceSize is less than the value of
- // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize).
- //
- ASSERT (BoottimeReservedNvVariableSpaceSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize));
-
- mVariableModuleGlobal->CommonVariableSpace = ((UINTN) VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize);
- mVariableModuleGlobal->CommonMaxUserVariableSpace = ((MaxUserNvVariableSpaceSize != 0) ? MaxUserNvVariableSpaceSize : mVariableModuleGlobal->CommonVariableSpace);
- mVariableModuleGlobal->CommonRuntimeVariableSpace = mVariableModuleGlobal->CommonVariableSpace - BoottimeReservedNvVariableSpaceSize;
-
- DEBUG ((EFI_D_INFO, "Variable driver common space: 0x%x 0x%x 0x%x\n", mVariableModuleGlobal->CommonVariableSpace, mVariableModuleGlobal->CommonMaxUserVariableSpace, mVariableModuleGlobal->CommonRuntimeVariableSpace));
-
- //
- // The max NV variable size should be < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)).
- //
- ASSERT (GetNonVolatileMaxVariableSize () < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)));
-
- return EFI_SUCCESS;
-}
-
-/**
- Init emulated non-volatile variable store.
-
- @param[out] VariableStoreBase Output pointer to emulated non-volatile variable store base.
-
- @retval EFI_SUCCESS Function successfully executed.
- @retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resource.
-
-**/
-EFI_STATUS
-InitEmuNonVolatileVariableStore (
- EFI_PHYSICAL_ADDRESS *VariableStoreBase
- )
-{
- VARIABLE_STORE_HEADER *VariableStore;
- UINT32 VariableStoreLength;
- BOOLEAN FullyInitializeStore;
- UINT32 HwErrStorageSize;
-
- FullyInitializeStore = TRUE;
-
- VariableStoreLength = PcdGet32 (PcdVariableStoreSize);
- ASSERT (sizeof (VARIABLE_STORE_HEADER) <= VariableStoreLength);
-
- //
- // Allocate memory for variable store.
- //
- if (PcdGet64 (PcdEmuVariableNvStoreReserved) == 0) {
- VariableStore = (VARIABLE_STORE_HEADER *) AllocateRuntimePool (VariableStoreLength);
- if (VariableStore == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- } else {
- //
- // A memory location has been reserved for the NV variable store. Certain
- // platforms may be able to preserve a memory range across system resets,
- // thereby providing better NV variable emulation.
- //
- VariableStore =
- (VARIABLE_STORE_HEADER *)(VOID*)(UINTN)
- PcdGet64 (PcdEmuVariableNvStoreReserved);
- if ((VariableStore->Size == VariableStoreLength) &&
- (CompareGuid (&VariableStore->Signature, &gEfiAuthenticatedVariableGuid) ||
- CompareGuid (&VariableStore->Signature, &gEfiVariableGuid)) &&
- (VariableStore->Format == VARIABLE_STORE_FORMATTED) &&
- (VariableStore->State == VARIABLE_STORE_HEALTHY)) {
- DEBUG((
- DEBUG_INFO,
- "Variable Store reserved at %p appears to be valid\n",
- VariableStore
- ));
- FullyInitializeStore = FALSE;
- }
- }
-
- if (FullyInitializeStore) {
- SetMem (VariableStore, VariableStoreLength, 0xff);
- //
- // Use gEfiAuthenticatedVariableGuid for potential auth variable support.
- //
- CopyGuid (&VariableStore->Signature, &gEfiAuthenticatedVariableGuid);
- VariableStore->Size = VariableStoreLength;
- VariableStore->Format = VARIABLE_STORE_FORMATTED;
- VariableStore->State = VARIABLE_STORE_HEALTHY;
- VariableStore->Reserved = 0;
- VariableStore->Reserved1 = 0;
- }
-
- *VariableStoreBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore;
-
- HwErrStorageSize = PcdGet32 (PcdHwErrStorageSize);
-
- //
- // Note that in EdkII variable driver implementation, Hardware Error Record type variable
- // is stored with common variable in the same NV region. So the platform integrator should
- // ensure that the value of PcdHwErrStorageSize is less than the value of
- // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)).
- //
- ASSERT (HwErrStorageSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)));
-
- mVariableModuleGlobal->CommonVariableSpace = ((UINTN) VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize);
- mVariableModuleGlobal->CommonMaxUserVariableSpace = mVariableModuleGlobal->CommonVariableSpace;
- mVariableModuleGlobal->CommonRuntimeVariableSpace = mVariableModuleGlobal->CommonVariableSpace;
-
- return EFI_SUCCESS;
-}
-
-/**
- Init non-volatile variable store.
-
- @retval EFI_SUCCESS Function successfully executed.
- @retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resource.
- @retval EFI_VOLUME_CORRUPTED Variable Store or Firmware Volume for Variable Store is corrupted.
-
-**/
-EFI_STATUS
-InitNonVolatileVariableStore (
- VOID
- )
-{
- VARIABLE_HEADER *Variable;
- VARIABLE_HEADER *NextVariable;
- EFI_PHYSICAL_ADDRESS VariableStoreBase;
- UINTN VariableSize;
- EFI_STATUS Status;
-
- if (PcdGetBool (PcdEmuVariableNvModeEnable)) {
- Status = InitEmuNonVolatileVariableStore (&VariableStoreBase);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- mVariableModuleGlobal->VariableGlobal.EmuNvMode = TRUE;
- DEBUG ((DEBUG_INFO, "Variable driver will work at emulated non-volatile variable mode!\n"));
- } else {
- Status = InitRealNonVolatileVariableStore (&VariableStoreBase);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- mVariableModuleGlobal->VariableGlobal.EmuNvMode = FALSE;
- }
-
- mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;
- mNvVariableCache = (VARIABLE_STORE_HEADER *) (UINTN) VariableStoreBase;
- mVariableModuleGlobal->VariableGlobal.AuthFormat = (BOOLEAN)(CompareGuid (&mNvVariableCache->Signature, &gEfiAuthenticatedVariableGuid));
-
- mVariableModuleGlobal->MaxVariableSize = PcdGet32 (PcdMaxVariableSize);
- mVariableModuleGlobal->MaxAuthVariableSize = ((PcdGet32 (PcdMaxAuthVariableSize) != 0) ? PcdGet32 (PcdMaxAuthVariableSize) : mVariableModuleGlobal->MaxVariableSize);
-
- //
- // Parse non-volatile variable data and get last variable offset.
- //
- Variable = GetStartPointer (mNvVariableCache);
- while (IsValidVariableHeader (Variable, GetEndPointer (mNvVariableCache))) {
- NextVariable = GetNextVariablePtr (Variable, mVariableModuleGlobal->VariableGlobal.AuthFormat);
- VariableSize = (UINTN) NextVariable - (UINTN) Variable;
- if ((Variable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize;
- } else {
- mVariableModuleGlobal->CommonVariableTotalSize += VariableSize;
- }
-
- Variable = NextVariable;
- }
- mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) Variable - (UINTN) mNvVariableCache;
-
- return EFI_SUCCESS;
-}
-
-/**
Flush the HOB variable to flash.
@param[in] VariableName Name of variable has been updated or deleted.