From: "Wu, Hao A" <hao.a.wu@intel.com>
To: "Kubacki, Michael A" <michael.a.kubacki@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Bi, Dandan" <dandan.bi@intel.com>,
Ard Biesheuvel <ard.biesheuvel@linaro.org>,
"Dong, Eric" <eric.dong@intel.com>,
Laszlo Ersek <lersek@redhat.com>,
"Gao, Liming" <liming.gao@intel.com>,
"Kinney, Michael D" <michael.d.kinney@intel.com>,
"Ni, Ray" <ray.ni@intel.com>,
"Wang, Jian J" <jian.j.wang@intel.com>,
"Yao, Jiewen" <jiewen.yao@intel.com>
Subject: Re: [PATCH V4 05/10] MdeModulePkg/Variable: Add a file for NV variable functions
Date: Wed, 16 Oct 2019 07:55:54 +0000 [thread overview]
Message-ID: <B80AF82E9BFB8E4FBD8C89DA810C6A093C94802B@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <20191014233001.33024-6-michael.a.kubacki@intel.com>
> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Tuesday, October 15, 2019 7:30 AM
> To: devel@edk2.groups.io
> Cc: Bi, Dandan; Ard Biesheuvel; Dong, Eric; Laszlo Ersek; Gao, Liming; Kinney,
> Michael D; Ni, Ray; Wang, Jian J; Wu, Hao A; Yao, Jiewen
> Subject: [PATCH V4 05/10] MdeModulePkg/Variable: Add a file for NV
> variable functions
>
> This change adds a dedicated file for variable operations specific
> to non-volatile variables. This decreases the overall length of the
> relatively large Variable.c file.
Since all my previous comments have been addressed, the patch looks good to me:
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
Best Regards,
Hao Wu
>
> Cc: Dandan Bi <dandan.bi@intel.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Hao A Wu <hao.a.wu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> | 2 +
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf | 2
> +
>
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> | 2 +
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.h |
> 67 ++++
> MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c | 317 +--
> ----------------
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c |
> 334 ++++++++++++++++++++
> 6 files changed, 408 insertions(+), 316 deletions(-)
>
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> index c35e5fe787..08a5490787 100644
> ---
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> +++
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> @@ -36,6 +36,8 @@
> Variable.c
> VariableDxe.c
> Variable.h
> + VariableNonVolatile.c
> + VariableNonVolatile.h
> VariableParsing.c
> VariableParsing.h
> PrivilegePolymorphic.h
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
> index 626738b9c7..6dc2721b81 100644
> --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
> +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
> @@ -45,6 +45,8 @@
> Variable.c
> VariableTraditionalMm.c
> VariableSmm.c
> + VariableNonVolatile.c
> + VariableNonVolatile.h
> VariableParsing.c
> VariableParsing.h
> VarCheck.c
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.i
> nf
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.
> inf
> index ff714b193a..f8a3742959 100644
> ---
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.i
> nf
> +++
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.
> inf
> @@ -45,6 +45,8 @@
> Variable.c
> VariableSmm.c
> VariableStandaloneMm.c
> + VariableNonVolatile.c
> + VariableNonVolatile.h
> VariableParsing.c
> VariableParsing.h
> VarCheck.c
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.h
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.h
> new file mode 100644
> index 0000000000..43653f27e6
> --- /dev/null
> +++
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.h
> @@ -0,0 +1,67 @@
> +/** @file
> + Common variable non-volatile store routines.
> +
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _VARIABLE_NON_VOLATILE_H_
> +#define _VARIABLE_NON_VOLATILE_H_
> +
> +#include "Variable.h"
> +
> +/**
> + Get non-volatile maximum variable size.
> +
> + @return Non-volatile maximum variable size.
> +
> +**/
> +UINTN
> +GetNonVolatileMaxVariableSize (
> + VOID
> + );
> +
> +/**
> + 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
> + );
> +
> +/**
> + 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
> + );
> +
> +/**
> + 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
> + );
> +
> +#endif
> 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;
> @@ -3079,25 +3080,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.
>
> @@ -3122,303 +3104,6 @@ GetMaxVariableSize (
> return MaxVariableSize;
> }
>
> -/**
> - 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.
>
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c
> new file mode 100644
> index 0000000000..0637a828b3
> --- /dev/null
> +++
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c
> @@ -0,0 +1,334 @@
> +/** @file
> + Common variable non-volatile store routines.
> +
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "VariableNonVolatile.h"
> +#include "VariableParsing.h"
> +
> +extern VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;
> +
> +/**
> + 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));
> + }
> +}
> +
> +/**
> + 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 (
> + OUT 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 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 ((DEBUG_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 ((DEBUG_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 ((DEBUG_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((DEBUG_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 ((
> + DEBUG_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 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;
> +}
> --
> 2.16.2.windows.1
next prev parent reply other threads:[~2019-10-16 7:56 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-14 23:29 [PATCH V4 00/10] UEFI Variable SMI Reduction Kubacki, Michael A
2019-10-14 23:29 ` [PATCH V4 01/10] MdeModulePkg/Variable: Consolidate common parsing functions Kubacki, Michael A
2019-10-16 7:52 ` Wu, Hao A
2019-10-14 23:29 ` [PATCH V4 02/10] MdeModulePkg/Variable: Parameterize GetNextVariableInternal () stores Kubacki, Michael A
2019-10-16 7:53 ` Wu, Hao A
2019-10-14 23:29 ` [PATCH V4 03/10] MdeModulePkg/Variable: Parameterize VARIABLE_INFO_ENTRY buffer Kubacki, Michael A
2019-10-16 7:54 ` Wu, Hao A
2019-10-14 23:29 ` [PATCH V4 04/10] MdeModulePkg/Variable: Parameterize auth status in VariableParsing Kubacki, Michael A
2019-10-17 1:01 ` Wu, Hao A
2019-10-17 1:41 ` Kubacki, Michael A
2019-10-17 1:49 ` Wu, Hao A
2019-10-14 23:29 ` [PATCH V4 05/10] MdeModulePkg/Variable: Add a file for NV variable functions Kubacki, Michael A
2019-10-16 7:55 ` Wu, Hao A [this message]
2019-10-14 23:29 ` [PATCH V4 06/10] MdeModulePkg VariableInfo: Always consider RT DXE and SMM stats Kubacki, Michael A
2019-10-16 7:56 ` Wu, Hao A
2019-10-14 23:29 ` [PATCH V4 07/10] MdeModulePkg/Variable: Add RT GetVariable() cache support Kubacki, Michael A
2019-10-16 6:46 ` Wang, Jian J
[not found] ` <15CE0DB2DE3EB613.1607@groups.io>
2019-10-16 6:54 ` [edk2-devel] " Wang, Jian J
2019-10-17 1:24 ` Kubacki, Michael A
2019-10-17 1:47 ` Wang, Jian J
2019-10-16 7:56 ` Wu, Hao A
2019-10-16 16:44 ` Kubacki, Michael A
2019-10-17 14:23 ` Wang, Jian J
2019-10-17 17:44 ` Kubacki, Michael A
2019-10-14 23:29 ` [PATCH V4 08/10] MdeModulePkg/Variable: Add RT GetNextVariableName() " Kubacki, Michael A
2019-10-16 7:56 ` Wu, Hao A
2019-10-14 23:30 ` [PATCH V4 09/10] OvmfPkg: Disable variable runtime cache Kubacki, Michael A
2019-10-15 7:32 ` Laszlo Ersek
2019-10-14 23:30 ` [PATCH V4 10/10] MdeModulePkg: Enable variable runtime cache by default Kubacki, Michael A
2019-10-15 7:33 ` Laszlo Ersek
2019-10-16 7:57 ` Wu, Hao A
2019-10-15 0:49 ` [PATCH V4 00/10] UEFI Variable SMI Reduction Liming Gao
2019-10-15 16:15 ` Kubacki, Michael A
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=B80AF82E9BFB8E4FBD8C89DA810C6A093C94802B@SHSMSX104.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox