/**\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