Implement ReadOnly Variable Services required by PEIM and install\r
PEI ReadOnly Varaiable2 PPI. These services operates the non volatile storage space.\r
\r
-Copyright (c) 2006 - 2008 Intel Corporation. <BR>\r
+Copyright (c) 2006 - 2009 Intel Corporation. <BR>\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
/**\r
Provide the functionality of the variable services.\r
\r
- @param FileHandle Handle of the file being invoked. \r
- Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().\r
+ @param FileHandle Handle of the file being invoked. \r
+ Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile().\r
@param PeiServices General purpose services available to every PEIM.\r
\r
@retval EFI_SUCCESS If the interface could be successfully installed\r
IN CONST EFI_PEI_SERVICES **PeiServices\r
)\r
{\r
+ EFI_BOOT_MODE BootMode;\r
+ EFI_STATUS Status;\r
+\r
//\r
- // Publish the variable capability to other modules\r
- //\r
+ // Check if this is recovery boot path. If no, publish the variable access capability\r
+ // to other modules. If yes, the content of variable area is not reliable. Therefore,\r
+ // in this case we should not provide variable service to other pei modules. \r
+ // \r
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
return PeiServicesInstallPpi (&mPpiListVariable);\r
\r
}\r
\r
-\r
/**\r
- This code gets the pointer to the first variable memory pointer byte.\r
\r
- @param VarStoreHeader Pointer to the Variable Store Header.\r
+ Gets the pointer to the first variable header in given variable store area.\r
\r
- @return VARIABLE_HEADER* pointer to last unavailable Variable Header.\r
+ @param VarStoreHeader Pointer to the Variable Store Header.\r
+\r
+ @return Pointer to the first variable header\r
\r
**/\r
VARIABLE_HEADER *\r
)\r
{\r
if (Variable->State == (UINT8) (-1) ||\r
- Variable->DataSize == (UINT32) -1 ||\r
- Variable->NameSize == (UINT32) -1 ||\r
- Variable->Attributes == (UINT32) -1) {\r
+ Variable->DataSize == (UINT32) (-1) ||\r
+ Variable->NameSize == (UINT32) (-1) ||\r
+ Variable->Attributes == (UINT32) (-1)) {\r
return 0;\r
}\r
return (UINTN) Variable->NameSize;\r
IN VARIABLE_HEADER *Variable\r
)\r
{\r
- if (Variable->State == (UINT8) -1 ||\r
- Variable->DataSize == (UINT32) -1 ||\r
- Variable->NameSize == (UINT32) -1 ||\r
- Variable->Attributes == (UINT32) -1) {\r
+ if (Variable->State == (UINT8) (-1) ||\r
+ Variable->DataSize == (UINT32) (-1) ||\r
+ Variable->NameSize == (UINT32) (-1) ||\r
+ Variable->Attributes == (UINT32) (-1)) {\r
return 0;\r
}\r
return (UINTN) Variable->DataSize;\r
IN VARIABLE_STORE_HEADER *VarStoreHeader\r
)\r
{\r
- if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&\r
+ \r
+ if (CompareGuid (&VarStoreHeader->Signature, &gEfiVariableGuid) &&\r
VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&\r
VarStoreHeader->State == VARIABLE_STORE_HEALTHY\r
) {\r
return EfiValid;\r
}\r
\r
- if (VarStoreHeader->Signature == 0xffffffff &&\r
+ if (((UINT32 *)(&VarStoreHeader->Signature))[0] == 0xffffffff &&\r
+ ((UINT32 *)(&VarStoreHeader->Signature))[1] == 0xffffffff &&\r
+ ((UINT32 *)(&VarStoreHeader->Signature))[2] == 0xffffffff &&\r
+ ((UINT32 *)(&VarStoreHeader->Signature))[3] == 0xffffffff &&\r
VarStoreHeader->Size == 0xffffffff &&\r
VarStoreHeader->Format == 0xff &&\r
VarStoreHeader->State == 0xff\r
EFI_HOB_GUID_TYPE *GuidHob;\r
VARIABLE_STORE_HEADER *VariableStoreHeader;\r
VARIABLE_HEADER *Variable;\r
+ VARIABLE_HEADER *LastVariable;\r
VARIABLE_HEADER *MaxIndex;\r
VARIABLE_INDEX_TABLE *IndexTable;\r
UINT32 Count;\r
+ UINT32 Offset;\r
UINT8 *VariableBase;\r
+ BOOLEAN StopRecord;\r
\r
- if (VariableName != 0 && VendorGuid == NULL) {\r
+ if (VariableName[0] != 0 && VendorGuid == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
//\r
// No Variable Address equals zero, so 0 as initial value is safe.\r
//\r
MaxIndex = 0;\r
+ StopRecord = FALSE;\r
\r
GuidHob = GetFirstGuidHob (&mEfiVariableIndexTableGuid);\r
if (GuidHob == NULL) {\r
+ //\r
+ // If it's the first time to access variable region in flash, create a guid hob to record\r
+ // VAR_ADDED type variable info.\r
+ // Note that as the resource of PEI phase is limited, only store the number of \r
+ // VARIABLE_INDEX_TABLE_VOLUME of VAR_ADDED type variables to reduce access time.\r
+ //\r
IndexTable = BuildGuidHob (&mEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE));\r
IndexTable->Length = 0;\r
IndexTable->StartPtr = NULL;\r
IndexTable->GoneThrough = 0;\r
} else {\r
IndexTable = GET_GUID_HOB_DATA (GuidHob);\r
- for (Count = 0; Count < IndexTable->Length; Count++) {\r
- MaxIndex = GetVariableByIndex (IndexTable, Count);\r
-\r
+ for (Offset = 0, Count = 0; Count < IndexTable->Length; Count++) {\r
+ //\r
+ // traverse the variable info list to look for varible.\r
+ // The IndexTable->Index[Count] records the distance of two neighbouring VAR_ADDED type variables.\r
+ //\r
+ ASSERT (Count < VARIABLE_INDEX_TABLE_VOLUME);\r
+ Offset += IndexTable->Index[Count];\r
+ MaxIndex = (VARIABLE_HEADER *)((CHAR8 *)(IndexTable->StartPtr) + Offset);\r
if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r
PtrTrack->StartPtr = IndexTable->StartPtr;\r
PtrTrack->EndPtr = IndexTable->EndPtr;\r
// If not found in HOB, then let's start from the MaxIndex we've found.\r
//\r
if (MaxIndex != NULL) {\r
- Variable = GetNextVariablePtr (MaxIndex);\r
+ Variable = GetNextVariablePtr (MaxIndex);\r
+ LastVariable = MaxIndex;\r
} else {\r
if ((IndexTable->StartPtr != NULL) || (IndexTable->EndPtr != NULL)) {\r
Variable = IndexTable->StartPtr;\r
//\r
Variable = IndexTable->StartPtr;\r
}\r
+\r
+ LastVariable = IndexTable->StartPtr;\r
}\r
//\r
// Find the variable by walk through non-volatile variable store\r
PtrTrack->StartPtr = IndexTable->StartPtr;\r
PtrTrack->EndPtr = IndexTable->EndPtr;\r
\r
- while (IsValidVariableHeader (Variable) && (Variable <= IndexTable->EndPtr)) {\r
+ while ((Variable < IndexTable->EndPtr) && IsValidVariableHeader (Variable)) {\r
if (Variable->State == VAR_ADDED) {\r
//\r
// Record Variable in VariableIndex HOB\r
//\r
- if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) {\r
- VariableIndexTableUpdate (IndexTable, Variable);\r
+ if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME && StopRecord != TRUE) {\r
+ Offset = (UINT32)((UINTN)Variable - (UINTN)LastVariable);\r
+ //\r
+ // The distance of two neighbouring VAR_ADDED variable is larger than 2^16, \r
+ // which is beyond the allowable scope(UINT16) of record. In such case, need not to\r
+ // record the subsequent VAR_ADDED type variables again.\r
+ //\r
+ if ((Offset & 0xFFFF0000UL) != 0) {\r
+ StopRecord = TRUE;\r
+ }\r
+\r
+ if (StopRecord != TRUE) {\r
+ IndexTable->Index[IndexTable->Length++] = (UINT16) Offset;\r
+ }\r
+ LastVariable = Variable;\r
}\r
\r
if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) {\r
@param VariableNameSize On entry, points to the size of the buffer pointed to by VariableName.\r
@param VariableName On entry, a pointer to a null-terminated string that is the variable's name.\r
On return, points to the next variable's null-terminated name string.\r
- @param VariableGuid On entry, a pointer to an UEFI _GUID that is the variable's GUID. \r
+ @param VendorGuid On entry, a pointer to an EFI_GUID that is the variable's GUID. \r
On return, a pointer to the next variable's GUID.\r
\r
@retval EFI_SUCCESS The variable was read successfully.\r