A couple of inline comments below:

> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, September 28, 2019 9:47 AM
> To: devel@edk2.groups.io
> Cc: Bi, Dandan; Ard Biesheuvel; Dong, Eric; Laszlo Ersek; Gao, Liming; Kinney,
> Michael D; Ni, Ray; Wang, Jian J; Wu, Hao A; Yao, Jiewen
> Subject: [PATCH V2 1/9] MdeModulePkg/Variable: Consolidate common
> parsing functions
> 
> This change moves the following functions into a dedicated file
> so they may be used in other variable files as needed. Furthermore,
> it reduces the overall size of the common Variable.c file.
> 
>  * DataSizeOfVariable ()
>  * FindVariableEx ()
>  * GetEndPointer ()
>  * GetNextVariablePtr ()
>  * GetStartPointer ()
>  * GetVariableDataOffset ()
>  * GetVariableDataPtr ()
>  * GetVariableHeaderSize ()
>  * GetVariableNamePtr ()
>  * GetVariableStoreStatus ()
>  * GetVendorGuidPtr ()
>  * IsValidVariableHeader ()
>  * NameSizeOfVariable ()
>  * SetDataSizeOfVariable ()
>  * SetNameSizeOfVariable ()
>  * UpdateVariableInfo ()
>  * VariableCompareTimeStampInternal ()
>  * VariableServiceGetNextVariableInternal ()


May I know what are the criteria for the above functions being moved to a
separate file?

At first, I think all of them will be consumed by the new codes that implement
the runtime cache. But I found that, for functions like GetVariableDataOffset(),
GetVariableStoreStatus() and etc., their usages are still remained within file
Variable.c (seems not related with the runtime cache).


> 
> Cc: Dandan Bi <dandan...@intel.com>
> Cc: Ard Biesheuvel <ard.biesheu...@linaro.org>
> Cc: Eric Dong <eric.d...@intel.com>
> Cc: Laszlo Ersek <ler...@redhat.com>
> Cc: Liming Gao <liming....@intel.com>
> Cc: Michael D Kinney <michael.d.kin...@intel.com>
> Cc: Ray Ni <ray...@intel.com>
> Cc: Jian J Wang <jian.j.w...@intel.com>
> Cc: Hao A Wu <hao.a...@intel.com>
> Cc: Jiewen Yao <jiewen....@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kuba...@intel.com>
> ---
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> |   2 +
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf          |   2
> +
> 
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> |   7 +
>  MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h               | 119 
> ----
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h        | 306
> ++++++++
>  MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c               | 726 +--
> ----------------
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c          |   3 +-
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c        | 731
> ++++++++++++++++++++
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c            |   1 +
>  9 files changed, 1052 insertions(+), 845 deletions(-)


For the below change in VariableStandaloneMm.inf:

[Guids]
...
  ## SOMETIMES_CONSUMES   ## Variable:L"db"
  ## SOMETIMES_CONSUMES   ## Variable:L"dbx"
  ## SOMETIMES_CONSUMES   ## Variable:L"dbt"
  gEfiImageSecurityDatabaseGuid
...

I think the above GUID is not used by the module specified by the above INF.
Could you double confirm on this?

Best Regards,
Hao Wu


