summaryrefslogtreecommitdiff
path: root/Core/EM/NVRAM/NVRAMRead.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/NVRAM/NVRAMRead.c')
-rw-r--r--Core/EM/NVRAM/NVRAMRead.c1508
1 files changed, 1508 insertions, 0 deletions
diff --git a/Core/EM/NVRAM/NVRAMRead.c b/Core/EM/NVRAM/NVRAMRead.c
new file mode 100644
index 0000000..463ed5b
--- /dev/null
+++ b/Core/EM/NVRAM/NVRAMRead.c
@@ -0,0 +1,1508 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAMRead.c 32 6/11/14 3:12p Oleksiyy $
+//
+// $Revision: 32 $
+//
+// $Date: 6/11/14 3:12p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAMRead.c $
+//
+// 32 6/11/14 3:12p Oleksiyy
+// [TAG] EIP173026
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] With AMITSE 2.17.1245 windows 8.1 (UEFI) does not install
+// [RootCause] GetNextVariableName was in certain cases returning name
+// and GUID of a boot time variable
+// [Solution] Variable name and GUID of a boot time variable X were
+// returned at runtime under the following conditions:
+// - The variable X was present in the default var.store and not
+// present in the main var.store
+// - The variable immediately before variable X in the default
+// var.store was present in the main var.store
+// The default var.store is a var.store generated at build time that
+// contains default values for all setup variables
+// (variables associated with setup controls).
+// The main var.store is the main NVRAM area. Variable is added into a
+// main var.store when somebody
+// calls SetVariable.
+// [Files] NVRAMRead.c
+// NVRAMDXE.c
+// NVRAM.cif
+//
+// 31 4/11/14 5:13p Oleksiyy
+// [TAG] EIP162446
+// [Category] Improvement
+// [Description] Chm file added.
+// [Files] NVRAMRead.c
+// NVRAM.cif
+//
+// 30 1/08/14 5:34p Oleksiyy
+// [TAG] EIP125555
+// [Category] Improvement
+// [Description] A Work-around provided for NvGetNextVariableName2() to
+// preserve the original VariableName when returning an
+// EFI_BUFFER_TOO_SMALL error from NvGetNameFromNvar().
+// [Files] NVRANRead.c
+//
+// 29 11/29/12 5:10p Felixp
+// Minor improvement: Since UEFI Specification versions prior to 2.1
+// (0x2000A) are no longer supported,
+// all the "#if EFI_SPECIFICATION_VERSION >= 0x2000A" conditional
+// compilation statements are removed.
+// Files modified: NVRAM.h, NVRAMRead.c, NVRAMDXE.c
+//
+// 28 7/13/11 9:24a Justinj
+// [TAG] EIP62762
+// [Category] Improvement
+// [Description] Optimize NVRAM cache index so that the entire linked
+// list is not walked every time a variable is set or retrieved.
+// [Files] NVRAM.h
+// NVRAMRead.c
+// NVRAMDXE.c
+//
+// 27 5/06/11 6:14p Oleksiyy
+// [TAG] EIP53253
+// [Category] Improvement
+// [Description] To comply with UEFI 2.3.1
+// EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS and
+// EFI_VARIABLE_APPEND_WRITE attributes handling added.
+// [Files] NVRAM.h, NVRAMRead.c and NVRAMDXE.c
+//
+// 26 9/30/10 4:36p Oleksiyy
+// Issue Number: 40356 and 39462
+//
+// Category: New Feature
+//
+// Description: Support for EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
+// Small fix of previously checked in code.
+//
+// Files: NVRAM. h, NVRAMRead.c, NVRAMDXE.c
+//
+// 25 9/22/10 6:39p Felixp
+// Enhancement(EIP 39462 and EIP 40356):
+// Support of the authenticated update of the NVRAM variables
+// as described in UEFI specification version 2.1 and above.
+// NOTE: The actual authentication is performed by the external SecureMod
+// eModule,
+// which must be in the proejct to use this feature.
+//
+// 24 8/18/10 11:08a Oleksiyy
+// [TAG] EIP42324
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] NVRAM checksum at EFI Variable deletion
+// [RootCause] Deleted variables also were checksummed when NVRAM
+// consistency is checked.
+// [Solution] Deleted variables not checksummed any more.
+// [Files] NVRAMRead.c
+//
+// 23 12/16/09 5:55p Oleksiyy
+// EIP 26085: Added support to read All the NVRAM variable. Final version.
+//
+// 22 12/04/09 2:27p Felixp
+// NvarEqNvar moved from NvramDxe.c to NvramRead.c
+//
+// 21 11/25/09 4:42p Felixp
+// NvGetNextVariableName2 changes are rolled back
+//
+// 20 11/25/09 4:38p Felixp
+// NvGetNextVariableName2 updated.
+//
+// 19 11/24/09 4:40p Felixp
+// Minor bug fixes
+//
+// 18 11/24/09 4:04p Oleksiyy
+// EIP 26085: Added support to read All the NVRAM variable (including
+// defoults) with GetNextVariable in PEI and DXE.
+//
+// 17 11/23/09 11:00p Felixp
+//
+// 16 11/23/09 4:44p Felixp
+// Code to validate NVRAM header fields used by the NVRAM driver is added.
+// If problem is found, the header fields are updated with the correct
+// values.
+//
+// 15 11/20/09 4:06p Felixp
+// NVRAM driver is updated to support UEFI2.1
+// EFI_VARIABLE_HARDWARE_ERROR_RECORD attribue.
+//
+// 14 11/19/09 4:30p Felixp
+//
+// 13 11/18/09 12:10p Oleksiyy
+// EIP 30751: Bug fix in the NVRAM record checksum implementation
+//
+// 12 8/25/09 4:11p Felixp
+// NVRAM Record Checksum Support(EIP 23825) is added.
+// Disabled by default. Enable using NVRAM_RECORD_CHECKSUM_SUPPORT SDL
+// token.
+//
+// 11 7/10/09 8:50a Felixp
+// Code clean up; comments and function header added
+//
+// 10 6/26/09 3:28p Felixp
+// New IsMainNvramStoreValid function is added.
+// The function detects is main NVRAM or backup NVRAM is currently active
+// (returns FALSE when backup is active).
+//
+// 9 5/14/09 9:36a Felixp
+// New feature: SMM version of Runtime Services
+// NVRAM driver is updated to populate SMM runtime table
+// with the pointers to SMM version of variable services.
+//
+// 8 11/18/08 5:45p Felixp
+// Bug fix in NvIsVariable and NvGetNextNvar functions.
+// Symptoms: False NVRAM corruption detection on systems with
+// NVRAM larger than 64KB during creation or update of the large
+// variables.
+// Reason: overflow during validation of record size
+//
+// 7 10/09/08 11:47a Felixp
+// 1. Fault tolerant NVRAM garbage collection support is added.
+// Use FAULT_TOLERANT_NVRAM_UPDATE SDL token to enable/disable (disabled
+// by default).
+// NOTE: This feature requires upgrade of the Board module.
+// NOTE: This feature requires porting:
+// Fault tolerant update requires reserved flash area of size NVRAM_SIZE
+// used for back up during NVRAM garbage collection.
+// The address of the area is defined by NVRAM_BACKUP_ADDRESS SDL token
+// defined in Board.sdl.
+// Size and Base addresses of other firmware volumes may need to be
+// adjusted to free up space for the NVRAM back up area.
+// Default ROM layout expects NVRAM back up area immediately below the
+// main NVRAM area.
+// For projects with the customized ROM layout Core.mak has to be updated.
+// 2. Top level NVRAM function updated to be reentrance-safe.
+// NOTE: This feature requires upgrade of the SB module.
+// 3. Improved recovery from the flash programming failures and
+// corruptions within NVRAM area.
+// 4. More reliable non-fault tolerant garbage collection.
+//
+// 6 9/06/07 12:14a Felixp
+//
+// 5 8/31/07 3:44p Felixp
+// NVRAM code has been significantly changed to introduce the following
+// improvements:
+// 1. The code is chaned to always use the same amount of memory.
+// Previous implementation allocated memory as needed, which caused
+// occasional S4 problems.
+// Plus S4 resume never worked during the very first boot after the
+// firmware update.
+// 2. Support for NVRAM defaults added.
+// NVRAM image with the default values for the Setup variables is now
+// generated by the build process.
+// The image is generated by the HpkTool (included into AMITSE module
+// part).
+// In addition to standard Setup defaults it is also possible
+// to generate manufactoring defaults. Support for the manufactoring
+// defaults
+// is disabled by default and can be enabled using
+// MANUFACTURING_MODE_SUPPORT SDL token.
+// 3. Support for boot with alternative configurations is added.
+// Decision to switch to the alternative configuration
+// (alternative set of values for NVRAM variables)
+// is based on values returned by the porintg routine in OemPort.c.
+// During boot with alternative configurations GetVariable service
+// returns alternative values for the setup-related variables.
+// If variable does not have an alternative value, current value is
+// returned.
+// Two alternative configurations are supported:
+// Boot with manufactoring settings(activated when IsMfgMode routine in
+// OemPort.c returns TRUE).
+// Boot with default settings(activated when IsDefaultConfigMode routine
+// in OemPort.c returns TRUE).
+// NOTE: This feature requires of the Board module
+// 4.NVRAM reset option is added.
+// If porting routine IsResetConfigMode in OemPort.c returns TRUE in PEI
+// phase,
+// NVRAM content will be reset during initialization of the DXE NVRAM
+// driver.
+// During reset operation all setup-related variables are reset to their
+// default values.
+// All other variables are deleted.
+// NOTE: This feature requires upgrade of the Board module
+// 5.Detection of NVRAM update added.
+// NVRAM implementation detects if NVRAM has been updated since the last
+// NVRAM call.
+// This provides ability to use variables services before and after
+// firmware update.
+// 6.Overall code clean up and simplification.
+// 7.Core Sources are no longer required in order to use NV_SIMULATION
+// option.
+// 8.PI 1.0 support.
+// Support for a PI 1.0 complient variable PPI is added. Old PPI is still
+// preserved in this label for backward compatibility.
+// New library routines PeiGetVariable and PeiGetNextVariableName are
+// created in order to hide the differences between two PPIs.
+// It is recommended to update existing code to use new library routines.
+// Support of the old PPI may be dropped in the future versions of Core.
+// 9. NVRAM is now packaged as a raw FFS file embedded into the standard
+// FV (used to be non-standard FV with raw NVRAM image).
+// Validation: New NVRAM code has been validated using SCT and EFI version
+// of Windows Server 2008
+// Files modified: Core.sdl, Core.mak, AmiPeiLib.h, PeiLib.c,
+// ReadOnlyVariable.h, , Token.c, HpkTool.exe, AMITSE.mak, Setup.ini,
+// NVRAM.sdl, NVRAM.mak, NVRAM.h, NVRAMRead.c, NVRAMPEI.c,
+// NVRAMDXE.c
+//
+// 4 4/27/07 7:12p Pavell
+// Bug fix in NVGetNextVariableName: GetNextVariable did not return
+// EFI_NOT_FOUND after the last variable if the very first operation after
+// ExitBootServices was update of the existing NV variable.
+//
+// 3 3/18/07 4:08p Felixp
+// 1. IsNvramBlock function added
+// 2. Clean up
+//
+// 2 10/27/06 10:42a Felixp
+// Bug fixes for correct work in Virtual Address Space.
+//
+// 3 1/20/05 11:37a Felixp
+// Component restructurized to support release in binary format
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/27/04 4:08p Felixp
+//
+// 11 12/09/04 9:02p Felixp
+// minor improvements
+//
+// 10 8/28/04 1:49a Felixp
+// NVRAM Routines fixes
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NVRAMRead.c
+//
+// Description: NVRAM data area access API
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "NVRAM.h"
+
+#define VALID_STATE_FLAGS (\
+ EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID |\
+ EFI_FILE_DATA_VALID | EFI_FILE_MARKED_FOR_UPDATE)
+
+//Definitions for Variables that are used
+//to store nested defaults images
+// {4599D26F-1A11-49b8-B91F-858745CFF824}
+const EFI_GUID AmiDefaultsVariableGuid =
+ { 0x4599d26f, 0x1a11, 0x49b8, { 0xb9, 0x1f, 0x85, 0x87, 0x45, 0xcf, 0xf8, 0x24 } };
+const CHAR16 MfgDefaults[] = L"MfgDefaults";
+const CHAR16 StdDefaults[] = L"StdDefaults";
+const EFI_GUID AmiNvramHobGuid = NVRAM_HOB_GUID;
+
+//Low level access routines
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetGuid
+//
+// Description: This function returns GUID of specified variable.
+//
+// Input: NVAR* pVar - pointer to Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: EFI_GUID* - pionter to the Var GUID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_GUID* NvGetGuid(NVAR* pVar, NVRAM_STORE_INFO *pInfo)
+{
+ if (pVar->flags&NVRAM_FLAG_GUID) return (EFI_GUID*)(pVar+1);
+ else return pInfo->NvramGuidsAddress-*(UINT8*)(pVar+1);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetName
+//
+// Description: This function returns pointer to the Var name.
+//
+// Input: NVAR* pVar - pointer to the Var
+//
+// Output: VOID* - pionter to the Var name
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* NvGetName(NVAR* pVar)
+{
+ return (INT8*)(pVar+1)+(pVar->flags&NVRAM_FLAG_GUID ? sizeof(EFI_GUID) : 1);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetDataNvar
+//
+// Description: This function returns last variable in NVRAM storage.
+//
+// Input: NVAR* pVar - pointer to Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: NVAR* - pointer to the last Var
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NVAR* NvGetDataNvar(NVAR *pVar, NVRAM_STORE_INFO *pInfo)
+{
+ NVAR *pLastVar=NULL;
+
+ for (
+ ; NvIsVariable(pVar,pInfo) //--Check if pVar reccord is correct
+ ; pVar = (NVAR*)((UINT8*)pVar + pVar->next)
+ )
+ {
+ if (pVar->next==FLASH_EMPTY_NEXT) return pVar;
+
+ pLastVar=pVar;
+ }
+
+ return pLastVar;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetExtSize
+//
+// Description: This function returs pointer to Ext Size feild in Var
+//
+// Input: NVAR* NvStart - pointer to the Var to checksumm
+//
+// Output:
+// UINT16* Pointer to Ext Size feild in Var
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VAR_SIZE_TYPE* NvGetExtSize (NVAR* pVar)
+{
+ return (VAR_SIZE_TYPE*) (((UINT8*) pVar + pVar->size) - sizeof(VAR_SIZE_TYPE));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetExtFlags
+//
+// Description: This function returs pointer to Ext Flags feild in Var
+//
+// Input: NVAR* NvStart - pointer to the Var to checksumm
+//
+// Output:
+// UINT8* Pointer to Ext Flags feild in Var
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8* NvGetExtFlags (NVAR* pVar)
+{
+ return (UINT8*) ((UINT8*) NvGetExtSize (pVar) - *NvGetExtSize (pVar) + sizeof(VAR_SIZE_TYPE));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvCalculateNvarChecksum
+//
+// Description: This function calculates and Checks the checksum of the Var
+//
+// Input: NVAR* NvStart - pointer to the Var to checksumm
+// BOOLEAN Calculate - if TRUE - skeep checksumm feild in Var
+//
+// Output:
+// UINT8 Checksum value
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 NvCalculateNvarChecksum(NVAR* pVar)
+{
+ UINT8 *p, *Start;
+ UINT8 Checksum = 0;
+
+ if ( !(pVar->flags & NVRAM_FLAG_EXT_HEDER)
+ || !(*NvGetExtFlags(pVar) & NVRAM_EXT_FLAG_CHECKSUM)
+ ) return 0;
+
+ //calculate checksum of the variable excluding the header
+ Start = (UINT8*)(pVar+1);
+ for(p=Start; p < Start+pVar->size - sizeof(NVAR); p++)
+ {
+ Checksum += *p;
+ }
+ //add variable size
+ Start = (UINT8*)&pVar->size;
+ for(p=Start; p < Start+sizeof(VAR_SIZE_TYPE); p++)
+ {
+ Checksum += *p;
+ }
+ //add flags except NVRAM_FLAG_VALID
+ Checksum += pVar->flags;
+
+ return 0 - Checksum;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetData
+//
+// Description: This function returns last variable in NVRAM storage.
+//
+// Input: NVAR* pVar - pointer to Var
+// UINTN NameLength - Length of the Var name
+// UINTN* pDataSize - pointer to where the site of data returned will be store
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: VOID* - pointer to the Data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* NvGetData(NVAR* pVar, UINTN NameLength, UINTN* pDataSize, NVRAM_STORE_INFO *pInfo)
+{
+ UINTN DataOffset;
+ UINTN ExtSize;
+
+ pVar = NvGetDataNvar(pVar,pInfo);
+
+ if (pVar==NULL) return NULL;
+
+ DataOffset = sizeof(NVAR);
+
+ if (!(pVar->flags&NVRAM_FLAG_DATA_ONLY))
+ {
+ DataOffset += NameLength
+ + ( pVar->flags&NVRAM_FLAG_GUID
+ ? sizeof(EFI_GUID) : 1
+ );
+ }
+
+ if (pDataSize)
+ { // if Ext. Header present - get its size
+ if (pVar->flags & NVRAM_FLAG_EXT_HEDER) ExtSize = *NvGetExtSize (pVar);
+ else ExtSize = 0;
+ *pDataSize = pVar->size - DataOffset - ExtSize;
+ }
+
+ return (INT8*)pVar+DataOffset;
+}
+
+//Validation routines
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvIsValid
+//
+// Description: This function checks if passed Var is valid.
+//
+// Input: NVAR* pVar - pointer to the Var
+//
+// Output: BOOLEAN - TRUE of FALSE based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvIsValid(NVAR* pVar)
+{
+ return ((pVar->flags^~FLASH_EMPTY_FLAG)&NVRAM_FLAG_VALID) &&
+ !(pVar->flags&NVRAM_FLAG_DATA_ONLY);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvIsVariable
+//
+// Description: This function checks if pVar reccord is correct.
+//
+// Input: NVAR* pVar - pointer to Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: BOOLEAN - TRUE of FALSE based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvIsVariable(NVAR *pVar, NVRAM_STORE_INFO *pInfo)
+{
+ return
+ pVar->signature==NVAR_SIGNATURE
+ && pVar->flags!=FLASH_EMPTY_FLAG
+ && !(pVar->flags&~ALL_FLAGS)
+ && pVar->size!=FLASH_EMPTY_SIZE && pVar->size>sizeof(NVAR)
+ && pVar->size<=(pInfo->pEndOfVars-(UINT8*)pVar)
+ && ( pVar->next==FLASH_EMPTY_NEXT
+ || pVar->next>=pVar->size
+ && pVar->next<=(UINT32)(pInfo->pEndOfVars-(UINT8*)pVar)
+ )
+ && ( !(pVar->flags & NVRAM_FLAG_EXT_HEDER)
+ || !(*NvGetExtFlags (pVar) & NVRAM_EXT_FLAG_CHECKSUM)
+ || !(pVar->flags & NVRAM_FLAG_VALID)
+ || !NvCalculateNvarChecksum(pVar)
+ )
+ ;
+}
+
+//Iteration routines
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNextNvar
+//
+// Description: This function returns the next valid Var after pVar.
+//
+// Input: NVAR* pVar - pointer to Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: NVAR* - pointer to next valid Var after pVar, NULL - if none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NVAR* NvGetNextNvar(NVAR* pVar, NVRAM_STORE_INFO *pInfo)
+{
+ if (!pVar || pVar >= (NVAR*)pInfo->pEndOfVars) return NULL;
+
+ if (NvIsVariable(pVar,pInfo))
+ {
+ pVar = (NVAR*)((UINT8*)pVar+pVar->size);
+
+ if (pVar >= (NVAR*)pInfo->pEndOfVars) return NULL;
+ }
+
+ do
+ {
+ if (pVar >= (NVAR*)pInfo->pEndOfVars) return NULL;
+
+ //If we found a variable, we are done
+ if (NvIsVariable(pVar,pInfo)) return pVar;
+
+ //Otherwise, let's check if record size seems valid
+ //If size is valid, skip corrupted NVAR
+ //Otherwise give up and return NULL
+ if ( pVar->size!=FLASH_EMPTY_SIZE
+ && pVar->size>sizeof(NVAR)
+ && pVar->size<=(pInfo->pEndOfVars-(UINT8*)pVar)
+ ) pVar = (NVAR*)((UINT8*)pVar+pVar->size);
+ else return NULL;
+ }
+ while (TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNextNvar
+//
+// Description: This function returns the next valid Var after pVar.
+//
+// Input: NVAR* pVar - pointer to Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: NVAR* - pointer to next valid Var after pVar, NULL - if none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NVAR* NvGetNextValid(NVAR* pVar, NVRAM_STORE_INFO *pInfo)
+{
+ do
+ {
+ pVar = NvGetNextNvar(pVar,pInfo);
+ }
+ while (pVar && !NvIsValid(pVar));
+
+ return pVar;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetFirstValid
+//
+// Description: This function returns the first valid Var in NVRAM.
+//
+// Input: NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: NVAR* - pointer to first valid Var in NVRAM, NULL - if none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NVAR* NvGetFirstValid(NVRAM_STORE_INFO *pInfo)
+{
+ NVAR* pNvar = (NVAR*)pInfo->pFirstVar;
+
+ //We assume that the first variable pInfo->pFirstVar is non-corrupted.
+ //We checked for pInfo->pFirstVar validity
+ //during NVRAM_STORE_INFO initialization in NvInitInfoBuffer routine.
+ if (!NvIsVariable(pNvar,pInfo)) return NULL;
+
+ if (NvIsValid(pNvar)) return pNvar;
+
+ return NvGetNextValid(pNvar,pInfo);
+}
+
+//Comparison routines
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvAttribEq
+//
+// Description: This function checks if pNvar attributes ara same with Attributes passed.
+//
+// Input: NVAR* pNVar - pointer to Var
+// UINT32 Attributes - Attributes of Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: NVAR* - pointer to next valid Var after pVar, NULL - if none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvAttribEq(NVAR* pNvar, UINT32 Attributes, NVRAM_STORE_INFO *pInfo)
+{
+ //--- By ! we convert integer to boolean
+ return !(pNvar->flags & NVRAM_FLAG_RUNTIME)
+ == !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)
+ && !(pInfo->Flags & NVRAM_STORE_FLAG_NON_VALATILE)
+ == !(Attributes & EFI_VARIABLE_NON_VOLATILE)
+ && !(pNvar->flags & NVRAM_FLAG_HARDWARE_ERROR_RECORD)
+ == !(Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD)
+ && !(pNvar->flags & NVRAM_FLAG_AUTH_WRITE)
+ == !(Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES)
+ ;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvarEqNvar
+//
+// Description: This function verifies if two Var are the same
+//
+// Input: NVAR *Nvar1 - pointer to the first Var
+// IN NVRAM_STORE_INFO *Info1 - pointer to the first NVRAM_STORE_INFO structure
+// NVAR *Nvar2 - pointer to the second Var
+// IN NVRAM_STORE_INFO *Info2 - pointer to the second NVRAM_STORE_INFO structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvarEqNvar(
+ NVAR *Nvar1, NVRAM_STORE_INFO *Info1,
+ NVAR *Nvar2, NVRAM_STORE_INFO *Info2
+)
+{
+ EFI_GUID *Guid1, *Guid2;
+ UINT8 *Name1, *Name2;
+ BOOLEAN AsciiName = Nvar1->flags&NVRAM_FLAG_ASCII_NAME;
+
+ if (AsciiName != (Nvar2->flags&NVRAM_FLAG_ASCII_NAME)) return FALSE;
+
+ if ( (Info1->Flags & NVRAM_STORE_FLAG_NON_VALATILE)
+ != (Info2->Flags & NVRAM_STORE_FLAG_NON_VALATILE)
+ ) return FALSE;
+
+ Guid1=NvGetGuid(Nvar1,Info1);
+ Guid2=NvGetGuid(Nvar2,Info2);
+
+ if (guidcmp(Guid1,Guid2)) return FALSE;
+
+ Name1=(UINT8*)NvGetName(Nvar1);
+ Name2=(UINT8*)NvGetName(Nvar2);
+
+ if (AsciiName)
+ {
+ while (*Name1 && *Name1==*Name2) {Name1++; Name2++;}
+
+ if (*Name1!=*Name2) return FALSE;
+ }
+
+ else
+ {
+ CHAR16 *N1 = (CHAR16*)Name1;
+ CHAR16 *N2 = (CHAR16*)Name2;
+
+ while (*N1 && *N1==*N2) {N1++; N2++;}
+
+ if (*N1!=*N2) return FALSE;
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvVarEq
+//
+// Description: This function checks if pNvar GUID and Name ara same with passed one.
+//
+// Input: NVAR* pNVar - pointer to Var
+// CHAR16* sName - Name of the Var to compare
+// EFI_GUID* pGuid - pointer to GUID to compare with
+// UINTN* pNameSize - Pointer to memory where Nane size will be returned
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: BOOLEAN - TRUE of FALSE based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvVarEq(NVAR* pNvar, CHAR16* sName, EFI_GUID* pGuid, UINTN* pNameSize, NVRAM_STORE_INFO *pInfo)
+{
+ UINT8 *pVarGuid, *pNameStart, *pN;
+ pVarGuid=(UINT8*)NvGetGuid(pNvar,pInfo);
+ pN=(UINT8*)NvGetName(pNvar);
+ pNameStart=pN;
+ //-- Check name if ASCII
+ if (pNvar->flags&NVRAM_FLAG_ASCII_NAME)
+ {
+ while (*pN && *pN==*sName) {pN++; sName++;}
+
+ if (*pN!=*sName) return FALSE;
+
+ pN++;
+ }
+
+ else //-- Check name if Unicode
+ {
+ CHAR16 *sN=(CHAR16*)pN;
+
+ while (*sN && *sN==*sName) {sN++; sName++;}
+
+ if (*sN!=*sName) return FALSE;
+
+ pN=(UINT8*)++sN;
+ }
+
+ if (!guidcmp(pVarGuid,pGuid))//---Check GUID
+ {
+ if (pNameSize) *pNameSize=pN-pNameStart;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//High level routines that work with a single NV store
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvFindVariable
+//
+// Description: This function searches for Var with specific GUID and Name.
+//
+// Input: CHAR16* sName - Name of the Var to search
+// EFI_GUID* pGuid - pointer to GUID to search
+// UINTN* pNameSize - Pointer to memory where Nane size will be returned
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: VOID* - Pointer to found Var, NULL - if not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* NvFindVariable(
+ CHAR16* sName, EFI_GUID* pGuid,
+ UINTN* pNameSize, NVRAM_STORE_INFO *pInfo
+)
+{
+ NVAR* pNvar = NvGetFirstValid(pInfo);
+
+ for (; pNvar; pNvar=NvGetNextValid(pNvar,pInfo))
+ {
+ if (NvVarEq(pNvar,sName,pGuid,pNameSize,pInfo)) return pNvar;
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvFindVariableByNvar
+//
+// Description: This function searches for Var equal to one passed.
+//
+// Input: NVAR* SourceNvar - pointer to Var, which need to be found
+// NVRAM_STORE_INFO* SourceInfo - pointer to source NVRAM store structure
+// NVRAM_STORE_INFO* DestInfo - pointer to NVRAM store structure where to search
+//
+// Output: VOID* - Pointer to found Var, NULL - if not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* NvFindVariableByNvar(NVAR* SourceNvar,
+ NVRAM_STORE_INFO *SourceInfo, NVRAM_STORE_INFO *DestInfo
+)
+{
+ NVAR* pNvar = NvGetFirstValid(DestInfo);
+
+ for (; pNvar; pNvar=NvGetNextValid(pNvar,DestInfo))
+ {
+ if (NvarEqNvar(SourceNvar, SourceInfo, pNvar, DestInfo)) return pNvar;
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetAttributesFromNvar
+//
+// Description: This function returns the attributes from a given Nvar
+//
+// Input: NVAR* pNVar - pointer to Var
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetAttributesFromNvar(
+ IN NVAR *pNvar, IN NVRAM_STORE_INFO *pInfo,
+ OUT UINT32 *Attributes
+)
+{
+ if (!pNvar || !pInfo || !Attributes) return EFI_INVALID_PARAMETER;
+
+ *Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ if ( pNvar->flags & NVRAM_FLAG_RUNTIME )
+ *Attributes|=EFI_VARIABLE_RUNTIME_ACCESS;
+ if ( pInfo->Flags & NVRAM_STORE_FLAG_NON_VALATILE )
+ *Attributes|=EFI_VARIABLE_NON_VOLATILE;
+ if ( pNvar->flags & NVRAM_FLAG_HARDWARE_ERROR_RECORD )
+ *Attributes|=EFI_VARIABLE_HARDWARE_ERROR_RECORD;
+ if ( pNvar->flags & NVRAM_FLAG_AUTH_WRITE )
+ *Attributes|= (UINT8)(*NvGetExtFlags (pNvar) & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetVariableFromNvar
+//
+// Description: This function searches for Var with specific GUID and Name.
+//
+// Input: NVAR* pNVar - pointer to Var
+// UINTN NameSize - size of the Var name
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// OUT UINT8 *Flags - Pointer to memory where Var Flags will be returned
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetVariableFromNvar(
+ NVAR *pNvar, UINTN NameSize, OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data,
+ IN NVRAM_STORE_INFO *pInfo, OUT UINT8 *Flags
+)
+{
+ UINT8* pN;
+ UINTN Size;
+
+ if (!pNvar || !NvIsVariable(pNvar,pInfo)) return EFI_NOT_FOUND;
+
+ if (Attributes)
+ NvGetAttributesFromNvar(pNvar, pInfo, Attributes);
+
+ // Data
+ pN = (UINT8*)NvGetData(pNvar,NameSize,&Size,pInfo);
+
+ if (*DataSize<Size) { *DataSize=Size; return EFI_BUFFER_TOO_SMALL;}
+
+ *DataSize=Size;
+ MemCpy(Data,pN,Size);
+
+ if (Flags) *Flags=pNvar->flags;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetVariable
+//
+// Description: This function searches for a Var after Var with specific GUID and Name.
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// OUT NVAR **Var - pointer to found Var variable
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data,
+ IN NVRAM_STORE_INFO *pInfo, OUT NVAR **Var
+)
+{
+ UINTN NameSize;
+ NVAR* pNvar;
+
+ if (!VariableName || !VendorGuid || !DataSize || !Data && *DataSize)
+ return EFI_INVALID_PARAMETER;
+
+ pNvar = (NVAR*)NvFindVariable(VariableName,VendorGuid,&NameSize,pInfo);
+ if ((Var != NULL) && (pNvar != NULL))
+ *Var = pNvar;
+ return NvGetVariableFromNvar(pNvar,NameSize,Attributes,DataSize,Data,pInfo, NULL);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNameFromNvar
+//
+// Description: This function searches for a Var after Var with specific GUID and returns it's Name.
+//
+// Input: IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID will be stored
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// BOOLEAN Runtime - search for Var with NVRAM_FLAG_RUNTIME set
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetNameFromNvar(
+ IN NVAR *pNvar, IN OUT CHAR16 *VariableName,
+ IN OUT UINTN *VariableNameSize,
+ IN OUT EFI_GUID *VendorGuid, NVRAM_STORE_INFO *pInfo
+)
+{
+ UINTN NameSize;
+ UINT8 *pN, *pNameStart;
+ EFI_GUID* pVarGuid;
+
+ if (!pNvar || !VariableNameSize || !VariableName || !VendorGuid) return EFI_INVALID_PARAMETER;
+
+
+ pN = pNameStart = (UINT8*)NvGetName(pNvar);
+
+ if (pNvar->flags&NVRAM_FLAG_ASCII_NAME)
+ {
+ while (*pN++);
+
+ NameSize = (pN - pNameStart)*2;
+ }
+
+ else
+ {
+ CHAR16* sN=(CHAR16*)pN;
+
+ while (*sN++);
+
+ pN=(UINT8*)sN;
+ NameSize = pN - pNameStart;
+ }
+
+ if (NameSize>*VariableNameSize)
+ {
+ *VariableNameSize=NameSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *VariableNameSize=NameSize;
+ pVarGuid=NvGetGuid(pNvar,pInfo);
+
+ if (pNvar->flags&NVRAM_FLAG_ASCII_NAME) while (*VariableName++=*pNameStart++);
+ else
+ {
+ CHAR16* sN = (CHAR16*)pNameStart;
+
+ while (*VariableName++=*sN++);
+ }
+
+ MemCpy(VendorGuid,pVarGuid,sizeof(EFI_GUID));
+ pInfo->pLastReturned = pNvar;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNextVariableNvar
+//
+// Description: This function searches for a Var after Var with specific GUID and returns
+// pointer to is using NextNvar parameter
+//
+// Input:
+// IN CHAR16 *VariableName - pointer to a Var Name in Unicode
+// IN OUT EFI_GUID *VendorGuid - pointer to Var GUID
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// BOOLEAN Runtime - search for Var with NVRAM_FLAG_RUNTIME set
+// NVAR **NextNvar - pointer to the next varaible's NVAR
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetNextVariableNvar(
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid,
+ NVRAM_STORE_INFO *pInfo, BOOLEAN Runtime, NVAR **NextNvar
+)
+{
+ NVAR* pNvar;
+
+ if (!VariableName || !VendorGuid) return EFI_INVALID_PARAMETER;
+
+ if (VariableName[0]==0)
+ {
+ pNvar = NvGetFirstValid(pInfo);
+ }
+
+ else
+ {
+ if ( pInfo->pLastReturned!=NULL
+ && NvIsVariable(pInfo->pLastReturned, pInfo)
+ && NvVarEq(pInfo->pLastReturned,VariableName,VendorGuid,NULL, pInfo)
+ )
+ {
+ pNvar=pInfo->pLastReturned;
+ }
+
+ else
+ {
+ UINTN NameSize;
+ pNvar=(NVAR*)NvFindVariable(VariableName,VendorGuid,&NameSize,pInfo);
+
+ if (!pNvar) return EFI_INVALID_PARAMETER;
+ }
+ if (Runtime && !(pNvar->flags & NVRAM_FLAG_RUNTIME) ) return EFI_INVALID_PARAMETER;
+ pNvar=NvGetNextValid(pNvar,pInfo);
+ }
+
+ if (!pNvar)
+ {
+ pInfo->pLastReturned = NULL;
+ return EFI_NOT_FOUND;
+ }
+
+ if (Runtime)
+ {
+ while (pNvar && !(pNvar->flags & NVRAM_FLAG_RUNTIME))
+ pNvar=NvGetNextValid(pNvar,pInfo);
+
+ if (!pNvar)
+ {
+ pInfo->pLastReturned = NULL;
+ return EFI_NOT_FOUND;
+ }
+ }
+ if (NextNvar) *NextNvar = pNvar;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNextVariableName
+//
+// Description: This function searches for a Var after Var with specific GUID and returns it's Name.
+//
+// Input: IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID will be stored
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// BOOLEAN Runtime - search for Var with NVRAM_FLAG_RUNTIME set
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetNextVariableName(
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid,
+ NVRAM_STORE_INFO *pInfo, BOOLEAN Runtime
+)
+{
+ NVAR* pNvar;
+ EFI_STATUS Status;
+
+ Status=NvGetNextVariableNvar(VariableName,VendorGuid,pInfo,Runtime,&pNvar);
+ if (EFI_ERROR(Status)) return Status;
+ return NvGetNameFromNvar(
+ pNvar, VariableName, VariableNameSize, VendorGuid, pInfo
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvInitInfoBuffer
+//
+// Description: This function inits NVRAM_STORE_INFO structure.
+//
+// Input: NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// UINTN HeaderSize - Size of the header
+// UINT8 Flags - default Flags
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NvInitInfoBuffer(IN NVRAM_STORE_INFO *pInfo, UINTN HeaderSize, UINT8 Flags)
+{
+ NVAR *pVar;
+ pInfo->NvramGuidsAddress = (EFI_GUID*)(pInfo->NvramAddress+pInfo->NvramSize-sizeof(EFI_GUID));
+ pInfo->pFirstVar = pInfo->NvramAddress+HeaderSize;
+ pInfo->NextGuid = 0;
+ pInfo->Flags = Flags;
+ pInfo->LastVarSize = 0;
+ pInfo->pLastReturned = NULL;
+
+ if (!(Flags & NVRAM_STORE_FLAG_NON_VALATILE))
+ {
+ pInfo->pEndOfVars = pInfo->pFirstVar;
+ return;
+ }
+
+ pInfo->pEndOfVars = pInfo->NvramAddress+pInfo->NvramSize;
+ pVar = NvGetFirstValid(pInfo);
+
+ if ((NVAR*)pInfo->pFirstVar!=pVar)
+ {
+ if (pVar!=NULL)
+ {
+ pInfo->pFirstVar=(UINT8*)pVar;
+ }
+
+ else //if pVar==NULL
+ {
+ //there are no valid variables
+ //set pEndOfVars equal to pFirstVar to indicate that variable store is empty
+ pInfo->pEndOfVars = pInfo->pFirstVar;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetDefaultsInfo
+//
+// Description: This function returns Default Variables info.
+//
+// Input: IN const CHAR16* DefaultsVar - name of the defaults Vars
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// OUT NVRAM_STORE_INFO *pOutInfo - pointer to memory where defaults vill be stored
+// NULL - if not found
+//
+// Output: NVRAM_STORE_INFO*
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NVRAM_STORE_INFO* NvGetDefaultsInfo(IN const CHAR16* DefaultsVar, IN NVRAM_STORE_INFO *pInInfo, OUT NVRAM_STORE_INFO *pOutInfo)
+{
+ UINTN NameSize;
+ NVAR* pNvar;
+ pNvar = (NVAR*)NvFindVariable(
+ (CHAR16*)DefaultsVar, (EFI_GUID*)&AmiDefaultsVariableGuid,
+ &NameSize,pInInfo
+ );
+
+ if (!pNvar) return NULL;
+
+ pOutInfo->NvramAddress = (UINT8*)NvGetData(
+ pNvar,NameSize,
+ &pOutInfo->NvramSize,pInInfo
+ );
+
+ if (pOutInfo->NvramAddress==NULL) return NULL;
+
+ NvInitInfoBuffer(
+ pOutInfo, 0,
+ NVRAM_STORE_FLAG_NON_VALATILE
+ | NVRAM_STORE_FLAG_READ_ONLY
+ | NVRAM_STORE_FLAG_DO_NOT_ENUMERATE
+ );
+ return pOutInfo;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetVariable2
+//
+// Description: This function searches for Var with specific GUID, Name and Enty number
+// not bigger than InfoCount parameter.
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+// UINT32 InfoCount - Max NVRAM entry number
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetVariable2(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data,
+ UINT32 InfoCount, NVRAM_STORE_INFO *Info
+)
+{
+ UINT32 i;
+
+ for (i=0; i<InfoCount; i++)
+ {
+ EFI_STATUS Status = NvGetVariable(
+ VariableName,VendorGuid,Attributes,DataSize,Data,&Info[i],NULL
+ );
+
+ if (Status!=EFI_NOT_FOUND) return Status;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNextVariableName2
+//
+// Description: This function searches for Var with specific GUID and Enty number
+// not betwin LastInfoIndex - InfoCount parameter and returns it's Name.
+//
+// Input: IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID will be stored
+// UINT32 InfoCount - Max NVRAM entry number
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// UINT32 *LastInfoIndex - NVRAM entry number to starf from
+// BOOLEAN Runtime - search for Var with NVRAM_FLAG_RUNTIME set
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetNextVariableName2(
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid,
+ UINT32 InfoCount, NVRAM_STORE_INFO *pInfo, UINT32 *LastInfoIndex,
+ BOOLEAN Runtime
+)
+{
+ UINT32 i;
+ EFI_STATUS Status;
+ NVAR* Nvar;
+ CHAR16 OrgName;
+
+ OrgName = VariableName[0];
+ // Preserve first letter of passed Var name, for the case when NvGetNameFromNvar returns EFI_BUFFER_TOO_SMALL right
+ // after setting first letter of name to 0 for search in the next Varstore
+ if (VariableName[0]==0 && LastInfoIndex) *LastInfoIndex=0;
+
+ for ( i=(LastInfoIndex) ? *LastInfoIndex : 0
+ ; i<InfoCount; i++
+ )
+ {
+ Status=NvGetNextVariableNvar(VariableName,VendorGuid,&pInfo[i],Runtime,&Nvar);
+ if (!EFI_ERROR(Status) && pInfo[i].Flags & NVRAM_STORE_FLAG_DO_NOT_ENUMERATE){
+ while ( Nvar ){
+ UINT32 j;
+ for (j = 0; j < i; j++)
+ if (NvFindVariableByNvar(Nvar, &pInfo[i], &pInfo[j] ))
+ break;
+ if (j==i) break;
+ Nvar=NvGetNextValid(Nvar,&pInfo[i]);
+ if ( Runtime ){
+ while (Nvar && !(Nvar->flags & NVRAM_FLAG_RUNTIME))
+ Nvar=NvGetNextValid(Nvar,&pInfo[i]);
+ }
+ }
+ if (!Nvar)
+ {
+ pInfo[i].pLastReturned = NULL;
+ Status=EFI_NOT_FOUND;
+ }
+ }
+
+ if (!EFI_ERROR(Status))
+ {
+ if (LastInfoIndex) *LastInfoIndex=i;
+ Status = NvGetNameFromNvar(
+ Nvar, VariableName, VariableNameSize, VendorGuid, &pInfo[i]
+ );
+ if (EFI_ERROR(Status)) {
+ VariableName[0] = OrgName; //Restore first letter in case it was set to 0 before going to new Varstore
+ }
+ return Status;
+ }
+
+ //When variable with VariableName/VendorGuid
+ //is not is the store EFI_INVALID_PARAMETER is returned
+ //and we have to keep searching.
+ //EFI_NOT_FOUND is returned when variable with VariableName/VendorGuid
+ //is found but it's the last variable in the store.
+ //In this case we have to return first variable from the next store
+ //In order to do that we need to reset the name
+ if (Status==EFI_NOT_FOUND)
+ {
+ VariableName[0]=0;
+ }
+
+ else
+ {
+ //If we are here the Status should be EFI_INVALID_PARAMETER,
+ //which means the variable with VariableName/VendorGuid has not been found.
+ //If we were using LastInfoIndex, the fact that variable has not been found
+ //indicates that LastInfoIndex is invalid and we have to restart the search.
+ //The condition below checks if LastInfoIndex has been used during this iteration.
+ //Seting i to -1 in conjunction with i++ at the end of the iteration restarts
+ //the search from 0.
+ if (LastInfoIndex && i!=0 && i==*LastInfoIndex){
+ i=(UINT32)-1;
+ *LastInfoIndex = 0;
+ }
+ }
+ }
+
+ if (LastInfoIndex) *LastInfoIndex=0;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetNvramFfsFileStatePtr
+//
+// Description: This function searches for firmvare vol header and returns pointer to its State field
+//
+// Input: NVRAM_STORE_INFO *Info - pointer to NVRAM store structure
+//
+// Output: EFI_FFS_FILE_STATE* - pointer to Ffs header State field
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_FFS_FILE_STATE* GetNvramFfsFileStatePtr(NVRAM_STORE_INFO *Info)
+{
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Info->NvramAddress;
+
+ if (FwVolHeader->FvLength == Info->NvramSize)
+ {
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)(
+ Info->NvramAddress + FwVolHeader->HeaderLength
+ );
+ return &FfsFileHeader->State;
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetNvramFfsFileState
+//
+// Description: This function searches for the header of the NVRAM image FFS file and returns the value of its State field
+//
+// Input: NVRAM_STORE_INFO *Info - pointer to NVRAM store structure
+//
+// Output: EFI_FFS_FILE_STATE - Ffs header State
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_FFS_FILE_STATE GetNvramFfsFileState(NVRAM_STORE_INFO *Info)
+{
+ EFI_FFS_FILE_STATE State;
+ EFI_FFS_FILE_STATE *StatePtr = GetNvramFfsFileStatePtr(Info);
+ if (StatePtr==NULL) return EFI_FILE_HEADER_INVALID;
+ State = (FlashEmpty==0) ? *StatePtr : ~*StatePtr;
+ if (State==0) State = EFI_FILE_HEADER_INVALID;
+ return State;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsMainNvramStoreValid
+//
+// Description: This function verifies if main NVRAM storage is valid
+//
+// Input:
+// NVRAM_STORE_INFO *MainInfo - pointer to Main NVRAM storage descriptor
+// VOID *BackUpAddress - address of the back up storage
+//
+// Output: BOOLEAN
+// TRUE - the main NVRAM storage is valid
+// FALSE - the main NVRAM storage is invalid. Back up srorage should be used.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsMainNvramStoreValid(
+ NVRAM_STORE_INFO *MainInfo, VOID *BackUpAddress,
+ BOOLEAN *BackupStoreValid
+){
+ NVRAM_STORE_INFO BackupNvram;
+ EFI_FFS_FILE_STATE MainState;
+ EFI_FFS_FILE_STATE BackupState;
+
+ if (BackUpAddress==NULL) return TRUE;
+ BackupNvram.NvramAddress = BackUpAddress;
+ BackupNvram.NvramSize = MainInfo->NvramSize;
+ MainState = GetNvramFfsFileState(MainInfo);
+ BackupState = GetNvramFfsFileState(&BackupNvram);
+// State Transitions:
+// Main Backup Valid Store
+// = Initial State After Firmware Flashing
+// 1. DATA_VALID HEADER_INVALID Main
+// = Update Cycle 1
+// 2. DATA_VALID HEADER_VALID Main
+// 3. MARKED_FOR_UPDATE HEADER_VALID Main
+// 4. MARKED_FOR_UPDATE DATA_VALID Backup
+// = Update Cycle 1 is Over
+// = Update Cycle 2
+// 5. HEADER_VALID DATA_VALID Backup
+// 6. HEADER_VALID MARKED_FOR_UPDATE Backup
+// 7. DATA_VALID MARKED_FOR_UPDATE Main
+// = Update Cycle 2 is Over
+// = Update Cycle 3
+// 8. DATA_VALID HEADER_VALID Main
+// Stae 8 == State 2
+ if ( (MainState & EFI_FILE_DATA_VALID)==0
+ || (MainState & EFI_FILE_MARKED_FOR_UPDATE)!=0
+ &&(BackupState & EFI_FILE_DATA_VALID)!=0
+ ||(MainState & ~VALID_STATE_FLAGS)!=0
+ ){
+ if (BackupStoreValid)
+ *BackupStoreValid=
+ ((BackupState & EFI_FILE_DATA_VALID)!=0)
+ &&((BackupState & ~VALID_STATE_FLAGS)==0)
+ ;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************