refine VariablePei driver to unify the algorithm of access VariableIndexTable among various archs.

1. record the distance of two neighboring VAR_ADDED type variables rather than the offset of each variable. As the field recording this info is UINT16 width, the latter causes in IA32/X64 platform, it can only cache those variables from offset 0 to offset 2^16; in IPF platform, from offset 0 to offset 2^18(extend the scope by left-shift the offset two bits).
when taking the former algorithm, the max range of caching variable is from offset 0 to offset 122*(2^16)

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8625 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
eric_tian 2009-06-23 08:30:04 +00:00
parent 48a9ea7b1b
commit 841014ba97
5 changed files with 45 additions and 163 deletions

View File

@ -1,58 +0,0 @@
/** @file
Variable worker functions specific for IPF arch.
Copyright (c) 2006 - 2008, Intel Corporation<BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Variable.h"
/**
Get one variable by the index count.
@param IndexTable The pointer to variable index table.
@param Count The index count of variable in index table.
@return The pointer to variable header indexed by count.
**/
VARIABLE_HEADER *
GetVariableByIndex (
IN VARIABLE_INDEX_TABLE *IndexTable,
IN UINT32 Count
)
{
return (VARIABLE_HEADER *) (UINTN) ((((UINT32)IndexTable->Index[Count]) << 2) + ((UINT32)(UINTN)IndexTable->StartPtr & 0xFFFC0000) );
}
/**
Record Variable in VariableIndex HOB.
Record Variable in VariableIndex HOB and update the length of variable index table.
@param IndexTable The pointer to variable index table.
@param Variable The pointer to the variable that will be recorded.
**/
VOID
VariableIndexTableUpdate (
IN OUT VARIABLE_INDEX_TABLE *IndexTable,
IN VARIABLE_HEADER *Variable
)
{
if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {
IndexTable->Index[IndexTable->Length++] = (UINT16) (((UINT32)(UINTN) Variable) >> 2);
}
return;
}

View File

