From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web12.2711.1571212560389911252 for ; Wed, 16 Oct 2019 00:56:00 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.24, mailfrom: hao.a.wu@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Oct 2019 00:55:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,303,1566889200"; d="scan'208";a="220698201" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by fmsmga004.fm.intel.com with ESMTP; 16 Oct 2019 00:55:58 -0700 Received: from fmsmsx114.amr.corp.intel.com (10.18.116.8) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 16 Oct 2019 00:55:58 -0700 Received: from shsmsx153.ccr.corp.intel.com (10.239.6.53) by FMSMSX114.amr.corp.intel.com (10.18.116.8) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 16 Oct 2019 00:55:58 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.166]) by SHSMSX153.ccr.corp.intel.com ([10.239.6.53]) with mapi id 14.03.0439.000; Wed, 16 Oct 2019 15:55:55 +0800 From: "Wu, Hao A" To: "Kubacki, Michael A" , "devel@edk2.groups.io" CC: "Bi, Dandan" , Ard Biesheuvel , "Dong, Eric" , Laszlo Ersek , "Gao, Liming" , "Kinney, Michael D" , "Ni, Ray" , "Wang, Jian J" , "Yao, Jiewen" Subject: Re: [PATCH V4 05/10] MdeModulePkg/Variable: Add a file for NV variable functions Thread-Topic: [PATCH V4 05/10] MdeModulePkg/Variable: Add a file for NV variable functions Thread-Index: AQHVgudjDkX4PLkYw0+ns84DoPbn4qdc6FeA Date: Wed, 16 Oct 2019 07:55:54 +0000 Message-ID: References: <20191014233001.33024-1-michael.a.kubacki@intel.com> <20191014233001.33024-6-michael.a.kubacki@intel.com> In-Reply-To: <20191014233001.33024-6-michael.a.kubacki@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: hao.a.wu@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable > -----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; Ki= nney, > 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 >=20 > 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 Best Regards, Hao Wu >=20 > Cc: Dandan Bi > Cc: Ard Biesheuvel > Cc: Eric Dong > Cc: Laszlo Ersek > Cc: Liming Gao > Cc: Michael D Kinney > Cc: Ray Ni > Cc: Jian J Wang > Cc: Hao A Wu > Cc: Jiewen Yao > Signed-off-by: Michael Kubacki > --- > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > | 2 + > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf | = 2 > + >=20 > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf > | 2 + > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.h | > 67 ++++ > MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c | 31= 7 +-- > ---------------- > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c | > 334 ++++++++++++++++++++ > 6 files changed, 408 insertions(+), 316 deletions(-) >=20 > 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.
> +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 > **/ >=20 > #include "Variable.h" > +#include "VariableNonVolatile.h" > #include "VariableParsing.h" >=20 > VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal; > @@ -3079,25 +3080,6 @@ ReclaimForOS( > } > } >=20 > -/** > - Get non-volatile maximum variable size. > - > - @return Non-volatile maximum variable size. > - > -**/ > -UINTN > -GetNonVolatileMaxVariableSize ( > - VOID > - ) > -{ > - if (PcdGet32 (PcdHwErrStorageSize) !=3D 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 var= iables. >=20 > @@ -3122,303 +3104,6 @@ GetMaxVariableSize ( > return MaxVariableSize; > } >=20 > -/** > - 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 BoottimeReservedNvVariableSpaceS= ize; > - EFI_STATUS Status; > - VOID *FtwProtocol; > - > - mVariableModuleGlobal->FvbInstance =3D 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 =3D PcdGet32 (PcdFlashNvStorageVariableSize); > - NvStorageData =3D AllocateRuntimeZeroPool (NvStorageSize); > - if (NvStorageData =3D=3D NULL) { > - return EFI_OUT_OF_RESOURCES; > - } > - > - NvStorageBase =3D NV_STORAGE_VARIABLE_BASE; > - ASSERT (NvStorageBase !=3D 0); > - > - // > - // Copy NV storage data to the memory buffer. > - // > - CopyMem (NvStorageData, (UINT8 *) (UINTN) NvStorageBase, > NvStorageSize); > - > - Status =3D 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 =3D GetFirstGuidHob (&gEdkiiFaultTolerantWriteGuid); > - if (GuidHob !=3D NULL) { > - FtwLastWriteData =3D (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *) > GET_GUID_HOB_DATA (GuidHob); > - if (FtwLastWriteData->TargetAddress =3D=3D 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 =3D (UINT32) (FtwLastWriteData->TargetAddress - > NvStorageBase); > - BackUpSize =3D NvStorageSize - BackUpOffset; > - DEBUG ((EFI_D_INFO, "Variable: High partial NV storage from offs= et: %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 buff= er > from spare block. > - // > - CopyMem (NvStorageData + BackUpOffset, (UINT8 *) (UINTN) > FtwLastWriteData->SpareAddress, BackUpSize); > - } > - } > - } > - > - FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *) NvStorageData; > - > - // > - // Check if the Firmware Volume is not corrupted > - // > - if ((FvHeader->Signature !=3D 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 =3D (VARIABLE_STORE_HEADER *) ((UINTN) FvHeader + > FvHeader->HeaderLength); > - VariableStoreLength =3D NvStorageSize - FvHeader->HeaderLength; > - ASSERT (sizeof (VARIABLE_STORE_HEADER) <=3D VariableStoreLength); > - ASSERT (VariableStore->Size =3D=3D VariableStoreLength); > - > - // > - // Check if the Variable Store header is not corrupted > - // > - if (GetVariableStoreStatus (VariableStore) !=3D EfiValid) { > - FreePool (NvStorageData); > - DEBUG((EFI_D_ERROR, "Variable Store header is corrupted\n")); > - return EFI_VOLUME_CORRUPTED; > - } > - > - mNvFvHeaderCache =3D FvHeader; > - > - *VariableStoreBase =3D (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore; > - > - HwErrStorageSize =3D PcdGet32 (PcdHwErrStorageSize); > - MaxUserNvVariableSpaceSize =3D PcdGet32 > (PcdMaxUserNvVariableSpaceSize); > - BoottimeReservedNvVariableSpaceSize =3D PcdGet32 > (PcdBoottimeReservedNvVariableSpaceSize); > - > - // > - // Note that in EdkII variable driver implementation, Hardware Error R= ecord > type variable > - // is stored with common variable in the same NV region. So the platfo= rm > 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 =3D ((UINTN) > VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - > HwErrStorageSize); > - mVariableModuleGlobal->CommonMaxUserVariableSpace =3D > ((MaxUserNvVariableSpaceSize !=3D 0) ? MaxUserNvVariableSpaceSize : > mVariableModuleGlobal->CommonVariableSpace); > - mVariableModuleGlobal->CommonRuntimeVariableSpace =3D > 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 - size= of > (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 =3D TRUE; > - > - VariableStoreLength =3D PcdGet32 (PcdVariableStoreSize); > - ASSERT (sizeof (VARIABLE_STORE_HEADER) <=3D VariableStoreLength); > - > - // > - // Allocate memory for variable store. > - // > - if (PcdGet64 (PcdEmuVariableNvStoreReserved) =3D=3D 0) { > - VariableStore =3D (VARIABLE_STORE_HEADER *) AllocateRuntimePool > (VariableStoreLength); > - if (VariableStore =3D=3D 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 =3D > - (VARIABLE_STORE_HEADER *)(VOID*)(UINTN) > - PcdGet64 (PcdEmuVariableNvStoreReserved); > - if ((VariableStore->Size =3D=3D VariableStoreLength) && > - (CompareGuid (&VariableStore->Signature, > &gEfiAuthenticatedVariableGuid) || > - CompareGuid (&VariableStore->Signature, &gEfiVariableGuid)) && > - (VariableStore->Format =3D=3D VARIABLE_STORE_FORMATTED) && > - (VariableStore->State =3D=3D VARIABLE_STORE_HEALTHY)) { > - DEBUG(( > - DEBUG_INFO, > - "Variable Store reserved at %p appears to be valid\n", > - VariableStore > - )); > - FullyInitializeStore =3D FALSE; > - } > - } > - > - if (FullyInitializeStore) { > - SetMem (VariableStore, VariableStoreLength, 0xff); > - // > - // Use gEfiAuthenticatedVariableGuid for potential auth variable sup= port. > - // > - CopyGuid (&VariableStore->Signature, &gEfiAuthenticatedVariableGuid)= ; > - VariableStore->Size =3D VariableStoreLength; > - VariableStore->Format =3D VARIABLE_STORE_FORMATTED; > - VariableStore->State =3D VARIABLE_STORE_HEALTHY; > - VariableStore->Reserved =3D 0; > - VariableStore->Reserved1 =3D 0; > - } > - > - *VariableStoreBase =3D (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore; > - > - HwErrStorageSize =3D PcdGet32 (PcdHwErrStorageSize); > - > - // > - // Note that in EdkII variable driver implementation, Hardware Error R= ecord > type variable > - // is stored with common variable in the same NV region. So the platfo= rm > 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 =3D ((UINTN) > VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - > HwErrStorageSize); > - mVariableModuleGlobal->CommonMaxUserVariableSpace =3D > mVariableModuleGlobal->CommonVariableSpace; > - mVariableModuleGlobal->CommonRuntimeVariableSpace =3D > 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 =3D InitEmuNonVolatileVariableStore (&VariableStoreBase); > - if (EFI_ERROR (Status)) { > - return Status; > - } > - mVariableModuleGlobal->VariableGlobal.EmuNvMode =3D TRUE; > - DEBUG ((DEBUG_INFO, "Variable driver will work at emulated non-volat= ile > variable mode!\n")); > - } else { > - Status =3D InitRealNonVolatileVariableStore (&VariableStoreBase); > - if (EFI_ERROR (Status)) { > - return Status; > - } > - mVariableModuleGlobal->VariableGlobal.EmuNvMode =3D FALSE; > - } > - > - mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase =3D > VariableStoreBase; > - mNvVariableCache =3D (VARIABLE_STORE_HEADER *) (UINTN) > VariableStoreBase; > - mVariableModuleGlobal->VariableGlobal.AuthFormat =3D > (BOOLEAN)(CompareGuid (&mNvVariableCache->Signature, > &gEfiAuthenticatedVariableGuid)); > - > - mVariableModuleGlobal->MaxVariableSize =3D PcdGet32 > (PcdMaxVariableSize); > - mVariableModuleGlobal->MaxAuthVariableSize =3D ((PcdGet32 > (PcdMaxAuthVariableSize) !=3D 0) ? PcdGet32 (PcdMaxAuthVariableSize) : > mVariableModuleGlobal->MaxVariableSize); > - > - // > - // Parse non-volatile variable data and get last variable offset. > - // > - Variable =3D GetStartPointer (mNvVariableCache); > - while (IsValidVariableHeader (Variable, GetEndPointer > (mNvVariableCache))) { > - NextVariable =3D GetNextVariablePtr (Variable, mVariableModuleGlobal= - > >VariableGlobal.AuthFormat); > - VariableSize =3D (UINTN) NextVariable - (UINTN) Variable; > - if ((Variable->Attributes & (EFI_VARIABLE_NON_VOLATILE | > EFI_VARIABLE_HARDWARE_ERROR_RECORD)) =3D=3D > (EFI_VARIABLE_NON_VOLATILE | > EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { > - mVariableModuleGlobal->HwErrVariableTotalSize +=3D VariableSize; > - } else { > - mVariableModuleGlobal->CommonVariableTotalSize +=3D VariableSize; > - } > - > - Variable =3D NextVariable; > - } > - mVariableModuleGlobal->NonVolatileLastVariableOffset =3D (UINTN) > Variable - (UINTN) mNvVariableCache; > - > - return EFI_SUCCESS; > -} > - > /** > Flush the HOB variable to flash. >=20 > 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.
> +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) !=3D 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 =3D TRUE; > + > + VariableStoreLength =3D PcdGet32 (PcdVariableStoreSize); > + ASSERT (sizeof (VARIABLE_STORE_HEADER) <=3D VariableStoreLength); > + > + // > + // Allocate memory for variable store. > + // > + if (PcdGet64 (PcdEmuVariableNvStoreReserved) =3D=3D 0) { > + VariableStore =3D (VARIABLE_STORE_HEADER *) AllocateRuntimePool > (VariableStoreLength); > + if (VariableStore =3D=3D 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 =3D > + (VARIABLE_STORE_HEADER *)(VOID*)(UINTN) > + PcdGet64 (PcdEmuVariableNvStoreReserved); > + if ((VariableStore->Size =3D=3D VariableStoreLength) && > + (CompareGuid (&VariableStore->Signature, > &gEfiAuthenticatedVariableGuid) || > + CompareGuid (&VariableStore->Signature, &gEfiVariableGuid)) && > + (VariableStore->Format =3D=3D VARIABLE_STORE_FORMATTED) && > + (VariableStore->State =3D=3D VARIABLE_STORE_HEALTHY)) { > + DEBUG(( > + DEBUG_INFO, > + "Variable Store reserved at %p appears to be valid\n", > + VariableStore > + )); > + FullyInitializeStore =3D FALSE; > + } > + } > + > + if (FullyInitializeStore) { > + SetMem (VariableStore, VariableStoreLength, 0xff); > + // > + // Use gEfiAuthenticatedVariableGuid for potential auth variable sup= port. > + // > + CopyGuid (&VariableStore->Signature, &gEfiAuthenticatedVariableGuid)= ; > + VariableStore->Size =3D VariableStoreLength; > + VariableStore->Format =3D VARIABLE_STORE_FORMATTED; > + VariableStore->State =3D VARIABLE_STORE_HEALTHY; > + VariableStore->Reserved =3D 0; > + VariableStore->Reserved1 =3D 0; > + } > + > + *VariableStoreBase =3D (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore; > + > + HwErrStorageSize =3D 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 platfo= rm > 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 =3D ((UINTN) > VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - > HwErrStorageSize); > + mVariableModuleGlobal->CommonMaxUserVariableSpace =3D > mVariableModuleGlobal->CommonVariableSpace; > + mVariableModuleGlobal->CommonRuntimeVariableSpace =3D > 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 BoottimeReservedNvVariableSpaceS= ize; > + EFI_STATUS Status; > + VOID *FtwProtocol; > + > + mVariableModuleGlobal->FvbInstance =3D 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 =3D PcdGet32 (PcdFlashNvStorageVariableSize); > + NvStorageData =3D AllocateRuntimeZeroPool (NvStorageSize); > + if (NvStorageData =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + NvStorageBase =3D NV_STORAGE_VARIABLE_BASE; > + ASSERT (NvStorageBase !=3D 0); > + > + // > + // Copy NV storage data to the memory buffer. > + // > + CopyMem (NvStorageData, (UINT8 *) (UINTN) NvStorageBase, > NvStorageSize); > + > + Status =3D 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 =3D GetFirstGuidHob (&gEdkiiFaultTolerantWriteGuid); > + if (GuidHob !=3D NULL) { > + FtwLastWriteData =3D (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *) > GET_GUID_HOB_DATA (GuidHob); > + if (FtwLastWriteData->TargetAddress =3D=3D 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 =3D (UINT32) (FtwLastWriteData->TargetAddress - > NvStorageBase); > + BackUpSize =3D 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 buff= er > from spare block. > + // > + CopyMem (NvStorageData + BackUpOffset, (UINT8 *) (UINTN) > FtwLastWriteData->SpareAddress, BackUpSize); > + } > + } > + } > + > + FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *) NvStorageData; > + > + // > + // Check if the Firmware Volume is not corrupted > + // > + if ((FvHeader->Signature !=3D 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 =3D (VARIABLE_STORE_HEADER *) ((UINTN) FvHeader + > FvHeader->HeaderLength); > + VariableStoreLength =3D NvStorageSize - FvHeader->HeaderLength; > + ASSERT (sizeof (VARIABLE_STORE_HEADER) <=3D VariableStoreLength); > + ASSERT (VariableStore->Size =3D=3D VariableStoreLength); > + > + // > + // Check if the Variable Store header is not corrupted > + // > + if (GetVariableStoreStatus (VariableStore) !=3D EfiValid) { > + FreePool (NvStorageData); > + DEBUG((DEBUG_ERROR, "Variable Store header is corrupted\n")); > + return EFI_VOLUME_CORRUPTED; > + } > + > + mNvFvHeaderCache =3D FvHeader; > + > + *VariableStoreBase =3D (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore; > + > + HwErrStorageSize =3D PcdGet32 (PcdHwErrStorageSize); > + MaxUserNvVariableSpaceSize =3D PcdGet32 > (PcdMaxUserNvVariableSpaceSize); > + BoottimeReservedNvVariableSpaceSize =3D 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 platfo= rm > 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 =3D ((UINTN) > VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - > HwErrStorageSize); > + mVariableModuleGlobal->CommonMaxUserVariableSpace =3D > ((MaxUserNvVariableSpaceSize !=3D 0) ? MaxUserNvVariableSpaceSize : > mVariableModuleGlobal->CommonVariableSpace); > + mVariableModuleGlobal->CommonRuntimeVariableSpace =3D > 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 - size= of > (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 =3D InitEmuNonVolatileVariableStore (&VariableStoreBase); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + mVariableModuleGlobal->VariableGlobal.EmuNvMode =3D TRUE; > + DEBUG ((DEBUG_INFO, "Variable driver will work at emulated non- > volatile variable mode!\n")); > + } else { > + Status =3D InitRealNonVolatileVariableStore (&VariableStoreBase); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + mVariableModuleGlobal->VariableGlobal.EmuNvMode =3D FALSE; > + } > + > + mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase =3D > VariableStoreBase; > + mNvVariableCache =3D (VARIABLE_STORE_HEADER *) (UINTN) > VariableStoreBase; > + mVariableModuleGlobal->VariableGlobal.AuthFormat =3D > (BOOLEAN)(CompareGuid (&mNvVariableCache->Signature, > &gEfiAuthenticatedVariableGuid)); > + > + mVariableModuleGlobal->MaxVariableSize =3D PcdGet32 > (PcdMaxVariableSize); > + mVariableModuleGlobal->MaxAuthVariableSize =3D ((PcdGet32 > (PcdMaxAuthVariableSize) !=3D 0) ? PcdGet32 (PcdMaxAuthVariableSize) : > mVariableModuleGlobal->MaxVariableSize); > + > + // > + // Parse non-volatile variable data and get last variable offset. > + // > + Variable =3D GetStartPointer (mNvVariableCache); > + while (IsValidVariableHeader (Variable, GetEndPointer > (mNvVariableCache))) { > + NextVariable =3D GetNextVariablePtr (Variable, mVariableModuleGlobal= - > >VariableGlobal.AuthFormat); > + VariableSize =3D (UINTN) NextVariable - (UINTN) Variable; > + if ((Variable->Attributes & (EFI_VARIABLE_NON_VOLATILE | > EFI_VARIABLE_HARDWARE_ERROR_RECORD)) =3D=3D > (EFI_VARIABLE_NON_VOLATILE | > EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { > + mVariableModuleGlobal->HwErrVariableTotalSize +=3D VariableSize; > + } else { > + mVariableModuleGlobal->CommonVariableTotalSize +=3D VariableSize; > + } > + > + Variable =3D NextVariable; > + } > + mVariableModuleGlobal->NonVolatileLastVariableOffset =3D (UINTN) > Variable - (UINTN) mNvVariableCache; > + > + return EFI_SUCCESS; > +} > -- > 2.16.2.windows.1