From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.151; helo=mga17.intel.com; envelope-from=jian.j.wang@intel.com; receiver=edk2-devel@lists.01.org Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 951A2211B63DE for ; Mon, 14 Jan 2019 22:03:18 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Jan 2019 22:03:17 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,480,1539673200"; d="scan'208";a="127797648" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by orsmga001.jf.intel.com with ESMTP; 14 Jan 2019 22:03:15 -0800 Received: from fmsmsx111.amr.corp.intel.com (10.18.116.5) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 14 Jan 2019 22:02:51 -0800 Received: from shsmsx154.ccr.corp.intel.com (10.239.6.54) by fmsmsx111.amr.corp.intel.com (10.18.116.5) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 14 Jan 2019 22:02:49 -0800 Received: from shsmsx107.ccr.corp.intel.com ([169.254.9.239]) by SHSMSX154.ccr.corp.intel.com ([169.254.7.46]) with mapi id 14.03.0415.000; Tue, 15 Jan 2019 14:01:13 +0800 From: "Wang, Jian J" To: "Zeng, Star" , "edk2-devel@lists.01.org" CC: "Wu, Hao A" , "Kinney, Michael D" , "Gao, Liming" , "Ni, Ray" , Laszlo Ersek , Ard Biesheuvel Thread-Topic: [PATCH V2 08/15] MdeModulePkg Variable: Add emulated variable NV mode support Thread-Index: AQHUrBytdwknfYPgh0aXqqMb0GX2jaWvwQEw Date: Tue, 15 Jan 2019 06:01:13 +0000 Message-ID: References: <1547479196-40248-1-git-send-email-star.zeng@intel.com> <1547479196-40248-9-git-send-email-star.zeng@intel.com> In-Reply-To: <1547479196-40248-9-git-send-email-star.zeng@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiNDhjMWNkYjItMDZlYy00ZWU2LTkzZWItYzk0MmY4MWIxNWMwIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiMmpwaDlpcXlrZ0swc1o0b28wc2I5M3c5ME1OdWEwbElKdXp5blZOSjRYUkZZUHM0MjhZMEJVc3lLK2ZTU2RQNiJ9 x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.0.400.15 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH V2 08/15] MdeModulePkg Variable: Add emulated variable NV mode support X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jan 2019 06:03:18 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Star, Just two minor comments below. > -----Original Message----- > From: Zeng, Star > Sent: Monday, January 14, 2019 11:20 PM > To: edk2-devel@lists.01.org > Cc: Zeng, Star ; Wang, Jian J ; > Wu, Hao A ; Kinney, Michael D > ; Gao, Liming ; Ni, Ray > ; Laszlo Ersek ; Ard Biesheuvel > > Subject: [PATCH V2 08/15] MdeModulePkg Variable: Add emulated variable NV > mode support >=20 > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D1323 > Merge EmuVariable and Real variable driver. >=20 > Add emulated variable NV mode support in real variable driver. > Platform can configure PcdEmuVariableNvModeEnable statically > (build time) or dynamically (boot time) to support emulated > variable NV mode. >=20 It would be better to mention, although it could be dynamically configured, it's just a one-shot action before this driver is loaded, just in case of any misunderstanding.=20 > Then EmuVariableRuntimeDxe could be removed, the removal of > EmuVariableRuntimeDxe will be done after platforms are migrated > to use the merged variable driver. >=20 > Cc: Jian J Wang > Cc: Hao Wu > Cc: Michael D Kinney > Cc: Liming Gao > Cc: Ray Ni > Cc: Laszlo Ersek > Cc: Ard Biesheuvel > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Star Zeng > --- > .../Universal/Variable/RuntimeDxe/Variable.c | 318 +++++++++++++++= ------ > .../Universal/Variable/RuntimeDxe/Variable.h | 1 + > .../Universal/Variable/RuntimeDxe/VariableDxe.c | 27 +- > .../Variable/RuntimeDxe/VariableRuntimeDxe.inf | 4 +- > .../Universal/Variable/RuntimeDxe/VariableSmm.c | 29 +- > .../Universal/Variable/RuntimeDxe/VariableSmm.inf | 4 +- > 6 files changed, 271 insertions(+), 112 deletions(-) >=20 > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > index 4c8e1d8cf4f1..845276d891ae 100644 > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > @@ -34,6 +34,7 @@ VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal; >=20 > /// > /// Define a memory cache that improves the search performance for a var= iable. > +/// For EmuNvMode =3D=3D TRUE, it will be equal to NonVolatileVariableBa= se. > /// > VARIABLE_STORE_HEADER *mNvVariableCache =3D NULL; >=20 > @@ -273,7 +274,7 @@ UpdateVariableStore ( > // > // Check if the Data is Volatile. > // > - if (!Volatile) { > + if (!Volatile && !mVariableModuleGlobal->VariableGlobal.EmuNvMode) { > if (Fvb =3D=3D NULL) { > return EFI_UNSUPPORTED; > } > @@ -296,17 +297,30 @@ UpdateVariableStore ( > // Data Pointer should point to the actual Address where data is to = be > // written. > // > - VolatileBase =3D (VARIABLE_STORE_HEADER *) ((UINTN) > mVariableModuleGlobal->VariableGlobal.VolatileVariableBase); > - if (SetByIndex) { > - DataPtr +=3D mVariableModuleGlobal->VariableGlobal.VolatileVariabl= eBase; > - } > + if (Volatile) { > + VolatileBase =3D (VARIABLE_STORE_HEADER *) ((UINTN) > mVariableModuleGlobal->VariableGlobal.VolatileVariableBase); > + if (SetByIndex) { > + DataPtr +=3D mVariableModuleGlobal->VariableGlobal.VolatileVaria= bleBase; > + } >=20 > - if ((DataPtr + DataSize) > ((UINTN) VolatileBase + VolatileBase->Siz= e)) { > - return EFI_OUT_OF_RESOURCES; > + if ((DataPtr + DataSize) > ((UINTN) VolatileBase + VolatileBase->S= ize)) { > + return EFI_OUT_OF_RESOURCES; > + } > + } else { > + // > + // Emulated non-volatile variable mode. > + // > + if (SetByIndex) { > + DataPtr +=3D (UINTN) mNvVariableCache; > + } > + > + if ((DataPtr + DataSize) > ((UINTN) mNvVariableCache + mNvVariable= Cache- > >Size)) { > + return EFI_OUT_OF_RESOURCES; > + } > } >=20 > // > - // If Volatile Variable just do a simple mem copy. > + // If Volatile/Emulated Non-volatile Variable just do a simple mem c= opy. > // > CopyMem ((UINT8 *)(UINTN)DataPtr, Buffer, DataSize); > return EFI_SUCCESS; > @@ -987,7 +1001,7 @@ Reclaim ( > CommonUserVariableTotalSize =3D 0; > HwErrVariableTotalSize =3D 0; >=20 > - if (IsVolatile) { > + if (IsVolatile || mVariableModuleGlobal->VariableGlobal.EmuNvMode) { > // > // Start Pointers for the variable. > // > @@ -1155,13 +1169,21 @@ Reclaim ( > CurrPtr +=3D NewVariableSize; > } >=20 > - if (IsVolatile) { > + if (IsVolatile || mVariableModuleGlobal->VariableGlobal.EmuNvMode) { > // > - // If volatile variable store, just copy valid buffer. > + // If volatile/emulated non-volatile variable store, just copy valid= buffer. > // > SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0= xff); > CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) CurrPt= r - > (UINTN) ValidBuffer); > *LastVariableOffset =3D (UINTN) CurrPtr - (UINTN) ValidBuffer; > + if (!IsVolatile) { > + // > + // Emulated non-volatile variable mode. > + // > + mVariableModuleGlobal->HwErrVariableTotalSize =3D HwErrVariableTot= alSize; > + mVariableModuleGlobal->CommonVariableTotalSize =3D > CommonVariableTotalSize; > + mVariableModuleGlobal->CommonUserVariableTotalSize =3D > CommonUserVariableTotalSize; > + } > Status =3D EFI_SUCCESS; > } else { > // > @@ -1200,7 +1222,7 @@ Reclaim ( > } >=20 > Done: > - if (IsVolatile) { > + if (IsVolatile || mVariableModuleGlobal->VariableGlobal.EmuNvMode) { > FreePool (ValidBuffer); > } else { > // > @@ -2147,7 +2169,7 @@ UpdateVariable ( > BOOLEAN IsCommonUserVariable; > AUTHENTICATED_VARIABLE_HEADER *AuthVariable; >=20 > - if (mVariableModuleGlobal->FvbInstance =3D=3D NULL) { > + if (mVariableModuleGlobal->FvbInstance =3D=3D NULL > && !mVariableModuleGlobal->VariableGlobal.EmuNvMode) { > // > // The FVB protocol is not ready, so the > EFI_VARIABLE_WRITE_ARCH_PROTOCOL is not installed. > // > @@ -2566,85 +2588,106 @@ UpdateVariable ( > } > goto Done; > } > - // > - // Four steps > - // 1. Write variable header > - // 2. Set variable state to header valid > - // 3. Write variable data > - // 4. Set variable state to valid > - // > - // > - // Step 1: > - // > - Status =3D UpdateVariableStore ( > - &mVariableModuleGlobal->VariableGlobal, > - FALSE, > - TRUE, > - Fvb, > - mVariableModuleGlobal->NonVolatileLastVariableOffset, > - (UINT32) GetVariableHeaderSize (), > - (UINT8 *) NextVariable > - ); >=20 > - if (EFI_ERROR (Status)) { > - goto Done; > - } > + if (!mVariableModuleGlobal->VariableGlobal.EmuNvMode) { > + // > + // Four steps > + // 1. Write variable header > + // 2. Set variable state to header valid > + // 3. Write variable data > + // 4. Set variable state to valid > + // > + // > + // Step 1: > + // > + Status =3D UpdateVariableStore ( > + &mVariableModuleGlobal->VariableGlobal, > + FALSE, > + TRUE, > + Fvb, > + mVariableModuleGlobal->NonVolatileLastVariableOffset, > + (UINT32) GetVariableHeaderSize (), > + (UINT8 *) NextVariable > + ); >=20 > - // > - // Step 2: > - // > - NextVariable->State =3D VAR_HEADER_VALID_ONLY; > - Status =3D UpdateVariableStore ( > - &mVariableModuleGlobal->VariableGlobal, > - FALSE, > - TRUE, > - Fvb, > - mVariableModuleGlobal->NonVolatileLastVariableOffset + OF= FSET_OF > (VARIABLE_HEADER, State), > - sizeof (UINT8), > - &NextVariable->State > - ); > + if (EFI_ERROR (Status)) { > + goto Done; > + } >=20 > - if (EFI_ERROR (Status)) { > - goto Done; > - } > - // > - // Step 3: > - // > - Status =3D UpdateVariableStore ( > - &mVariableModuleGlobal->VariableGlobal, > - FALSE, > - TRUE, > - Fvb, > - mVariableModuleGlobal->NonVolatileLastVariableOffset + > GetVariableHeaderSize (), > - (UINT32) (VarSize - GetVariableHeaderSize ()), > - (UINT8 *) NextVariable + GetVariableHeaderSize () > - ); > + // > + // Step 2: > + // > + NextVariable->State =3D VAR_HEADER_VALID_ONLY; > + Status =3D UpdateVariableStore ( > + &mVariableModuleGlobal->VariableGlobal, > + FALSE, > + TRUE, > + Fvb, > + mVariableModuleGlobal->NonVolatileLastVariableOffset + > OFFSET_OF (VARIABLE_HEADER, State), > + sizeof (UINT8), > + &NextVariable->State > + ); >=20 > - if (EFI_ERROR (Status)) { > - goto Done; > - } > - // > - // Step 4: > - // > - NextVariable->State =3D VAR_ADDED; > - Status =3D UpdateVariableStore ( > - &mVariableModuleGlobal->VariableGlobal, > - FALSE, > - TRUE, > - Fvb, > - mVariableModuleGlobal->NonVolatileLastVariableOffset + OF= FSET_OF > (VARIABLE_HEADER, State), > - sizeof (UINT8), > - &NextVariable->State > - ); > + if (EFI_ERROR (Status)) { > + goto Done; > + } > + // > + // Step 3: > + // > + Status =3D UpdateVariableStore ( > + &mVariableModuleGlobal->VariableGlobal, > + FALSE, > + TRUE, > + Fvb, > + mVariableModuleGlobal->NonVolatileLastVariableOffset + > GetVariableHeaderSize (), > + (UINT32) (VarSize - GetVariableHeaderSize ()), > + (UINT8 *) NextVariable + GetVariableHeaderSize () > + ); >=20 > - if (EFI_ERROR (Status)) { > - goto Done; > - } > + if (EFI_ERROR (Status)) { > + goto Done; > + } > + // > + // Step 4: > + // > + NextVariable->State =3D VAR_ADDED; > + Status =3D UpdateVariableStore ( > + &mVariableModuleGlobal->VariableGlobal, > + FALSE, > + TRUE, > + Fvb, > + mVariableModuleGlobal->NonVolatileLastVariableOffset + > OFFSET_OF (VARIABLE_HEADER, State), > + sizeof (UINT8), > + &NextVariable->State > + ); >=20 > - // > - // update the memory copy of Flash region. > - // > - CopyMem ((UINT8 *)mNvVariableCache + mVariableModuleGlobal- > >NonVolatileLastVariableOffset, (UINT8 *)NextVariable, VarSize); > + if (EFI_ERROR (Status)) { > + goto Done; > + } > + > + // > + // update the memory copy of Flash region. > + // > + CopyMem ((UINT8 *)mNvVariableCache + mVariableModuleGlobal- > >NonVolatileLastVariableOffset, (UINT8 *)NextVariable, VarSize); > + } else { > + // > + // Emulated non-volatile variable mode. > + // > + NextVariable->State =3D VAR_ADDED; > + Status =3D UpdateVariableStore ( > + &mVariableModuleGlobal->VariableGlobal, > + FALSE, > + TRUE, > + Fvb, > + mVariableModuleGlobal->NonVolatileLastVariableOffset, > + (UINT32) VarSize, > + (UINT8 *) NextVariable > + ); > + > + if (EFI_ERROR (Status)) { > + goto Done; > + } > + } >=20 > mVariableModuleGlobal->NonVolatileLastVariableOffset +=3D HEADER_ALI= GN > (VarSize); >=20 > @@ -3876,6 +3919,93 @@ InitRealNonVolatileVariableStore ( > } >=20 > /** > + 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. C= ertain > + // platforms may be able to preserve a memory range across system re= sets, > + // 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. >=20 > @retval EFI_SUCCESS Function successfully executed. > @@ -3894,9 +4024,19 @@ InitNonVolatileVariableStore ( > UINTN VariableSize; > EFI_STATUS Status; >=20 > - Status =3D InitRealNonVolatileVariableStore (&VariableStoreBase); > - if (EFI_ERROR (Status)) { > - return Status; > + if (!PcdGetBool (PcdEmuVariableNvModeEnable)) { > + Status =3D InitRealNonVolatileVariableStore (&VariableStoreBase); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + mVariableModuleGlobal->VariableGlobal.EmuNvMode =3D FALSE; > + } else { > + 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")); > } >=20 The logic is not wrong, just the if/else style might cause confusion at the first glance. Swapping the if/else might let the code more clear. if (PcdGetBool (PcdEmuVariableNvModeEnable)) { ...initialize emulated variable store... } else { ...initialize the real nv variable store... } > mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase =3D > VariableStoreBase; > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > index 566e7268d187..fdc92b2b017c 100644 > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > @@ -92,6 +92,7 @@ typedef struct { > UINT32 ReentrantState; > BOOLEAN AuthFormat; > BOOLEAN AuthSupport; > + BOOLEAN EmuNvMode; > } VARIABLE_GLOBAL; >=20 > typedef struct { > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c > index 5131e6f351e4..7d5c8b3f842d 100644 > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c > @@ -533,16 +533,23 @@ VariableServiceInitialize ( > ); > ASSERT_EFI_ERROR (Status); >=20 > - // > - // Register FtwNotificationEvent () notify function. > - // > - EfiCreateProtocolNotifyEvent ( > - &gEfiFaultTolerantWriteProtocolGuid, > - TPL_CALLBACK, > - FtwNotificationEvent, > - (VOID *)SystemTable, > - &mFtwRegistration > - ); > + if (!PcdGetBool (PcdEmuVariableNvModeEnable)) { > + // > + // Register FtwNotificationEvent () notify function. > + // > + EfiCreateProtocolNotifyEvent ( > + &gEfiFaultTolerantWriteProtocolGuid, > + TPL_CALLBACK, > + FtwNotificationEvent, > + (VOID *)SystemTable, > + &mFtwRegistration > + ); > + } else { > + // > + // Emulated non-volatile variable mode does not depend on FVB and FT= W. > + // > + VariableWriteServiceInitializeDxe (); > + } >=20 > Status =3D gBS->CreateEventEx ( > EVT_NOTIFY_SIGNAL, > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > index 7ef8a97f5d6a..273067753c25 100644 > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > @@ -9,7 +9,7 @@ > # This external input must be validated carefully to avoid security iss= ues such as > # buffer overflow or integer overflow. > # > -# Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
> +# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
> # This program and the accompanying materials > # are licensed and made available under the terms and conditions of the = BSD > License > # which accompanies this distribution. The full text of the license may = be found > at > @@ -131,6 +131,8 @@ [Pcd] > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxUserNvVariableSpaceSize = ## > CONSUMES >=20 > gEfiMdeModulePkgTokenSpaceGuid.PcdBoottimeReservedNvVariableSpaceSize > ## CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe ## > CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable ## > SOMETIMES_CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved ## > SOMETIMES_CONSUMES >=20 > [FeaturePcd] > gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## > CONSUMES # statistic the information of variable. > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > index e63af812534e..d47493c891e5 100644 > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > @@ -1034,17 +1034,24 @@ VariableServiceInitialize ( > ); > ASSERT_EFI_ERROR (Status); >=20 > - // > - // Register FtwNotificationEvent () notify function. > - // > - Status =3D gSmst->SmmRegisterProtocolNotify ( > - &gEfiSmmFaultTolerantWriteProtocolGuid, > - SmmFtwNotificationEvent, > - &SmmFtwRegistration > - ); > - ASSERT_EFI_ERROR (Status); > - > - SmmFtwNotificationEvent (NULL, NULL, NULL); > + if (!PcdGetBool (PcdEmuVariableNvModeEnable)) { > + // > + // Register FtwNotificationEvent () notify function. > + // > + Status =3D gSmst->SmmRegisterProtocolNotify ( > + &gEfiSmmFaultTolerantWriteProtocolGuid, > + SmmFtwNotificationEvent, > + &SmmFtwRegistration > + ); > + ASSERT_EFI_ERROR (Status); > + > + SmmFtwNotificationEvent (NULL, NULL, NULL); > + } else { > + // > + // Emulated non-volatile variable mode does not depend on FVB and FT= W. > + // > + VariableWriteServiceInitializeSmm (); > + } >=20 > return EFI_SUCCESS; > } > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > index db7d220e06df..30d446d06e0d 100644 > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > @@ -18,7 +18,7 @@ > # may not be modified without authorization. If platform fails to prote= ct these > resources, > # the authentication service provided in this driver will be broken, an= d the > behavior is undefined. > # > -# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
> +# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
> # This program and the accompanying materials > # are licensed and made available under the terms and conditions of the = BSD > License > # which accompanies this distribution. The full text of the license may = be found > at > @@ -133,6 +133,8 @@ [Pcd] > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxUserNvVariableSpaceSize = ## > CONSUMES >=20 > gEfiMdeModulePkgTokenSpaceGuid.PcdBoottimeReservedNvVariableSpaceSize > ## CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe ## > CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable ## > SOMETIMES_CONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved ## > SOMETIMES_CONSUMES >=20 > [FeaturePcd] > gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## > CONSUMES # statistic the information of variable. > -- > 2.7.0.windows.1