@ -366,10 +366,13 @@ FindVariable (
EFI_HOB_GUID_TYPE *GuidHob;
VARIABLE_STORE_HEADER *VariableStoreHeader;
VARIABLE_HEADER *Variable;
VARIABLE_HEADER *LastVariable;
VARIABLE_HEADER *MaxIndex;
VARIABLE_INDEX_TABLE *IndexTable;
UINT32 Count;
UINT32 Offset;
UINT8 *VariableBase;
BOOLEAN StopRecord;
if (VariableName[0] != 0 && VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
@ -378,9 +381,16 @@ FindVariable (
// No Variable Address equals zero, so 0 as initial value is safe.
//
MaxIndex = 0;
StopRecord = FALSE;
GuidHob = GetFirstGuidHob (&mEfiVariableIndexTableGuid);
if (GuidHob == NULL) {
//
// If it's the first time to access variable region in flash, create a guid hob to record
// VAR_ADDED type variable info.
// Note that as the resource of PEI phase is limited, only store the number of
// VARIABLE_INDEX_TABLE_VOLUME of VAR_ADDED type variables to reduce access time.
//
IndexTable = BuildGuidHob (&mEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));
IndexTable->Length = 0;
IndexTable->StartPtr = NULL;
@ -388,9 +398,13 @@ FindVariable (
IndexTable->GoneThrough = 0;
} else {
IndexTable = GET_GUID_HOB_DATA (GuidHob);
for (Count = 0; Count < IndexTable->Length; Count++) {
MaxIndex = GetVariableByIndex (IndexTable, Count);
for (Offset = 0, Count = 0; Count < IndexTable->Length; Count++) {
//
// traverse the variable info list to look for varible.
// The IndexTable->Index[Count] records the distance of two neighbouring VAR_ADDED type variables.
//
Offset += IndexTable->Index[Count];
MaxIndex = (VARIABLE_HEADER *)((CHAR8 *)(IndexTable->StartPtr) + Offset);
if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
PtrTrack->StartPtr = IndexTable->StartPtr;
PtrTrack->EndPtr = IndexTable->EndPtr;
@ -407,7 +421,8 @@ FindVariable (
// If not found in HOB, then let's start from the MaxIndex we've found.
//
if (MaxIndex != NULL) {
Variable = GetNextVariablePtr (MaxIndex);
Variable = GetNextVariablePtr (MaxIndex);
LastVariable = MaxIndex;
} else {
if ((IndexTable->StartPtr != NULL) || (IndexTable->EndPtr != NULL)) {
Variable = IndexTable->StartPtr;
@ -435,6 +450,8 @@ FindVariable (
//
Variable = IndexTable->StartPtr;
}
LastVariable = IndexTable->StartPtr;
}
//
// Find the variable by walk through non-volatile variable store
@ -447,8 +464,23 @@ FindVariable (
//
// Record Variable in VariableIndex HOB
//
VariableIndexTableUpdate (IndexTable, Variable);
if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME && StopRecord != TRUE) {
Offset = (UINT32)((UINTN)Variable - (UINTN)LastVariable);
//
// The distance of two neighbouring VAR_ADDED variable is larger than 2^16,
// which is beyond the allowable scope(UINT16) of record. In such case, need not to
// record the subsequent VAR_ADDED type variables again.
//
if ((Offset & 0xFFFF0000UL) != 0) {
StopRecord = TRUE;
}
if (StopRecord != TRUE) {
IndexTable->Index[IndexTable->Length++] = (UINT16) Offset;
}
LastVariable = Variable;
}
if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {
return EFI_SUCCESS;
}

View File

@ -41,11 +41,18 @@ typedef struct {
#define EFI_VARIABLE_INDEX_TABLE_GUID \
{ 0x8cfdb8c8, 0xd6b2, 0x40f3, { 0x8e, 0x97, 0x02, 0x30, 0x7c, 0xc9, 0x8b, 0x7c } }
///
/// Use this data structure to store variable-related info, which can decrease
/// the cost of access to NV.
///
typedef struct {
UINT16 Length;
UINT16 GoneThrough;
VARIABLE_HEADER *EndPtr;
VARIABLE_HEADER *StartPtr;
///
/// This field is used to store the distance of two neighbouring VAR_ADDED type variables.
/// The meaning of the field is implement-dependent.
UINT16 Index[VARIABLE_INDEX_TABLE_VOLUME];
} VARIABLE_INDEX_TABLE;
@ -146,34 +153,4 @@ PeiGetNextVariableName (
IN OUT EFI_GUID *VariableGuid
);
/**
Get one variable by the index count.
@param IndexTable The pointer to variable index table.
@param Count The index count of variable in index table.
@return The pointer to variable header indexed by count.
**/
VARIABLE_HEADER *
GetVariableByIndex (
IN VARIABLE_INDEX_TABLE *IndexTable,
IN UINT32 Count
);
/**
Record Variable in VariableIndex HOB.
Record Variable in VariableIndex HOB and update the length of variable index table.
@param IndexTable The pointer to variable index table.
@param Variable The pointer to the variable that will be recorded.
**/
VOID
VariableIndexTableUpdate (
IN OUT VARIABLE_INDEX_TABLE *IndexTable,
IN VARIABLE_HEADER *Variable
);
#endif

View File

@ -32,18 +32,6 @@
Variable.c
Variable.h
[Sources.Ia32]
VariableWorker.c
[Sources.X64]
VariableWorker.c
[Sources.IPF]
Ipf/VariableWorker.c
[Sources.EBC]
VariableWorker.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec

View File

@ -1,57 +0,0 @@
/** @file
Variable worker functions specific for IA32, X64 and EBC.
Copyright (c) 2007 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Variable.h"
/**
Get one variable by the index count.
@param IndexTable The pointer to variable index table.
@param Count The index count of variable in index table.
@return The pointer to variable header indexed by count.
**/
VARIABLE_HEADER *
GetVariableByIndex (
IN VARIABLE_INDEX_TABLE *IndexTable,
IN UINT32 Count
)
{
return (VARIABLE_HEADER *) (UINTN) (IndexTable->Index[Count] + ((UINTN) IndexTable->StartPtr & 0xFFFF0000));
}
/**
Record Variable in VariableIndex HOB.
Record Variable in VariableIndex HOB and update the length of variable index table.
@param IndexTable The pointer to variable index table.
@param Variable The pointer to the variable that will be recorded.
**/
VOID
VariableIndexTableUpdate (
IN OUT VARIABLE_INDEX_TABLE *IndexTable,
IN VARIABLE_HEADER *Variable
)
{
if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {
IndexTable->Index[IndexTable->Length++] = (UINT16) (UINTN) Variable;
}
return;
}