From nobody Tue Nov 26 16:39:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+49825+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+49825+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1572629990; cv=none; d=zoho.com; s=zohoarc; b=MaFlYC38Imq0mUWBlFew4LtspBNeQfmQeaQRWnWXQqWslILD7/jehJibqiGCp3a1btNr9Wp5qvqBcMjpiL6+RQroZI267F/JD9l7TWcJMFraT5sfoNt69/G+C+hGxAHLDBK7bOXw8SRhx8aZUK8Loz2c2+iE9ep23pkXy6jG7DU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572629990; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=HhTP+v1TGBbUDav3z1AU9TfJOAk4asMTuHYuHk2cq44=; b=KTGSAZCQD4vxHlUYXvhEIZGiOpSg0aLwuOu8lQywFEY+OJkILCMDFJ5J2fRqg/V1PlJSBEykd9j26ONrAvnQISHdiPbrD2+XJ9U2LLQlwwg6Xzh2zzhSyMbkZP7Rvvm/hzwA6Ykr/gPgYJ89JHRJVrHVHsGD06EfBQ97pKe6vt0= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+49825+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1572629990754802.7308816727907; Fri, 1 Nov 2019 10:39:50 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id tjizYY1788612xlNLJT550x6; Fri, 01 Nov 2019 10:39:49 -0700 X-Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web11.79.1572629732142986416 for ; Fri, 01 Nov 2019 10:35:32 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Nov 2019 10:35:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,256,1569308400"; d="scan'208";a="204559555" X-Received: from makuback-desk1.amr.corp.intel.com ([10.7.159.162]) by orsmga006.jf.intel.com with ESMTP; 01 Nov 2019 10:35:31 -0700 From: "Kubacki, Michael A" To: devel@edk2.groups.io Cc: Dandan Bi , Ard Biesheuvel , Eric Dong , Laszlo Ersek , Liming Gao , Michael D Kinney , Ray Ni , Jian J Wang , Hao A Wu , Jiewen Yao Subject: [edk2-devel] [PATCH V7 05/10] MdeModulePkg/Variable: Add a file for NV variable functions Date: Fri, 1 Nov 2019 10:34:52 -0700 Message-Id: <20191101173457.11956-6-michael.a.kubacki@intel.com> In-Reply-To: <20191101173457.11956-1-michael.a.kubacki@intel.com> References: <20191101173457.11956-1-michael.a.kubacki@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,michael.a.kubacki@intel.com X-Gm-Message-State: C6dxt98JQpZSFhS6FLo2a68Ox1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1572629989; bh=r2djjx+gp+mqcG1SfuQRxJR3sD/Ao/DIbn7U6IQ5P3w=; h=Cc:Date:From:Reply-To:Subject:To; b=v1O/aRdjwPzctBBGHqJoP3lBG4fiLq775+BwogDSvoSwqqdmr9y+KTFow+XIDCON7pB aCG0eztuLXh3zvjl7Zi7iqpG7AwPpVc9Q8J0GugN/VFhZq1uEIH0f107Uyk4mOVu9LsEM yBoqbayUPAgFlwYO4NS0Km9pPB9yIdYs0II= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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. 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 + 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/M= deModulePkg/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/VariableStandaloneM= m.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf index ff714b193a..f8a3742959 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf +++ 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 va= riable 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 variab= le 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 Vari= able 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 Vari= able Store is corrupted. + +**/ +EFI_STATUS +InitNonVolatileVariableStore ( + VOID + ); + +#endif diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeMod= ulePkg/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 (PcdMaxAuthVa= riableSize)), - PcdGet32 (PcdMaxHardwareErrorVariableSize)); - } else { - return MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxAuthVariabl= eSize)); - } -} - /** Get maximum variable size, covering both non-volatile and volatile varia= bles. =20 @@ -3122,303 +3104,6 @@ GetMaxVariableSize ( return MaxVariableSize; } =20 -/** - Init real non-volatile variable store. - - @param[out] VariableStoreBase Output pointer to real non-volatile variab= le 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 Vari= able 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 BoottimeReservedNvVariableSpaceSiz= e; - 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 d= ata 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_GU= ID_HOB_DATA (GuidHob); - if (FtwLastWriteData->TargetAddress =3D=3D NvStorageBase) { - DEBUG ((EFI_D_INFO, "Variable: NV storage is backed up in spare bl= ock: 0x%x\n", (UINTN) FtwLastWriteData->SpareAddress)); - // - // Copy the backed up NV storage data to the memory buffer from sp= are block. - // - CopyMem (NvStorageData, (UINT8 *) (UINTN) (FtwLastWriteData->Spare= Address), NvStorageSize); - } else if ((FtwLastWriteData->TargetAddress > NvStorageBase) && - (FtwLastWriteData->TargetAddress < (NvStorageBase + NvSto= rageSize))) { - // - // Flash NV storage from the Offset is backed up in spare block. - // - BackUpOffset =3D (UINT32) (FtwLastWriteData->TargetAddress - NvSto= rageBase); - BackUpSize =3D 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) FtwLastWri= teData->SpareAddress)); - // - // Copy the partial backed up NV storage data to the memory buffer= from spare block. - // - CopyMem (NvStorageData + BackUpOffset, (UINT8 *) (UINTN) FtwLastWr= iteData->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 (&gEfi= SystemNvDataFvGuid, &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 (PcdBoottimeReservedNvV= ariableSpaceSize); - - // - // Note that in EdkII variable driver implementation, Hardware Error Rec= ord 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 t= he value of - // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (Pc= dHwErrStorageSize). - // - ASSERT (MaxUserNvVariableSpaceSize < (VariableStoreLength - sizeof (VARI= ABLE_STORE_HEADER) - HwErrStorageSize)); - // - // Ensure that the value of PcdBoottimeReservedNvVariableSpaceSize is le= ss than the value of - // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (Pc= dHwErrStorageSize). - // - ASSERT (BoottimeReservedNvVariableSpaceSize < (VariableStoreLength - siz= eof (VARIABLE_STORE_HEADER) - HwErrStorageSize)); - - mVariableModuleGlobal->CommonVariableSpace =3D ((UINTN) VariableStoreLen= gth - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize); - mVariableModuleGlobal->CommonMaxUserVariableSpace =3D ((MaxUserNvVariabl= eSpaceSize !=3D 0) ? MaxUserNvVariableSpaceSize : mVariableModuleGlobal->Co= mmonVariableSpace); - mVariableModuleGlobal->CommonRuntimeVariableSpace =3D mVariableModuleGlo= bal->CommonVariableSpace - BoottimeReservedNvVariableSpaceSize; - - DEBUG ((EFI_D_INFO, "Variable driver common space: 0x%x 0x%x 0x%x\n", mV= ariableModuleGlobal->CommonVariableSpace, mVariableModuleGlobal->CommonMaxU= serVariableSpace, mVariableModuleGlobal->CommonRuntimeVariableSpace)); - - // - // The max NV variable size should be < (VariableStoreLength - sizeof (V= ARIABLE_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 va= riable 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 (Varia= bleStoreLength); - if (VariableStore =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - } else { - // - // A memory location has been reserved for the NV variable store. Cer= tain - // platforms may be able to preserve a memory range across system rese= ts, - // thereby providing better NV variable emulation. - // - VariableStore =3D - (VARIABLE_STORE_HEADER *)(VOID*)(UINTN) - PcdGet64 (PcdEmuVariableNvStoreReserved); - if ((VariableStore->Size =3D=3D VariableStoreLength) && - (CompareGuid (&VariableStore->Signature, &gEfiAuthenticatedVariabl= eGuid) || - 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 suppo= rt. - // - 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 Rec= ord 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 =3D ((UINTN) VariableStoreLen= gth - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize); - mVariableModuleGlobal->CommonMaxUserVariableSpace =3D mVariableModuleGlo= bal->CommonVariableSpace; - mVariableModuleGlobal->CommonRuntimeVariableSpace =3D mVariableModuleGlo= bal->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 Vari= able 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-volatil= e variable mode!\n")); - } else { - Status =3D InitRealNonVolatileVariableStore (&VariableStoreBase); - if (EFI_ERROR (Status)) { - return Status; - } - mVariableModuleGlobal->VariableGlobal.EmuNvMode =3D FALSE; - } - - mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase =3D Variab= leStoreBase; - mNvVariableCache =3D (VARIABLE_STORE_HEADER *) (UINTN) VariableStoreBase; - mVariableModuleGlobal->VariableGlobal.AuthFormat =3D (BOOLEAN)(CompareGu= id (&mNvVariableCache->Signature, &gEfiAuthenticatedVariableGuid)); - - mVariableModuleGlobal->MaxVariableSize =3D PcdGet32 (PcdMaxVariableSize); - mVariableModuleGlobal->MaxAuthVariableSize =3D ((PcdGet32 (PcdMaxAuthVar= iableSize) !=3D 0) ? PcdGet32 (PcdMaxAuthVariableSize) : mVariableModuleGlo= bal->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_HA= RDWARE_ERROR_RECORD)) { - mVariableModuleGlobal->HwErrVariableTotalSize +=3D VariableSize; - } else { - mVariableModuleGlobal->CommonVariableTotalSize +=3D VariableSize; - } - - Variable =3D NextVariable; - } - mVariableModuleGlobal->NonVolatileLastVariableOffset =3D (UINTN) Variabl= e - (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 (PcdMaxAuthVa= riableSize)), + PcdGet32 (PcdMaxHardwareErrorVariableSize)); + } else { + return MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxAuthVariabl= eSize)); + } +} + +/** + Init emulated non-volatile variable store. + + @param[out] VariableStoreBase Output pointer to emulated non-volatile va= riable 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 (Varia= bleStoreLength); + if (VariableStore =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + } else { + // + // A memory location has been reserved for the NV variable store. Cer= tain + // platforms may be able to preserve a memory range across system rese= ts, + // thereby providing better NV variable emulation. + // + VariableStore =3D + (VARIABLE_STORE_HEADER *)(VOID*)(UINTN) + PcdGet64 (PcdEmuVariableNvStoreReserved); + if ((VariableStore->Size =3D=3D VariableStoreLength) && + (CompareGuid (&VariableStore->Signature, &gEfiAuthenticatedVariabl= eGuid) || + 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 suppo= rt. + // + 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 Rec= ord 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 =3D ((UINTN) VariableStoreLen= gth - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize); + mVariableModuleGlobal->CommonMaxUserVariableSpace =3D mVariableModuleGlo= bal->CommonVariableSpace; + mVariableModuleGlobal->CommonRuntimeVariableSpace =3D mVariableModuleGlo= bal->CommonVariableSpace; + + return EFI_SUCCESS; +} + +/** + Init real non-volatile variable store. + + @param[out] VariableStoreBase Output pointer to real non-volatile variab= le 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 Vari= able 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 BoottimeReservedNvVariableSpaceSiz= e; + 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 d= ata 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_GU= ID_HOB_DATA (GuidHob); + if (FtwLastWriteData->TargetAddress =3D=3D NvStorageBase) { + DEBUG ((DEBUG_INFO, "Variable: NV storage is backed up in spare bl= ock: 0x%x\n", (UINTN) FtwLastWriteData->SpareAddress)); + // + // Copy the backed up NV storage data to the memory buffer from sp= are block. + // + CopyMem (NvStorageData, (UINT8 *) (UINTN) (FtwLastWriteData->Spare= Address), NvStorageSize); + } else if ((FtwLastWriteData->TargetAddress > NvStorageBase) && + (FtwLastWriteData->TargetAddress < (NvStorageBase + NvSto= rageSize))) { + // + // Flash NV storage from the Offset is backed up in spare block. + // + BackUpOffset =3D (UINT32) (FtwLastWriteData->TargetAddress - NvSto= rageBase); + 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) FtwLastWri= teData->SpareAddress)); + // + // Copy the partial backed up NV storage data to the memory buffer= from spare block. + // + CopyMem (NvStorageData + BackUpOffset, (UINT8 *) (UINTN) FtwLastWr= iteData->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 (&gEfi= SystemNvDataFvGuid, &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 (PcdBoottimeReservedNvV= ariableSpaceSize); + + // + // Note that in EdkII variable driver implementation, Hardware Error Rec= ord 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 t= he value of + // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (Pc= dHwErrStorageSize). + // + ASSERT (MaxUserNvVariableSpaceSize < (VariableStoreLength - sizeof (VARI= ABLE_STORE_HEADER) - HwErrStorageSize)); + // + // Ensure that the value of PcdBoottimeReservedNvVariableSpaceSize is le= ss than the value of + // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (Pc= dHwErrStorageSize). + // + ASSERT (BoottimeReservedNvVariableSpaceSize < (VariableStoreLength - siz= eof (VARIABLE_STORE_HEADER) - HwErrStorageSize)); + + mVariableModuleGlobal->CommonVariableSpace =3D ((UINTN) VariableStoreLen= gth - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize); + mVariableModuleGlobal->CommonMaxUserVariableSpace =3D ((MaxUserNvVariabl= eSpaceSize !=3D 0) ? MaxUserNvVariableSpaceSize : mVariableModuleGlobal->Co= mmonVariableSpace); + mVariableModuleGlobal->CommonRuntimeVariableSpace =3D mVariableModuleGlo= bal->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 (V= ARIABLE_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 Vari= able 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-volatil= e variable mode!\n")); + } else { + Status =3D InitRealNonVolatileVariableStore (&VariableStoreBase); + if (EFI_ERROR (Status)) { + return Status; + } + mVariableModuleGlobal->VariableGlobal.EmuNvMode =3D FALSE; + } + + mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase =3D Variab= leStoreBase; + mNvVariableCache =3D (VARIABLE_STORE_HEADER *) (UINTN) VariableStoreBase; + mVariableModuleGlobal->VariableGlobal.AuthFormat =3D (BOOLEAN)(CompareGu= id (&mNvVariableCache->Signature, &gEfiAuthenticatedVariableGuid)); + + mVariableModuleGlobal->MaxVariableSize =3D PcdGet32 (PcdMaxVariableSize); + mVariableModuleGlobal->MaxAuthVariableSize =3D ((PcdGet32 (PcdMaxAuthVar= iableSize) !=3D 0) ? PcdGet32 (PcdMaxAuthVariableSize) : mVariableModuleGlo= bal->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_HA= RDWARE_ERROR_RECORD)) { + mVariableModuleGlobal->HwErrVariableTotalSize +=3D VariableSize; + } else { + mVariableModuleGlobal->CommonVariableTotalSize +=3D VariableSize; + } + + Variable =3D NextVariable; + } + mVariableModuleGlobal->NonVolatileLastVariableOffset =3D (UINTN) Variabl= e - (UINTN) mNvVariableCache; + + return EFI_SUCCESS; +} --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#49825): https://edk2.groups.io/g/devel/message/49825 Mute This Topic: https://groups.io/mt/40450356/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-