> 
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> index 641376c9c5..c35e5fe787 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
> +  VariableParsing.c
> +  VariableParsing.h
>    PrivilegePolymorphic.h
>    Measurement.c
>    TcgMorLockDxe.c
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
> index 0a160d269d..626738b9c7 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
> +  VariableParsing.c
> +  VariableParsing.h
>    VarCheck.c
>    Variable.h
>    PrivilegePolymorphic.h
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.i
> nf
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.
> inf
> index 21bc81163b..1ba8f9ebfb 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
> +  VariableParsing.c
> +  VariableParsing.h
>    VarCheck.c
>    Variable.h
>    PrivilegePolymorphic.h
> @@ -99,6 +101,11 @@
>    ## SOMETIMES_PRODUCES   ## Variable:L"Lang"
>    gEfiGlobalVariableGuid
> 
> +  ## SOMETIMES_CONSUMES   ## Variable:L"db"
> +  ## SOMETIMES_CONSUMES   ## Variable:L"dbx"
> +  ## SOMETIMES_CONSUMES   ## Variable:L"dbt"
> +  gEfiImageSecurityDatabaseGuid
> +
>    gEfiMemoryOverwriteControlDataGuid            ## SOMETIMES_CONSUMES
> ## Variable:L"MemoryOverwriteRequestControl"
>    gEfiMemoryOverwriteRequestControlLockGuid     ##
> SOMETIMES_PRODUCES   ##
> Variable:L"MemoryOverwriteRequestControlLock"
> 
> diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
> index 9eac43759f..fb574b2e32 100644
> --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
> +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
> @@ -179,89 +179,6 @@ FindVariable (
>    IN  BOOLEAN                 IgnoreRtCheck
>    );
> 
> -/**
> -
> -  Gets the pointer to the end of the variable storage area.
> -
> -  This function gets pointer to the end of the variable storage
> -  area, according to the input variable store header.
> -
> -  @param VarStoreHeader  Pointer to the Variable Store Header.
> -
> -  @return Pointer to the end of the variable storage area.
> -
> -**/
> -VARIABLE_HEADER *
> -GetEndPointer (
> -  IN VARIABLE_STORE_HEADER       *VarStoreHeader
> -  );
> -
> -/**
> -  This code gets the size of variable header.
> -
> -  @return Size of variable header in bytes in type UINTN.
> -
> -**/
> -UINTN
> -GetVariableHeaderSize (
> -  VOID
> -  );
> -
> -/**
> -
> -  This code gets the pointer to the variable name.
> -
> -  @param Variable        Pointer to the Variable Header.
> -
> -  @return Pointer to Variable Name which is Unicode encoding.
> -
> -**/
> -CHAR16 *
> -GetVariableNamePtr (
> -  IN  VARIABLE_HEADER   *Variable
> -  );
> -
> -/**
> -  This code gets the pointer to the variable guid.
> -
> -  @param Variable   Pointer to the Variable Header.
> -
> -  @return A EFI_GUID* pointer to Vendor Guid.
> -
> -**/
> -EFI_GUID *
> -GetVendorGuidPtr (
> -  IN VARIABLE_HEADER    *Variable
> -  );
> -
> -/**
> -
> -  This code gets the pointer to the variable data.
> -
> -  @param Variable        Pointer to the Variable Header.
> -
> -  @return Pointer to Variable Data.
> -
> -**/
> -UINT8 *
> -GetVariableDataPtr (
> -  IN  VARIABLE_HEADER   *Variable
> -  );
> -
> -/**
> -
> -  This code gets the size of variable data.
> -
> -  @param Variable        Pointer to the Variable Header.
> -
> -  @return Size of variable in bytes.
> -
> -**/
> -UINTN
> -DataSizeOfVariable (
> -  IN  VARIABLE_HEADER   *Variable
> -  );
> -
>  /**
>    This function is to check if the remaining variable space is enough to set
>    all Variables from argument list successfully. The purpose of the check
> @@ -450,17 +367,6 @@ ReclaimForOS(
>    VOID
>    );
> 
> -/**
> -  Get non-volatile maximum variable size.
> -
> -  @return Non-volatile maximum variable size.
> -
> -**/
> -UINTN
> -GetNonVolatileMaxVariableSize (
> -  VOID
> -  );
> -
>  /**
>    Get maximum variable size, covering both non-volatile and volatile 
> variables.
> 
> @@ -546,31 +452,6 @@ VariableServiceGetVariable (
>    OUT     VOID              *Data OPTIONAL
>    );
> 
> -/**
> -  This code Finds the Next available variable.
> -
> -  Caution: This function may receive untrusted input.
> -  This function may be invoked in SMM mode. This function will do basic
> validation, before parse the data.
> -
> -  @param[in] VariableName   Pointer to variable name.
> -  @param[in] VendorGuid     Variable Vendor Guid.
> -  @param[out] VariablePtr   Pointer to variable header address.
> -
> -  @retval EFI_SUCCESS           The function completed successfully.
> -  @retval EFI_NOT_FOUND         The next variable was not found.
> -  @retval EFI_INVALID_PARAMETER If VariableName is not an empty string,
> while VendorGuid is NULL.
> -  @retval EFI_INVALID_PARAMETER The input values of VariableName and
> VendorGuid are not a name and
> -                                GUID of an existing variable.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -VariableServiceGetNextVariableInternal (
> -  IN  CHAR16                *VariableName,
> -  IN  EFI_GUID              *VendorGuid,
> -  OUT VARIABLE_HEADER       **VariablePtr
> -  );
> -
>  /**
> 
>    This code Finds the Next available variable.
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h
> new file mode 100644
> index 0000000000..9d77c4916c
> --- /dev/null
> +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h
> @@ -0,0 +1,306 @@
> +/** @file
> +  Functions in this module are associated with variable parsing operations
> and
> +  are intended to be usable across variable driver source files.
> +
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _VARIABLE_PARSING_H_
> +#define _VARIABLE_PARSING_H_
> +
> +#include <Guid/ImageAuthentication.h>
> +#include "Variable.h"
> +
> +/**
> +
> +  This code checks if variable header is valid or not.
> +
> +  @param Variable           Pointer to the Variable Header.
> +  @param VariableStoreEnd   Pointer to the Variable Store End.
> +
> +  @retval TRUE              Variable header is valid.
> +  @retval FALSE             Variable header is not valid.
> +
> +**/
> +BOOLEAN
> +IsValidVariableHeader (
> +  IN  VARIABLE_HEADER       *Variable,
> +  IN  VARIABLE_HEADER       *VariableStoreEnd
> +  );
> +
> +/**
> +
> +  This code gets the current status of Variable Store.
> +
> +  @param VarStoreHeader  Pointer to the Variable Store Header.
> +
> +  @retval EfiRaw         Variable store status is raw.
> +  @retval EfiValid       Variable store status is valid.
> +  @retval EfiInvalid     Variable store status is invalid.
> +
> +**/
> +VARIABLE_STORE_STATUS
> +GetVariableStoreStatus (
> +  IN VARIABLE_STORE_HEADER *VarStoreHeader
> +  );
> +
> +/**
> +  This code gets the size of variable header.
> +
> +  @return Size of variable header in bytes in type UINTN.
> +
> +**/
> +UINTN
> +GetVariableHeaderSize (
> +  VOID
> +  );
> +
> +/**
> +
> +  This code gets the size of name of variable.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return UINTN          Size of variable in bytes.
> +
> +**/
> +UINTN
> +NameSizeOfVariable (
> +  IN  VARIABLE_HEADER   *Variable
> +  );
> +
> +/**
> +  This code sets the size of name of variable.
> +
> +  @param[in] Variable   Pointer to the Variable Header.
> +  @param[in] NameSize   Name size to set.
> +
> +**/
> +VOID
> +SetNameSizeOfVariable (
> +  IN VARIABLE_HEADER    *Variable,
> +  IN UINTN              NameSize
> +  );
> +
> +/**
> +
> +  This code gets the size of variable data.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return Size of variable in bytes.
> +
> +**/
> +UINTN
> +DataSizeOfVariable (
> +  IN  VARIABLE_HEADER   *Variable
> +  );
> +
> +/**
> +  This code sets the size of variable data.
> +
> +  @param[in] Variable   Pointer to the Variable Header.
> +  @param[in] DataSize   Data size to set.
> +
> +**/
> +VOID
> +SetDataSizeOfVariable (
> +  IN VARIABLE_HEADER    *Variable,
> +  IN UINTN              DataSize
> +  );
> +
> +/**
> +
> +  This code gets the pointer to the variable name.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return Pointer to Variable Name which is Unicode encoding.
> +
> +**/
> +CHAR16 *
> +GetVariableNamePtr (
> +  IN  VARIABLE_HEADER   *Variable
> +  );
> +
> +/**
> +  This code gets the pointer to the variable guid.
> +
> +  @param Variable   Pointer to the Variable Header.
> +
> +  @return A EFI_GUID* pointer to Vendor Guid.
> +
> +**/
> +EFI_GUID *
> +GetVendorGuidPtr (
> +  IN VARIABLE_HEADER    *Variable
> +  );
> +
> +/**
> +
> +  This code gets the pointer to the variable data.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return Pointer to Variable Data.
> +
> +**/
> +UINT8 *
> +GetVariableDataPtr (
> +  IN  VARIABLE_HEADER   *Variable
> +  );
> +
> +/**
> +  This code gets the variable data offset related to variable header.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return Variable Data offset.
> +
> +**/
> +UINTN
> +GetVariableDataOffset (
> +  IN  VARIABLE_HEADER   *Variable
> +  );
> +
> +/**
> +
> +  This code gets the pointer to the next variable header.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return Pointer to next variable header.
> +
> +**/
> +VARIABLE_HEADER *
> +GetNextVariablePtr (
> +  IN  VARIABLE_HEADER   *Variable
> +  );
> +
> +/**
> +
> +  Gets the pointer to the first variable header in given variable store area.
> +
> +  @param VarStoreHeader  Pointer to the Variable Store Header.
> +
> +  @return Pointer to the first variable header.
> +
> +**/
> +VARIABLE_HEADER *
> +GetStartPointer (
> +  IN VARIABLE_STORE_HEADER       *VarStoreHeader
> +  );
> +
> +/**
> +
> +  Gets the pointer to the end of the variable storage area.
> +
> +  This function gets pointer to the end of the variable storage
> +  area, according to the input variable store header.
> +
> +  @param VarStoreHeader  Pointer to the Variable Store Header.
> +
> +  @return Pointer to the end of the variable storage area.
> +
> +**/
> +VARIABLE_HEADER *
> +GetEndPointer (
> +  IN VARIABLE_STORE_HEADER       *VarStoreHeader
> +  );
> +
> +/**
> +  Compare two EFI_TIME data.
> +
> +
> +  @param FirstTime           A pointer to the first EFI_TIME data.
> +  @param SecondTime          A pointer to the second EFI_TIME data.
> +
> +  @retval  TRUE              The FirstTime is not later than the SecondTime.
> +  @retval  FALSE             The FirstTime is later than the SecondTime.
> +
> +**/
> +BOOLEAN
> +VariableCompareTimeStampInternal (
> +  IN EFI_TIME               *FirstTime,
> +  IN EFI_TIME               *SecondTime
> +  );
> +
> +/**
> +  Find the variable in the specified variable store.
> +
> +  @param[in]       VariableName        Name of the variable to be found
> +  @param[in]       VendorGuid          Vendor GUID to be found.
> +  @param[in]       IgnoreRtCheck       Ignore EFI_VARIABLE_RUNTIME_ACCESS
> attribute
> +                                       check at runtime when searching 
> variable.
> +  @param[in, out]  PtrTrack            Variable Track Pointer structure that
> contains Variable Information.
> +
> +  @retval          EFI_SUCCESS         Variable found successfully
> +  @retval          EFI_NOT_FOUND       Variable not found
> +**/
> +EFI_STATUS
> +FindVariableEx (
> +  IN     CHAR16                  *VariableName,
> +  IN     EFI_GUID                *VendorGuid,
> +  IN     BOOLEAN                 IgnoreRtCheck,
> +  IN OUT VARIABLE_POINTER_TRACK  *PtrTrack
> +  );
> +
> +/**
> +  This code Finds the Next available variable.
> +
> +  Caution: This function may receive untrusted input.
> +  This function may be invoked in SMM mode. This function will do basic
> validation, before parse the data.
> +
> +  @param[in]  VariableName  Pointer to variable name.
> +  @param[in]  VendorGuid    Variable Vendor Guid.
> +  @param[out] VariablePtr   Pointer to variable header address.
> +
> +  @retval EFI_SUCCESS           The function completed successfully.
> +  @retval EFI_NOT_FOUND         The next variable was not found.
> +  @retval EFI_INVALID_PARAMETER If VariableName is not an empty string,
> while VendorGuid is NULL.
> +  @retval EFI_INVALID_PARAMETER The input values of VariableName and
> VendorGuid are not a name and
> +                                GUID of an existing variable.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VariableServiceGetNextVariableInternal (
> +  IN  CHAR16                *VariableName,
> +  IN  EFI_GUID              *VendorGuid,
> +  OUT VARIABLE_HEADER       **VariablePtr
> +  );
> +
> +/**
> +  Routine used to track statistical information about variable usage.
> +  The data is stored in the EFI system table so it can be accessed later.
> +  VariableInfo.efi can dump out the table. Only Boot Services variable
> +  accesses are tracked by this code. The PcdVariableCollectStatistics
> +  build flag controls if this feature is enabled.
> +
> +  A read that hits in the cache will have Read and Cache true for
> +  the transaction. Data is allocated by this routine, but never
> +  freed.
> +
> +  @param[in] VariableName   Name of the Variable to track.
> +  @param[in] VendorGuid     Guid of the Variable to track.
> +  @param[in] Volatile       TRUE if volatile FALSE if non-volatile.
> +  @param[in] Read           TRUE if GetVariable() was called.
> +  @param[in] Write          TRUE if SetVariable() was called.
> +  @param[in] Delete         TRUE if deleted via SetVariable().
> +  @param[in] Cache          TRUE for a cache hit.
> +
> +**/
> +VOID
> +UpdateVariableInfo (
> +  IN  CHAR16                  *VariableName,
> +  IN  EFI_GUID                *VendorGuid,
> +  IN  BOOLEAN                 Volatile,
> +  IN  BOOLEAN                 Read,
> +  IN  BOOLEAN                 Write,
> +  IN  BOOLEAN                 Delete,
> +  IN  BOOLEAN                 Cache
> +  );
> +
> +#endif
> diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
> index f32c9c2808..76536308e6 100644
> --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
> +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
> @@ -23,6 +23,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>  **/
> 
>  #include "Variable.h"
> +#include "VariableParsing.h"
> 
>  VARIABLE_MODULE_GLOBAL  *mVariableModuleGlobal;
> 
> @@ -92,131 +93,6 @@ AUTH_VAR_LIB_CONTEXT_IN mAuthContextIn = {
> 
>  AUTH_VAR_LIB_CONTEXT_OUT mAuthContextOut;
> 
> -/**
> -  Routine used to track statistical information about variable usage.
> -  The data is stored in the EFI system table so it can be accessed later.
> -  VariableInfo.efi can dump out the table. Only Boot Services variable
> -  accesses are tracked by this code. The PcdVariableCollectStatistics
> -  build flag controls if this feature is enabled.
> -
> -  A read that hits in the cache will have Read and Cache true for
> -  the transaction. Data is allocated by this routine, but never
> -  freed.
> -
> -  @param[in] VariableName   Name of the Variable to track.
> -  @param[in] VendorGuid     Guid of the Variable to track.
> -  @param[in] Volatile       TRUE if volatile FALSE if non-volatile.
> -  @param[in] Read           TRUE if GetVariable() was called.
> -  @param[in] Write          TRUE if SetVariable() was called.
> -  @param[in] Delete         TRUE if deleted via SetVariable().
> -  @param[in] Cache          TRUE for a cache hit.
> -
> -**/
> -VOID
> -UpdateVariableInfo (
> -  IN  CHAR16                  *VariableName,
> -  IN  EFI_GUID                *VendorGuid,
> -  IN  BOOLEAN                 Volatile,
> -  IN  BOOLEAN                 Read,
> -  IN  BOOLEAN                 Write,
> -  IN  BOOLEAN                 Delete,
> -  IN  BOOLEAN                 Cache
> -  )
> -{
> -  VARIABLE_INFO_ENTRY   *Entry;
> -
> -  if (FeaturePcdGet (PcdVariableCollectStatistics)) {
> -
> -    if (AtRuntime ()) {
> -      // Don't collect statistics at runtime.
> -      return;
> -    }
> -
> -    if (gVariableInfo == NULL) {
> -      //
> -      // On the first call allocate a entry and place a pointer to it in
> -      // the EFI System Table.
> -      //
> -      gVariableInfo = AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY));
> -      ASSERT (gVariableInfo != NULL);
> -
> -      CopyGuid (&gVariableInfo->VendorGuid, VendorGuid);
> -      gVariableInfo->Name = AllocateZeroPool (StrSize (VariableName));
> -      ASSERT (gVariableInfo->Name != NULL);
> -      StrCpyS (gVariableInfo->Name, StrSize(VariableName)/sizeof(CHAR16),
> VariableName);
> -      gVariableInfo->Volatile = Volatile;
> -    }
> -
> -
> -    for (Entry = gVariableInfo; Entry != NULL; Entry = Entry->Next) {
> -      if (CompareGuid (VendorGuid, &Entry->VendorGuid)) {
> -        if (StrCmp (VariableName, Entry->Name) == 0) {
> -          if (Read) {
> -            Entry->ReadCount++;
> -          }
> -          if (Write) {
> -            Entry->WriteCount++;
> -          }
> -          if (Delete) {
> -            Entry->DeleteCount++;
> -          }
> -          if (Cache) {
> -            Entry->CacheCount++;
> -          }
> -
> -          return;
> -        }
> -      }
> -
> -      if (Entry->Next == NULL) {
> -        //
> -        // If the entry is not in the table add it.
> -        // Next iteration of the loop will fill in the data.
> -        //
> -        Entry->Next = AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY));
> -        ASSERT (Entry->Next != NULL);
> -
> -        CopyGuid (&Entry->Next->VendorGuid, VendorGuid);
> -        Entry->Next->Name = AllocateZeroPool (StrSize (VariableName));
> -        ASSERT (Entry->Next->Name != NULL);
> -        StrCpyS (Entry->Next->Name, StrSize(VariableName)/sizeof(CHAR16),
> VariableName);
> -        Entry->Next->Volatile = Volatile;
> -      }
> -
> -    }
> -  }
> -}
> -
> -
> -/**
> -
> -  This code checks if variable header is valid or not.
> -
> -  @param Variable           Pointer to the Variable Header.
> -  @param VariableStoreEnd   Pointer to the Variable Store End.
> -
> -  @retval TRUE              Variable header is valid.
> -  @retval FALSE             Variable header is not valid.
> -
> -**/
> -BOOLEAN
> -IsValidVariableHeader (
> -  IN  VARIABLE_HEADER       *Variable,
> -  IN  VARIABLE_HEADER       *VariableStoreEnd
> -  )
> -{
> -  if ((Variable == NULL) || (Variable >= VariableStoreEnd) || (Variable-
> >StartId != VARIABLE_DATA)) {
> -    //
> -    // Variable is NULL or has reached the end of variable store,
> -    // or the StartId is not correct.
> -    //
> -    return FALSE;
> -  }
> -
> -  return TRUE;
> -}
> -
> -
>  /**
> 
>    This function writes data to the FWH at the correct LBA even if the LBAs
> @@ -376,345 +252,6 @@ UpdateVariableStore (
>    return EFI_SUCCESS;
>  }
> 
> -
> -/**
> -
> -  This code gets the current status of Variable Store.
> -
> -  @param VarStoreHeader  Pointer to the Variable Store Header.
> -
> -  @retval EfiRaw         Variable store status is raw.
> -  @retval EfiValid       Variable store status is valid.
> -  @retval EfiInvalid     Variable store status is invalid.
> -
> -**/
> -VARIABLE_STORE_STATUS
> -GetVariableStoreStatus (
> -  IN VARIABLE_STORE_HEADER *VarStoreHeader
> -  )
> -{
> -  if ((CompareGuid (&VarStoreHeader->Signature,
> &gEfiAuthenticatedVariableGuid) ||
> -       CompareGuid (&VarStoreHeader->Signature, &gEfiVariableGuid)) &&
> -      VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&
> -      VarStoreHeader->State == VARIABLE_STORE_HEALTHY
> -      ) {
> -
> -    return EfiValid;
> -  } else if (((UINT32 *)(&VarStoreHeader->Signature))[0] == 0xffffffff &&
> -             ((UINT32 *)(&VarStoreHeader->Signature))[1] == 0xffffffff &&
> -             ((UINT32 *)(&VarStoreHeader->Signature))[2] == 0xffffffff &&
> -             ((UINT32 *)(&VarStoreHeader->Signature))[3] == 0xffffffff &&
> -             VarStoreHeader->Size == 0xffffffff &&
> -             VarStoreHeader->Format == 0xff &&
> -             VarStoreHeader->State == 0xff
> -          ) {
> -
> -    return EfiRaw;
> -  } else {
> -    return EfiInvalid;
> -  }
> -}
> -
> -/**
> -  This code gets the size of variable header.
> -
> -  @return Size of variable header in bytes in type UINTN.
> -
> -**/
> -UINTN
> -GetVariableHeaderSize (
> -  VOID
> -  )
> -{
> -  UINTN Value;
> -
> -  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> -    Value = sizeof (AUTHENTICATED_VARIABLE_HEADER);
> -  } else {
> -    Value = sizeof (VARIABLE_HEADER);
> -  }
> -
> -  return Value;
> -}
> -
> -/**
> -
> -  This code gets the size of name of variable.
> -
> -  @param Variable        Pointer to the Variable Header.
> -
> -  @return UINTN          Size of variable in bytes.
> -
> -**/
> -UINTN
> -NameSizeOfVariable (
> -  IN  VARIABLE_HEADER   *Variable
> -  )
> -{
> -  AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
> -
> -  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable;
> -  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> -    if (AuthVariable->State == (UINT8) (-1) ||
> -       AuthVariable->DataSize == (UINT32) (-1) ||
> -       AuthVariable->NameSize == (UINT32) (-1) ||
> -       AuthVariable->Attributes == (UINT32) (-1)) {
> -      return 0;
> -    }
> -    return (UINTN) AuthVariable->NameSize;
> -  } else {
> -    if (Variable->State == (UINT8) (-1) ||
> -        Variable->DataSize == (UINT32) (-1) ||
> -        Variable->NameSize == (UINT32) (-1) ||
> -        Variable->Attributes == (UINT32) (-1)) {
> -      return 0;
> -    }
> -    return (UINTN) Variable->NameSize;
> -  }
> -}
> -
> -/**
> -  This code sets the size of name of variable.
> -
> -  @param[in] Variable   Pointer to the Variable Header.
> -  @param[in] NameSize   Name size to set.
> -
> -**/
> -VOID
> -SetNameSizeOfVariable (
> -  IN VARIABLE_HEADER    *Variable,
> -  IN UINTN              NameSize
> -  )
> -{
> -  AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
> -
> -  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable;
> -  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> -    AuthVariable->NameSize = (UINT32) NameSize;
> -  } else {
> -    Variable->NameSize = (UINT32) NameSize;
> -  }
> -}
> -
> -/**
> -
> -  This code gets the size of variable data.
> -
> -  @param Variable        Pointer to the Variable Header.
> -
> -  @return Size of variable in bytes.
> -
> -**/
> -UINTN
> -DataSizeOfVariable (
> -  IN  VARIABLE_HEADER   *Variable
> -  )
> -{
> -  AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
> -
> -  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable;
> -  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> -    if (AuthVariable->State == (UINT8) (-1) ||
> -       AuthVariable->DataSize == (UINT32) (-1) ||
> -       AuthVariable->NameSize == (UINT32) (-1) ||
> -       AuthVariable->Attributes == (UINT32) (-1)) {
> -      return 0;
> -    }
> -    return (UINTN) AuthVariable->DataSize;
> -  } else {
> -    if (Variable->State == (UINT8) (-1) ||
> -        Variable->DataSize == (UINT32) (-1) ||
> -        Variable->NameSize == (UINT32) (-1) ||
> -        Variable->Attributes == (UINT32) (-1)) {
> -      return 0;
> -    }
> -    return (UINTN) Variable->DataSize;
> -  }
> -}
> -
> -/**
> -  This code sets the size of variable data.
> -
> -  @param[in] Variable   Pointer to the Variable Header.
> -  @param[in] DataSize   Data size to set.
> -
> -**/
> -VOID
> -SetDataSizeOfVariable (
> -  IN VARIABLE_HEADER    *Variable,
> -  IN UINTN              DataSize
> -  )
> -{
> -  AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
> -
> -  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable;
> -  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> -    AuthVariable->DataSize = (UINT32) DataSize;
> -  } else {
> -    Variable->DataSize = (UINT32) DataSize;
> -  }
> -}
> -
> -/**
> -
> -  This code gets the pointer to the variable name.
> -
> -  @param Variable        Pointer to the Variable Header.
> -
> -  @return Pointer to Variable Name which is Unicode encoding.
> -
> -**/
> -CHAR16 *
> -GetVariableNamePtr (
> -  IN  VARIABLE_HEADER   *Variable
> -  )
> -{
> -  return (CHAR16 *) ((UINTN) Variable + GetVariableHeaderSize ());
> -}
> -
> -/**
> -  This code gets the pointer to the variable guid.
> -
> -  @param Variable   Pointer to the Variable Header.
> -
> -  @return A EFI_GUID* pointer to Vendor Guid.
> -
> -**/
> -EFI_GUID *
> -GetVendorGuidPtr (
> -  IN VARIABLE_HEADER    *Variable
> -  )
> -{
> -  AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
> -
> -  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable;
> -  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> -    return &AuthVariable->VendorGuid;
> -  } else {
> -    return &Variable->VendorGuid;
> -  }
> -}
> -
> -/**
> -
> -  This code gets the pointer to the variable data.
> -
> -  @param Variable        Pointer to the Variable Header.
> -
> -  @return Pointer to Variable Data.
> -
> -**/
> -UINT8 *
> -GetVariableDataPtr (
> -  IN  VARIABLE_HEADER   *Variable
> -  )
> -{
> -  UINTN Value;
> -
> -  //
> -  // Be careful about pad size for alignment.
> -  //
> -  Value =  (UINTN) GetVariableNamePtr (Variable);
> -  Value += NameSizeOfVariable (Variable);
> -  Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));
> -
> -  return (UINT8 *) Value;
> -}
> -
> -/**
> -  This code gets the variable data offset related to variable header.
> -
> -  @param Variable        Pointer to the Variable Header.
> -
> -  @return Variable Data offset.
> -
> -**/
> -UINTN
> -GetVariableDataOffset (
> -  IN  VARIABLE_HEADER   *Variable
> -  )
> -{
> -  UINTN Value;
> -
> -  //
> -  // Be careful about pad size for alignment
> -  //
> -  Value = GetVariableHeaderSize ();
> -  Value += NameSizeOfVariable (Variable);
> -  Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));
> -
> -  return Value;
> -}
> -
> -/**
> -
> -  This code gets the pointer to the next variable header.
> -
> -  @param Variable        Pointer to the Variable Header.
> -
> -  @return Pointer to next variable header.
> -
> -**/
> -VARIABLE_HEADER *
> -GetNextVariablePtr (
> -  IN  VARIABLE_HEADER   *Variable
> -  )
> -{
> -  UINTN Value;
> -
> -  Value =  (UINTN) GetVariableDataPtr (Variable);
> -  Value += DataSizeOfVariable (Variable);
> -  Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));
> -
> -  //
> -  // Be careful about pad size for alignment.
> -  //
> -  return (VARIABLE_HEADER *) HEADER_ALIGN (Value);
> -}
> -
> -/**
> -
> -  Gets the pointer to the first variable header in given variable store area.
> -
> -  @param VarStoreHeader  Pointer to the Variable Store Header.
> -
> -  @return Pointer to the first variable header.
> -
> -**/
> -VARIABLE_HEADER *
> -GetStartPointer (
> -  IN VARIABLE_STORE_HEADER       *VarStoreHeader
> -  )
> -{
> -  //
> -  // The start of variable store.
> -  //
> -  return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);
> -}
> -
> -/**
> -
> -  Gets the pointer to the end of the variable storage area.
> -
> -  This function gets pointer to the end of the variable storage
> -  area, according to the input variable store header.
> -
> -  @param VarStoreHeader  Pointer to the Variable Store Header.
> -
> -  @return Pointer to the end of the variable storage area.
> -
> -**/
> -VARIABLE_HEADER *
> -GetEndPointer (
> -  IN VARIABLE_STORE_HEADER       *VarStoreHeader
> -  )
> -{
> -  //
> -  // The end of variable store
> -  //
> -  return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader +
> VarStoreHeader->Size);
> -}
> -
>  /**
>    Record variable error flag.
> 
> @@ -1228,75 +765,6 @@ Done:
>    return Status;
>  }
> 
> -/**
> -  Find the variable in the specified variable store.
> -
> -  @param[in]       VariableName        Name of the variable to be found
> -  @param[in]       VendorGuid          Vendor GUID to be found.
> -  @param[in]       IgnoreRtCheck       Ignore EFI_VARIABLE_RUNTIME_ACCESS
> attribute
> -                                       check at runtime when searching 
> variable.
> -  @param[in, out]  PtrTrack            Variable Track Pointer structure that
> contains Variable Information.
> -
> -  @retval          EFI_SUCCESS         Variable found successfully
> -  @retval          EFI_NOT_FOUND       Variable not found
> -**/
> -EFI_STATUS
> -FindVariableEx (
> -  IN     CHAR16                  *VariableName,
> -  IN     EFI_GUID                *VendorGuid,
> -  IN     BOOLEAN                 IgnoreRtCheck,
> -  IN OUT VARIABLE_POINTER_TRACK  *PtrTrack
> -  )
> -{
> -  VARIABLE_HEADER                *InDeletedVariable;
> -  VOID                           *Point;
> -
> -  PtrTrack->InDeletedTransitionPtr = NULL;
> -
> -  //
> -  // Find the variable by walk through HOB, volatile and non-volatile 
> variable
> store.
> -  //
> -  InDeletedVariable  = NULL;
> -
> -  for ( PtrTrack->CurrPtr = PtrTrack->StartPtr
> -      ; IsValidVariableHeader (PtrTrack->CurrPtr, PtrTrack->EndPtr)
> -      ; PtrTrack->CurrPtr = GetNextVariablePtr (PtrTrack->CurrPtr)
> -      ) {
> -    if (PtrTrack->CurrPtr->State == VAR_ADDED ||
> -        PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION &
> VAR_ADDED)
> -       ) {
> -      if (IgnoreRtCheck || !AtRuntime () || ((PtrTrack->CurrPtr->Attributes &
> EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {
> -        if (VariableName[0] == 0) {
> -          if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION &
> VAR_ADDED)) {
> -            InDeletedVariable   = PtrTrack->CurrPtr;
> -          } else {
> -            PtrTrack->InDeletedTransitionPtr = InDeletedVariable;
> -            return EFI_SUCCESS;
> -          }
> -        } else {
> -          if (CompareGuid (VendorGuid, GetVendorGuidPtr (PtrTrack->CurrPtr)))
> {
> -            Point = (VOID *) GetVariableNamePtr (PtrTrack->CurrPtr);
> -
> -            ASSERT (NameSizeOfVariable (PtrTrack->CurrPtr) != 0);
> -            if (CompareMem (VariableName, Point, NameSizeOfVariable
> (PtrTrack->CurrPtr)) == 0) {
> -              if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION &
> VAR_ADDED)) {
> -                InDeletedVariable     = PtrTrack->CurrPtr;
> -              } else {
> -                PtrTrack->InDeletedTransitionPtr = InDeletedVariable;
> -                return EFI_SUCCESS;
> -              }
> -            }
> -          }
> -        }
> -      }
> -    }
> -  }
> -
> -  PtrTrack->CurrPtr = InDeletedVariable;
> -  return (PtrTrack->CurrPtr  == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS;
> -}
> -
> -
>  /**
>    Finds variable in storage blocks of volatile and non-volatile storage 
> areas.
> 
> @@ -2078,38 +1546,6 @@ AutoUpdateLangVariable (
>    }
>  }
> 
> -/**
> -  Compare two EFI_TIME data.
> -
> -
> -  @param FirstTime           A pointer to the first EFI_TIME data.
> -  @param SecondTime          A pointer to the second EFI_TIME data.
> -
> -  @retval  TRUE              The FirstTime is not later than the SecondTime.
> -  @retval  FALSE             The FirstTime is later than the SecondTime.
> -
> -**/
> -BOOLEAN
> -VariableCompareTimeStampInternal (
> -  IN EFI_TIME               *FirstTime,
> -  IN EFI_TIME               *SecondTime
> -  )
> -{
> -  if (FirstTime->Year != SecondTime->Year) {
> -    return (BOOLEAN) (FirstTime->Year < SecondTime->Year);
> -  } else if (FirstTime->Month != SecondTime->Month) {
> -    return (BOOLEAN) (FirstTime->Month < SecondTime->Month);
> -  } else if (FirstTime->Day != SecondTime->Day) {
> -    return (BOOLEAN) (FirstTime->Day < SecondTime->Day);
> -  } else if (FirstTime->Hour != SecondTime->Hour) {
> -    return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour);
> -  } else if (FirstTime->Minute != SecondTime->Minute) {
> -    return (BOOLEAN) (FirstTime->Minute < SecondTime->Minute);
> -  }
> -
> -  return (BOOLEAN) (FirstTime->Second <= SecondTime->Second);
> -}
> -
>  /**
>    Update the variable region with Variable information. If
> EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is set,
>    index of associated public key is needed.
> @@ -2885,166 +2321,6 @@ Done:
>    return Status;
>  }
> 
> -/**
> -  This code Finds the Next available variable.
> -
> -  Caution: This function may receive untrusted input.
> -  This function may be invoked in SMM mode. This function will do basic
> validation, before parse the data.
> -
> -  @param[in]  VariableName  Pointer to variable name.
> -  @param[in]  VendorGuid    Variable Vendor Guid.
> -  @param[out] VariablePtr   Pointer to variable header address.
> -
> -  @retval EFI_SUCCESS           The function completed successfully.
> -  @retval EFI_NOT_FOUND         The next variable was not found.
> -  @retval EFI_INVALID_PARAMETER If VariableName is not an empty string,
> while VendorGuid is NULL.
> -  @retval EFI_INVALID_PARAMETER The input values of VariableName and
> VendorGuid are not a name and
> -                                GUID of an existing variable.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -VariableServiceGetNextVariableInternal (
> -  IN  CHAR16                *VariableName,
> -  IN  EFI_GUID              *VendorGuid,
> -  OUT VARIABLE_HEADER       **VariablePtr
> -  )
> -{
> -  VARIABLE_STORE_TYPE     Type;
> -  VARIABLE_POINTER_TRACK  Variable;
> -  VARIABLE_POINTER_TRACK  VariableInHob;
> -  VARIABLE_POINTER_TRACK  VariablePtrTrack;
> -  EFI_STATUS              Status;
> -  VARIABLE_STORE_HEADER   *VariableStoreHeader[VariableStoreTypeMax];
> -
> -  Status = FindVariable (VariableName, VendorGuid, &Variable,
> &mVariableModuleGlobal->VariableGlobal, FALSE);
> -  if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {
> -    //
> -    // For VariableName is an empty string, FindVariable() will try to find 
> and
> return
> -    // the first qualified variable, and if FindVariable() returns error
> (EFI_NOT_FOUND)
> -    // as no any variable is found, still go to return the error
> (EFI_NOT_FOUND).
> -    //
> -    if (VariableName[0] != 0) {
> -      //
> -      // For VariableName is not an empty string, and FindVariable() returns
> error as
> -      // VariableName and VendorGuid are not a name and GUID of an existing
> variable,
> -      // there is no way to get next variable, follow spec to return
> EFI_INVALID_PARAMETER.
> -      //
> -      Status = EFI_INVALID_PARAMETER;
> -    }
> -    goto Done;
> -  }
> -
> -  if (VariableName[0] != 0) {
> -    //
> -    // If variable name is not NULL, get next variable.
> -    //
> -    Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
> -  }
> -
> -  //
> -  // 0: Volatile, 1: HOB, 2: Non-Volatile.
> -  // The index and attributes mapping must be kept in this order as
> FindVariable
> -  // makes use of this mapping to implement search algorithm.
> -  //
> -  VariableStoreHeader[VariableStoreTypeVolatile] =
> (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal-
> >VariableGlobal.VolatileVariableBase;
> -  VariableStoreHeader[VariableStoreTypeHob]      =
> (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal-
> >VariableGlobal.HobVariableBase;
> -  VariableStoreHeader[VariableStoreTypeNv]       = mNvVariableCache;
> -
> -  while (TRUE) {
> -    //
> -    // Switch from Volatile to HOB, to Non-Volatile.
> -    //
> -    while (!IsValidVariableHeader (Variable.CurrPtr, Variable.EndPtr)) {
> -      //
> -      // Find current storage index
> -      //
> -      for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax;
> Type++) {
> -        if ((VariableStoreHeader[Type] != NULL) && (Variable.StartPtr ==
> GetStartPointer (VariableStoreHeader[Type]))) {
> -          break;
> -        }
> -      }
> -      ASSERT (Type < VariableStoreTypeMax);
> -      //
> -      // Switch to next storage
> -      //
> -      for (Type++; Type < VariableStoreTypeMax; Type++) {
> -        if (VariableStoreHeader[Type] != NULL) {
> -          break;
> -        }
> -      }
> -      //
> -      // Capture the case that
> -      // 1. current storage is the last one, or
> -      // 2. no further storage
> -      //
> -      if (Type == VariableStoreTypeMax) {
> -        Status = EFI_NOT_FOUND;
> -        goto Done;
> -      }
> -      Variable.StartPtr = GetStartPointer (VariableStoreHeader[Type]);
> -      Variable.EndPtr   = GetEndPointer   (VariableStoreHeader[Type]);
> -      Variable.CurrPtr  = Variable.StartPtr;
> -    }
> -
> -    //
> -    // Variable is found
> -    //
> -    if (Variable.CurrPtr->State == VAR_ADDED || Variable.CurrPtr->State ==
> (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
> -      if (!AtRuntime () || ((Variable.CurrPtr->Attributes &
> EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {
> -        if (Variable.CurrPtr->State == (VAR_IN_DELETED_TRANSITION &
> VAR_ADDED)) {
> -          //
> -          // If it is a IN_DELETED_TRANSITION variable,
> -          // and there is also a same ADDED one at the same time,
> -          // don't return it.
> -          //
> -          VariablePtrTrack.StartPtr = Variable.StartPtr;
> -          VariablePtrTrack.EndPtr = Variable.EndPtr;
> -          Status = FindVariableEx (
> -                     GetVariableNamePtr (Variable.CurrPtr),
> -                     GetVendorGuidPtr (Variable.CurrPtr),
> -                     FALSE,
> -                     &VariablePtrTrack
> -                     );
> -          if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State ==
> VAR_ADDED) {
> -            Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
> -            continue;
> -          }
> -        }
> -
> -        //
> -        // Don't return NV variable when HOB overrides it
> -        //
> -        if ((VariableStoreHeader[VariableStoreTypeHob] != NULL) &&
> (VariableStoreHeader[VariableStoreTypeNv] != NULL) &&
> -            (Variable.StartPtr == GetStartPointer
> (VariableStoreHeader[VariableStoreTypeNv]))
> -           ) {
> -          VariableInHob.StartPtr = GetStartPointer
> (VariableStoreHeader[VariableStoreTypeHob]);
> -          VariableInHob.EndPtr   = GetEndPointer
> (VariableStoreHeader[VariableStoreTypeHob]);
> -          Status = FindVariableEx (
> -                     GetVariableNamePtr (Variable.CurrPtr),
> -                     GetVendorGuidPtr (Variable.CurrPtr),
> -                     FALSE,
> -                     &VariableInHob
> -                     );
> -          if (!EFI_ERROR (Status)) {
> -            Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
> -            continue;
> -          }
> -        }
> -
> -        *VariablePtr = Variable.CurrPtr;
> -        Status = EFI_SUCCESS;
> -        goto Done;
> -      }
> -    }
> -
> -    Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
> -  }
> -
> -Done:
> -  return Status;
> -}
> -
>  /**
> 
>    This code Finds the Next available variable.
> diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c
> index cb6fcebe2d..dc78f68fa9 100644
> --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c
> +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c
> @@ -1,12 +1,13 @@
>  /** @file
>    Provides variable driver extended services.
> 
> -Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  **/
> 
>  #include "Variable.h"
> +#include "VariableParsing.h"
> 
>  /**
>    Finds variable in storage blocks of volatile and non-volatile storage 
> areas.
> diff --git
> a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c
> new file mode 100644
> index 0000000000..7de0a90772
> --- /dev/null
> +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c
> @@ -0,0 +1,731 @@
> +/** @file
> +  Functions in this module are associated with variable parsing operations
> and
> +  are intended to be usable across variable driver source files.
> +
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "VariableParsing.h"
> +
> +/**
> +
> +  This code checks if variable header is valid or not.
> +
> +  @param Variable           Pointer to the Variable Header.
> +  @param VariableStoreEnd   Pointer to the Variable Store End.
> +
> +  @retval TRUE              Variable header is valid.
> +  @retval FALSE             Variable header is not valid.
> +
> +**/
> +BOOLEAN
> +IsValidVariableHeader (
> +  IN  VARIABLE_HEADER       *Variable,
> +  IN  VARIABLE_HEADER       *VariableStoreEnd
> +  )
> +{
> +  if ((Variable == NULL) || (Variable >= VariableStoreEnd) || (Variable-
> >StartId != VARIABLE_DATA)) {
> +    //
> +    // Variable is NULL or has reached the end of variable store,
> +    // or the StartId is not correct.
> +    //
> +    return FALSE;
> +  }
> +
> +  return TRUE;
> +}
> +
> +/**
> +
> +  This code gets the current status of Variable Store.
> +
> +  @param VarStoreHeader  Pointer to the Variable Store Header.
> +
> +  @retval EfiRaw         Variable store status is raw.
> +  @retval EfiValid       Variable store status is valid.
> +  @retval EfiInvalid     Variable store status is invalid.
> +
> +**/
> +VARIABLE_STORE_STATUS
> +GetVariableStoreStatus (
> +  IN VARIABLE_STORE_HEADER *VarStoreHeader
> +  )
> +{
> +  if ((CompareGuid (&VarStoreHeader->Signature,
> &gEfiAuthenticatedVariableGuid) ||
> +       CompareGuid (&VarStoreHeader->Signature, &gEfiVariableGuid)) &&
> +      VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&
> +      VarStoreHeader->State == VARIABLE_STORE_HEALTHY
> +      ) {
> +
> +    return EfiValid;
> +  } else if (((UINT32 *)(&VarStoreHeader->Signature))[0] == 0xffffffff &&
> +             ((UINT32 *)(&VarStoreHeader->Signature))[1] == 0xffffffff &&
> +             ((UINT32 *)(&VarStoreHeader->Signature))[2] == 0xffffffff &&
> +             ((UINT32 *)(&VarStoreHeader->Signature))[3] == 0xffffffff &&
> +             VarStoreHeader->Size == 0xffffffff &&
> +             VarStoreHeader->Format == 0xff &&
> +             VarStoreHeader->State == 0xff
> +          ) {
> +
> +    return EfiRaw;
> +  } else {
> +    return EfiInvalid;
> +  }
> +}
> +
> +/**
> +  This code gets the size of variable header.
> +
> +  @return Size of variable header in bytes in type UINTN.
> +
> +**/
> +UINTN
> +GetVariableHeaderSize (
> +  VOID
> +  )
> +{
> +  UINTN Value;
> +
> +  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> +    Value = sizeof (AUTHENTICATED_VARIABLE_HEADER);
> +  } else {
> +    Value = sizeof (VARIABLE_HEADER);
> +  }
> +
> +  return Value;
> +}
> +
> +/**
> +
> +  This code gets the size of name of variable.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return UINTN          Size of variable in bytes.
> +
> +**/
> +UINTN
> +NameSizeOfVariable (
> +  IN  VARIABLE_HEADER   *Variable
> +  )
> +{
> +  AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
> +
> +  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable;
> +  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> +    if (AuthVariable->State == (UINT8) (-1) ||
> +       AuthVariable->DataSize == (UINT32) (-1) ||
> +       AuthVariable->NameSize == (UINT32) (-1) ||
> +       AuthVariable->Attributes == (UINT32) (-1)) {
> +      return 0;
> +    }
> +    return (UINTN) AuthVariable->NameSize;
> +  } else {
> +    if (Variable->State == (UINT8) (-1) ||
> +        Variable->DataSize == (UINT32) (-1) ||
> +        Variable->NameSize == (UINT32) (-1) ||
> +        Variable->Attributes == (UINT32) (-1)) {
> +      return 0;
> +    }
> +    return (UINTN) Variable->NameSize;
> +  }
> +}
> +
> +/**
> +  This code sets the size of name of variable.
> +
> +  @param[in] Variable   Pointer to the Variable Header.
> +  @param[in] NameSize   Name size to set.
> +
> +**/
> +VOID
> +SetNameSizeOfVariable (
> +  IN VARIABLE_HEADER    *Variable,
> +  IN UINTN              NameSize
> +  )
> +{
> +  AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
> +
> +  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable;
> +  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> +    AuthVariable->NameSize = (UINT32) NameSize;
> +  } else {
> +    Variable->NameSize = (UINT32) NameSize;
> +  }
> +}
> +
> +/**
> +
> +  This code gets the size of variable data.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return Size of variable in bytes.
> +
> +**/
> +UINTN
> +DataSizeOfVariable (
> +  IN  VARIABLE_HEADER   *Variable
> +  )
> +{
> +  AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
> +
> +  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable;
> +  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> +    if (AuthVariable->State == (UINT8) (-1) ||
> +       AuthVariable->DataSize == (UINT32) (-1) ||
> +       AuthVariable->NameSize == (UINT32) (-1) ||
> +       AuthVariable->Attributes == (UINT32) (-1)) {
> +      return 0;
> +    }
> +    return (UINTN) AuthVariable->DataSize;
> +  } else {
> +    if (Variable->State == (UINT8) (-1) ||
> +        Variable->DataSize == (UINT32) (-1) ||
> +        Variable->NameSize == (UINT32) (-1) ||
> +        Variable->Attributes == (UINT32) (-1)) {
> +      return 0;
> +    }
> +    return (UINTN) Variable->DataSize;
> +  }
> +}
> +
> +/**
> +  This code sets the size of variable data.
> +
> +  @param[in] Variable   Pointer to the Variable Header.
> +  @param[in] DataSize   Data size to set.
> +
> +**/
> +VOID
> +SetDataSizeOfVariable (
> +  IN VARIABLE_HEADER    *Variable,
> +  IN UINTN              DataSize
> +  )
> +{
> +  AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
> +
> +  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable;
> +  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> +    AuthVariable->DataSize = (UINT32) DataSize;
> +  } else {
> +    Variable->DataSize = (UINT32) DataSize;
> +  }
> +}
> +
> +/**
> +
> +  This code gets the pointer to the variable name.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return Pointer to Variable Name which is Unicode encoding.
> +
> +**/
> +CHAR16 *
> +GetVariableNamePtr (
> +  IN  VARIABLE_HEADER   *Variable
> +  )
> +{
> +  return (CHAR16 *) ((UINTN) Variable + GetVariableHeaderSize ());
> +}
> +
> +/**
> +  This code gets the pointer to the variable guid.
> +
> +  @param Variable   Pointer to the Variable Header.
> +
> +  @return A EFI_GUID* pointer to Vendor Guid.
> +
> +**/
> +EFI_GUID *
> +GetVendorGuidPtr (
> +  IN VARIABLE_HEADER    *Variable
> +  )
> +{
> +  AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
> +
> +  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable;
> +  if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
> +    return &AuthVariable->VendorGuid;
> +  } else {
> +    return &Variable->VendorGuid;
> +  }
> +}
> +
> +/**
> +
> +  This code gets the pointer to the variable data.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return Pointer to Variable Data.
> +
> +**/
> +UINT8 *
> +GetVariableDataPtr (
> +  IN  VARIABLE_HEADER   *Variable
> +  )
> +{
> +  UINTN Value;
> +
> +  //
> +  // Be careful about pad size for alignment.
> +  //
> +  Value =  (UINTN) GetVariableNamePtr (Variable);
> +  Value += NameSizeOfVariable (Variable);
> +  Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));
> +
> +  return (UINT8 *) Value;
> +}
> +
> +/**
> +  This code gets the variable data offset related to variable header.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return Variable Data offset.
> +
> +**/
> +UINTN
> +GetVariableDataOffset (
> +  IN  VARIABLE_HEADER   *Variable
> +  )
> +{
> +  UINTN Value;
> +
> +  //
> +  // Be careful about pad size for alignment
> +  //
> +  Value = GetVariableHeaderSize ();
> +  Value += NameSizeOfVariable (Variable);
> +  Value += GET_PAD_SIZE (NameSizeOfVariable (Variable));
> +
> +  return Value;
> +}
> +
> +/**
> +
> +  This code gets the pointer to the next variable header.
> +
> +  @param Variable        Pointer to the Variable Header.
> +
> +  @return Pointer to next variable header.
> +
> +**/
> +VARIABLE_HEADER *
> +GetNextVariablePtr (
> +  IN  VARIABLE_HEADER   *Variable
> +  )
> +{
> +  UINTN Value;
> +
> +  Value =  (UINTN) GetVariableDataPtr (Variable);
> +  Value += DataSizeOfVariable (Variable);
> +  Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));
> +
> +  //
> +  // Be careful about pad size for alignment.
> +  //
> +  return (VARIABLE_HEADER *) HEADER_ALIGN (Value);
> +}
> +
> +/**
> +
> +  Gets the pointer to the first variable header in given variable store area.
> +
> +  @param VarStoreHeader  Pointer to the Variable Store Header.
> +
> +  @return Pointer to the first variable header.
> +
> +**/
> +VARIABLE_HEADER *
> +GetStartPointer (
> +  IN VARIABLE_STORE_HEADER       *VarStoreHeader
> +  )
> +{
> +  //
> +  // The start of variable store.
> +  //
> +  return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);
> +}
> +
> +/**
> +
> +  Gets the pointer to the end of the variable storage area.
> +
> +  This function gets pointer to the end of the variable storage
> +  area, according to the input variable store header.
> +
> +  @param VarStoreHeader  Pointer to the Variable Store Header.
> +
> +  @return Pointer to the end of the variable storage area.
> +
> +**/
> +VARIABLE_HEADER *
> +GetEndPointer (
> +  IN VARIABLE_STORE_HEADER       *VarStoreHeader
> +  )
> +{
> +  //
> +  // The end of variable store
> +  //
> +  return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader +
> VarStoreHeader->Size);
> +}
> +
> +/**
> +  Compare two EFI_TIME data.
> +
> +
> +  @param FirstTime           A pointer to the first EFI_TIME data.
> +  @param SecondTime          A pointer to the second EFI_TIME data.
> +
> +  @retval  TRUE              The FirstTime is not later than the SecondTime.
> +  @retval  FALSE             The FirstTime is later than the SecondTime.
> +
> +**/
> +BOOLEAN
> +VariableCompareTimeStampInternal (
> +  IN EFI_TIME               *FirstTime,
> +  IN EFI_TIME               *SecondTime
> +  )
> +{
> +  if (FirstTime->Year != SecondTime->Year) {
> +    return (BOOLEAN) (FirstTime->Year < SecondTime->Year);
> +  } else if (FirstTime->Month != SecondTime->Month) {
> +    return (BOOLEAN) (FirstTime->Month < SecondTime->Month);
> +  } else if (FirstTime->Day != SecondTime->Day) {
> +    return (BOOLEAN) (FirstTime->Day < SecondTime->Day);
> +  } else if (FirstTime->Hour != SecondTime->Hour) {
> +    return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour);
> +  } else if (FirstTime->Minute != SecondTime->Minute) {
> +    return (BOOLEAN) (FirstTime->Minute < SecondTime->Minute);
> +  }
> +
> +  return (BOOLEAN) (FirstTime->Second <= SecondTime->Second);
> +}
> +
> +/**
> +  Find the variable in the specified variable store.
> +
> +  @param[in]       VariableName        Name of the variable to be found
> +  @param[in]       VendorGuid          Vendor GUID to be found.
> +  @param[in]       IgnoreRtCheck       Ignore EFI_VARIABLE_RUNTIME_ACCESS
> attribute
> +                                       check at runtime when searching 
> variable.
> +  @param[in, out]  PtrTrack            Variable Track Pointer structure that
> contains Variable Information.
> +
> +  @retval          EFI_SUCCESS         Variable found successfully
> +  @retval          EFI_NOT_FOUND       Variable not found
> +**/
> +EFI_STATUS
> +FindVariableEx (
> +  IN     CHAR16                  *VariableName,
> +  IN     EFI_GUID                *VendorGuid,
> +  IN     BOOLEAN                 IgnoreRtCheck,
> +  IN OUT VARIABLE_POINTER_TRACK  *PtrTrack
> +  )
> +{
> +  VARIABLE_HEADER                *InDeletedVariable;
> +  VOID                           *Point;
> +
> +  PtrTrack->InDeletedTransitionPtr = NULL;
> +
> +  //
> +  // Find the variable by walk through HOB, volatile and non-volatile 
> variable
> store.
> +  //
> +  InDeletedVariable  = NULL;
> +
> +  for ( PtrTrack->CurrPtr = PtrTrack->StartPtr
> +      ; IsValidVariableHeader (PtrTrack->CurrPtr, PtrTrack->EndPtr)
> +      ; PtrTrack->CurrPtr = GetNextVariablePtr (PtrTrack->CurrPtr)
> +      ) {
> +    if (PtrTrack->CurrPtr->State == VAR_ADDED ||
> +        PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION &
> VAR_ADDED)
> +       ) {
> +      if (IgnoreRtCheck || !AtRuntime () || ((PtrTrack->CurrPtr->Attributes &
> EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {
> +        if (VariableName[0] == 0) {
> +          if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION &
> VAR_ADDED)) {
> +            InDeletedVariable   = PtrTrack->CurrPtr;
> +          } else {
> +            PtrTrack->InDeletedTransitionPtr = InDeletedVariable;
> +            return EFI_SUCCESS;
> +          }
> +        } else {
> +          if (CompareGuid (VendorGuid, GetVendorGuidPtr (PtrTrack->CurrPtr)))
> {
> +            Point = (VOID *) GetVariableNamePtr (PtrTrack->CurrPtr);
> +
> +            ASSERT (NameSizeOfVariable (PtrTrack->CurrPtr) != 0);
> +            if (CompareMem (VariableName, Point, NameSizeOfVariable
> (PtrTrack->CurrPtr)) == 0) {
> +              if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION &
> VAR_ADDED)) {
> +                InDeletedVariable     = PtrTrack->CurrPtr;
> +              } else {
> +                PtrTrack->InDeletedTransitionPtr = InDeletedVariable;
> +                return EFI_SUCCESS;
> +              }
> +            }
> +          }
> +        }
> +      }
> +    }
> +  }
> +
> +  PtrTrack->CurrPtr = InDeletedVariable;
> +  return (PtrTrack->CurrPtr  == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS;
> +}
> +
> +/**
> +  This code Finds the Next available variable.
> +
> +  Caution: This function may receive untrusted input.
> +  This function may be invoked in SMM mode. This function will do basic
> validation, before parse the data.
> +
> +  @param[in]  VariableName  Pointer to variable name.
> +  @param[in]  VendorGuid    Variable Vendor Guid.
> +  @param[out] VariablePtr   Pointer to variable header address.
> +
> +  @retval EFI_SUCCESS           The function completed successfully.
> +  @retval EFI_NOT_FOUND         The next variable was not found.
> +  @retval EFI_INVALID_PARAMETER If VariableName is not an empty string,
> while VendorGuid is NULL.
> +  @retval EFI_INVALID_PARAMETER The input values of VariableName and
> VendorGuid are not a name and
> +                                GUID of an existing variable.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VariableServiceGetNextVariableInternal (
> +  IN  CHAR16                *VariableName,
> +  IN  EFI_GUID              *VendorGuid,
> +  OUT VARIABLE_HEADER       **VariablePtr
> +  )
> +{
> +  VARIABLE_STORE_TYPE     Type;
> +  VARIABLE_POINTER_TRACK  Variable;
> +  VARIABLE_POINTER_TRACK  VariableInHob;
> +  VARIABLE_POINTER_TRACK  VariablePtrTrack;
> +  EFI_STATUS              Status;
> +  VARIABLE_STORE_HEADER
> *VariableStoreHeader[VariableStoreTypeMax];
> +
> +  Status = FindVariable (VariableName, VendorGuid, &Variable,
> &mVariableModuleGlobal->VariableGlobal, FALSE);
> +  if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {
> +    //
> +    // For VariableName is an empty string, FindVariable() will try to find 
> and
> return
> +    // the first qualified variable, and if FindVariable() returns error
> (EFI_NOT_FOUND)
> +    // as no any variable is found, still go to return the error
> (EFI_NOT_FOUND).
> +    //
> +    if (VariableName[0] != 0) {
> +      //
> +      // For VariableName is not an empty string, and FindVariable() returns
> error as
> +      // VariableName and VendorGuid are not a name and GUID of an
> existing variable,
> +      // there is no way to get next variable, follow spec to return
> EFI_INVALID_PARAMETER.
> +      //
> +      Status = EFI_INVALID_PARAMETER;
> +    }
> +    goto Done;
> +  }
> +
> +  if (VariableName[0] != 0) {
> +    //
> +    // If variable name is not NULL, get next variable.
> +    //
> +    Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
> +  }
> +
> +  //
> +  // 0: Volatile, 1: HOB, 2: Non-Volatile.
> +  // The index and attributes mapping must be kept in this order as
> FindVariable
> +  // makes use of this mapping to implement search algorithm.
> +  //
> +  VariableStoreHeader[VariableStoreTypeVolatile] =
> (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal-
> >VariableGlobal.VolatileVariableBase;
> +  VariableStoreHeader[VariableStoreTypeHob]      =
> (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal-
> >VariableGlobal.HobVariableBase;
> +  VariableStoreHeader[VariableStoreTypeNv]       = mNvVariableCache;
> +
> +  while (TRUE) {
> +    //
> +    // Switch from Volatile to HOB, to Non-Volatile.
> +    //
> +    while (!IsValidVariableHeader (Variable.CurrPtr, Variable.EndPtr)) {
> +      //
> +      // Find current storage index
> +      //
> +      for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax;
> Type++) {
> +        if ((VariableStoreHeader[Type] != NULL) && (Variable.StartPtr ==
> GetStartPointer (VariableStoreHeader[Type]))) {
> +          break;
> +        }
> +      }
> +      ASSERT (Type < VariableStoreTypeMax);
> +      //
> +      // Switch to next storage
> +      //
> +      for (Type++; Type < VariableStoreTypeMax; Type++) {
> +        if (VariableStoreHeader[Type] != NULL) {
> +          break;
> +        }
> +      }
> +      //
> +      // Capture the case that
> +      // 1. current storage is the last one, or
> +      // 2. no further storage
> +      //
> +      if (Type == VariableStoreTypeMax) {
> +        Status = EFI_NOT_FOUND;
> +        goto Done;
> +      }
> +      Variable.StartPtr = GetStartPointer (VariableStoreHeader[Type]);
> +      Variable.EndPtr   = GetEndPointer   (VariableStoreHeader[Type]);
> +      Variable.CurrPtr  = Variable.StartPtr;
> +    }
> +
> +    //
> +    // Variable is found
> +    //
> +    if (Variable.CurrPtr->State == VAR_ADDED || Variable.CurrPtr->State ==
> (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
> +      if (!AtRuntime () || ((Variable.CurrPtr->Attributes &
> EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {
> +        if (Variable.CurrPtr->State == (VAR_IN_DELETED_TRANSITION &
> VAR_ADDED)) {
> +          //
> +          // If it is a IN_DELETED_TRANSITION variable,
> +          // and there is also a same ADDED one at the same time,
> +          // don't return it.
> +          //
> +          VariablePtrTrack.StartPtr = Variable.StartPtr;
> +          VariablePtrTrack.EndPtr = Variable.EndPtr;
> +          Status = FindVariableEx (
> +                     GetVariableNamePtr (Variable.CurrPtr),
> +                     GetVendorGuidPtr (Variable.CurrPtr),
> +                     FALSE,
> +                     &VariablePtrTrack
> +                     );
> +          if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State ==
> VAR_ADDED) {
> +            Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
> +            continue;
> +          }
> +        }
> +
> +        //
> +        // Don't return NV variable when HOB overrides it
> +        //
> +        if ((VariableStoreHeader[VariableStoreTypeHob] != NULL) &&
> (VariableStoreHeader[VariableStoreTypeNv] != NULL) &&
> +            (Variable.StartPtr == GetStartPointer
> (VariableStoreHeader[VariableStoreTypeNv]))
> +           ) {
> +          VariableInHob.StartPtr = GetStartPointer
> (VariableStoreHeader[VariableStoreTypeHob]);
> +          VariableInHob.EndPtr   = GetEndPointer
> (VariableStoreHeader[VariableStoreTypeHob]);
> +          Status = FindVariableEx (
> +                     GetVariableNamePtr (Variable.CurrPtr),
> +                     GetVendorGuidPtr (Variable.CurrPtr),
> +                     FALSE,
> +                     &VariableInHob
> +                     );
> +          if (!EFI_ERROR (Status)) {
> +            Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
> +            continue;
> +          }
> +        }
> +
> +        *VariablePtr = Variable.CurrPtr;
> +        Status = EFI_SUCCESS;
> +        goto Done;
> +      }
> +    }
> +
> +    Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
> +  }
> +
> +Done:
> +  return Status;
> +}
> +
> +/**
> +  Routine used to track statistical information about variable usage.
> +  The data is stored in the EFI system table so it can be accessed later.
> +  VariableInfo.efi can dump out the table. Only Boot Services variable
> +  accesses are tracked by this code. The PcdVariableCollectStatistics
> +  build flag controls if this feature is enabled.
> +
> +  A read that hits in the cache will have Read and Cache true for
> +  the transaction. Data is allocated by this routine, but never
> +  freed.
> +
> +  @param[in] VariableName   Name of the Variable to track.
> +  @param[in] VendorGuid     Guid of the Variable to track.
> +  @param[in] Volatile       TRUE if volatile FALSE if non-volatile.
> +  @param[in] Read           TRUE if GetVariable() was called.
> +  @param[in] Write          TRUE if SetVariable() was called.
> +  @param[in] Delete         TRUE if deleted via SetVariable().
> +  @param[in] Cache          TRUE for a cache hit.
> +
> +**/
> +VOID
> +UpdateVariableInfo (
> +  IN  CHAR16                  *VariableName,
> +  IN  EFI_GUID                *VendorGuid,
> +  IN  BOOLEAN                 Volatile,
> +  IN  BOOLEAN                 Read,
> +  IN  BOOLEAN                 Write,
> +  IN  BOOLEAN                 Delete,
> +  IN  BOOLEAN                 Cache
> +  )
> +{
> +  VARIABLE_INFO_ENTRY   *Entry;
> +
> +  if (FeaturePcdGet (PcdVariableCollectStatistics)) {
> +
> +    if (AtRuntime ()) {
> +      // Don't collect statistics at runtime.
> +      return;
> +    }
> +
> +    if (gVariableInfo == NULL) {
> +      //
> +      // On the first call allocate a entry and place a pointer to it in
> +      // the EFI System Table.
> +      //
> +      gVariableInfo = AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY));
> +      ASSERT (gVariableInfo != NULL);
> +
> +      CopyGuid (&gVariableInfo->VendorGuid, VendorGuid);
> +      gVariableInfo->Name = AllocateZeroPool (StrSize (VariableName));
> +      ASSERT (gVariableInfo->Name != NULL);
> +      StrCpyS (gVariableInfo->Name, StrSize(VariableName)/sizeof(CHAR16),
> VariableName);
> +      gVariableInfo->Volatile = Volatile;
> +    }
> +
> +
> +    for (Entry = gVariableInfo; Entry != NULL; Entry = Entry->Next) {
> +      if (CompareGuid (VendorGuid, &Entry->VendorGuid)) {
> +        if (StrCmp (VariableName, Entry->Name) == 0) {
> +          if (Read) {
> +            Entry->ReadCount++;
> +          }
> +          if (Write) {
> +            Entry->WriteCount++;
> +          }
> +          if (Delete) {
> +            Entry->DeleteCount++;
> +          }
> +          if (Cache) {
> +            Entry->CacheCount++;
> +          }
> +
> +          return;
> +        }
> +      }
> +
> +      if (Entry->Next == NULL) {
> +        //
> +        // If the entry is not in the table add it.
> +        // Next iteration of the loop will fill in the data.
> +        //
> +        Entry->Next = AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY));
> +        ASSERT (Entry->Next != NULL);
> +
> +        CopyGuid (&Entry->Next->VendorGuid, VendorGuid);
> +        Entry->Next->Name = AllocateZeroPool (StrSize (VariableName));
> +        ASSERT (Entry->Next->Name != NULL);
> +        StrCpyS (Entry->Next->Name, StrSize(VariableName)/sizeof(CHAR16),
> VariableName);
> +        Entry->Next->Volatile = Volatile;
> +      }
> +
> +    }
> +  }
> +}
> diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
> b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
> index ec463d063e..ce409f22a3 100644
> --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
> +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
> @@ -30,6 +30,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  #include <Guid/SmmVariableCommon.h>
>  #include "Variable.h"
> +#include "VariableParsing.h"
> 
>  BOOLEAN                                              mAtRuntime              
> = FALSE;
>  UINT8                                                *mVariableBufferPayload 
> = NULL;
> --
> 2.16.2.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#48415): https://edk2.groups.io/g/devel/message/48415
Mute This Topic: https://groups.io/mt/34318584/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to