The main reason is cohesiveness in the VariableParsing.c file. These are functions that are commonly needed for general variable data structure parsing operations. Most of them just read a member or two in a VARIABLE_STORE_HEADER or VARIABLE_HEADER data structure, perform a simple calculation if needed, and return some value. More complex functions such as FindVariableEx (), do this in iteration across the variable store. If a function is needed that performs these tasks, it is easier to have them grouped into a cohesive file than search which one is in Variable.c and VariableParsing.c on a case-by-case basis. UpdateVariableInfo () is the exception here, I can move this to a separate file if you prefer.
Also, Variable.c is, in my opinion, far too large. It is on trend to only grow larger: * Today: ~4,600 LOC * ~2 years ago: ~4,200 LOC * ~4 years ago: ~4,100 LOC * ~5 years ago: ~3,440 LOC * ~8 years ago: ~2,600 LOC I think moving out generic parsing services such as these better groups related functionality in the short-term but also aids future refactoring efforts in the file. Thanks, Michael > -----Original Message----- > From: Wu, Hao A <hao.a...@intel.com> > Sent: Thursday, October 3, 2019 1:03 AM > To: Kubacki, Michael A <michael.a.kuba...@intel.com>; > devel@edk2.groups.io > Cc: Bi, Dandan <dandan...@intel.com>; Ard Biesheuvel > <ard.biesheu...@linaro.org>; Dong, Eric <eric.d...@intel.com>; Laszlo Ersek > <ler...@redhat.com>; Gao, Liming <liming....@intel.com>; Kinney, Michael > D <michael.d.kin...@intel.com>; Ni, Ray <ray...@intel.com>; Wang, Jian J > <jian.j.w...@intel.com>; Yao, Jiewen <jiewen....@intel.com> > Subject: RE: [PATCH V2 1/9] MdeModulePkg/Variable: Consolidate common > parsing functions > > 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 (#48441): https://edk2.groups.io/g/devel/message/48441 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] -=-=-=-=-=-=-=-=-=-=-=-