}\r
\r
\r
-\r
BOOLEAN\r
IsValidVariableHeader (\r
IN VARIABLE_HEADER *Variable\r
\r
--*/\r
{\r
- if (Variable == NULL ||\r
- Variable->StartId != VARIABLE_DATA ||\r
- (sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize) > MAX_VARIABLE_SIZE\r
- ) {\r
+ if (Variable == NULL || Variable->StartId != VARIABLE_DATA) {\r
return FALSE;\r
}\r
\r
}\r
}\r
\r
-\r
UINT8 *\r
GetVariableDataPtr (\r
IN VARIABLE_HEADER *Variable\r
//\r
// Be careful about pad size for alignment\r
//\r
- return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize));\r
+ return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + NAMESIZE_OF_VARIABLE (Variable) + GET_PAD_SIZE (NAMESIZE_OF_VARIABLE (Variable)));\r
}\r
\r
\r
//\r
// Be careful about pad size for alignment\r
//\r
- return (VARIABLE_HEADER *) ((UINTN) GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));\r
+ return (VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) GetVariableDataPtr (Variable) + DATASIZE_OF_VARIABLE (Variable) + GET_PAD_SIZE (DATASIZE_OF_VARIABLE (Variable))));\r
}\r
\r
+VARIABLE_HEADER *\r
+GetStartPointer (\r
+ IN VARIABLE_STORE_HEADER *VarStoreHeader\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This code gets the pointer to the first variable memory pointer byte\r
+\r
+Arguments:\r
+\r
+ VarStoreHeader Pointer to the Variable Store Header.\r
+\r
+Returns:\r
+\r
+ VARIABLE_HEADER* Pointer to last unavailable Variable Header\r
+\r
+--*/\r
+{\r
+ //\r
+ // The end of variable store\r
+ //\r
+ return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);\r
+}\r
\r
VARIABLE_HEADER *\r
GetEndPointer (\r
//\r
// The end of variable store\r
//\r
- return (VARIABLE_HEADER *) ((UINTN) VarStoreHeader + VarStoreHeader->Size);\r
+ return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size);\r
}\r
\r
\r
//\r
// Start Pointers for the variable.\r
//\r
- Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);\r
-\r
+ Variable = GetStartPointer (VariableStoreHeader);\r
ValidBufferSize = sizeof (VARIABLE_STORE_HEADER);\r
\r
while (IsValidVariableHeader (Variable)) {\r
// Copy variable store header\r
//\r
CopyMem (CurrPtr, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));\r
- CurrPtr += sizeof (VARIABLE_STORE_HEADER);\r
+ CurrPtr = (UINT8 *) GetStartPointer (VariableStoreHeader);\r
\r
//\r
// Start Pointers for the variable.\r
//\r
- Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);\r
+ Variable = GetStartPointer (VariableStoreHeader);\r
\r
while (IsValidVariableHeader (Variable)) {\r
NextVariable = GetNextVariablePtr (Variable);\r
if (Entry->DataSize == 0) {\r
// Variable was deleted so return not found\r
return EFI_NOT_FOUND;\r
- } else if (Entry->DataSize != *DataSize) {\r
+ } else if (Entry->DataSize > *DataSize) {\r
// If the buffer is too small return correct size\r
*DataSize = Entry->DataSize;\r
return EFI_BUFFER_TOO_SMALL;\r
} else {\r
+ *DataSize = Entry->DataSize;\r
// Return the data\r
CopyMem (Data, Entry->Data, Entry->DataSize);\r
if (Attributes != NULL) {\r
VARIABLE_STORE_HEADER *VariableStoreHeader[2];\r
UINTN Index;\r
\r
- //\r
- // We aquire the lock at the entry of FindVariable as GetVariable, GetNextVariableName\r
- // SetVariable all call FindVariable at entry point. Please move "Aquire Lock" to\r
- // the correct places if this assumption does not hold TRUE anymore.\r
- //\r
- AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
-\r
//\r
// 0: Volatile, 1: Non-Volatile\r
+ // The index and attributes mapping must be kept in this order as RuntimeServiceGetNextVariableName\r
+ // make use of this mapping to implement search algorithme.\r
//\r
VariableStoreHeader[0] = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);\r
VariableStoreHeader[1] = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
// Start Pointers for the variable.\r
// Actual Data Pointer where data can be written.\r
//\r
- Variable[0] = (VARIABLE_HEADER *) (VariableStoreHeader[0] + 1);\r
- Variable[1] = (VARIABLE_HEADER *) (VariableStoreHeader[1] + 1);\r
+ Variable[0] = GetStartPointer (VariableStoreHeader[0]);\r
+ Variable[1] = GetStartPointer (VariableStoreHeader[1]);\r
\r
if (VariableName[0] != 0 && VendorGuid == NULL) {\r
return EFI_INVALID_PARAMETER;\r
// Find the variable by walk through volatile and then non-volatile variable store\r
//\r
for (Index = 0; Index < 2; Index++) {\r
- PtrTrack->StartPtr = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1);\r
+ PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[Index]);\r
PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]);\r
\r
while (IsValidVariableHeader (Variable[Index]) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) {\r
return EFI_SUCCESS;\r
} else {\r
if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {\r
- if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), Variable[Index]->NameSize)) {\r
+ ASSERT (NAMESIZE_OF_VARIABLE (Variable[Index]) != 0);\r
+ if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), NAMESIZE_OF_VARIABLE (Variable[Index]))) {\r
PtrTrack->CurrPtr = Variable[Index];\r
PtrTrack->Volatile = (BOOLEAN)(Index == 0);\r
return EFI_SUCCESS;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
//\r
// Find existing variable\r
//\r
if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_SUCCESS)){\r
// Hit in the Cache\r
UpdateVariableInfo (VariableName, VendorGuid, FALSE, TRUE, FALSE, FALSE, TRUE);\r
- return Status;\r
+ goto Done;\r
}\r
\r
Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
//\r
// Get data size\r
//\r
- VarDataSize = Variable.CurrPtr->DataSize;\r
+ VarDataSize = DATASIZE_OF_VARIABLE (Variable.CurrPtr);\r
+ ASSERT (VarDataSize != 0);\r
+\r
if (*DataSize >= VarDataSize) {\r
if (Data == NULL) {\r
Status = EFI_INVALID_PARAMETER;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
goto Done;\r
//\r
if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {\r
Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1));\r
- if (Variable.Volatile) {\r
- Variable.StartPtr = (VARIABLE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER)));\r
- Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));\r
+ if (!Variable.Volatile) {\r
+ Variable.StartPtr = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
+ Variable.EndPtr = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase));\r
} else {\r
Status = EFI_NOT_FOUND;\r
goto Done;\r
//\r
if (IsValidVariableHeader (Variable.CurrPtr) && Variable.CurrPtr->State == VAR_ADDED) {\r
if (!(EfiAtRuntime () && !(Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) {\r
- VarNameSize = Variable.CurrPtr->NameSize;\r
+ VarNameSize = NAMESIZE_OF_VARIABLE (Variable.CurrPtr);\r
+ ASSERT (VarNameSize != 0);\r
+\r
if (VarNameSize <= *VariableNameSize) {\r
CopyMem (\r
VariableName,\r
UINTN *NonVolatileOffset;\r
UINT32 Instance;\r
BOOLEAN Volatile;\r
-\r
- Reclaimed = FALSE;\r
- VolatileOffset = &mVariableModuleGlobal->VolatileLastVariableOffset;\r
- NonVolatileOffset = &mVariableModuleGlobal->NonVolatileLastVariableOffset;\r
- Instance = mVariableModuleGlobal->FvbInstance;\r
+ EFI_PHYSICAL_ADDRESS Point;\r
\r
//\r
// Check input parameters\r
if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {\r
return EFI_INVALID_PARAMETER;\r
}\r
+\r
//\r
// The size of the VariableName, including the Unicode Null in bytes plus\r
// the DataSize is limited to maximum size of MAX_HARDWARE_ERROR_VARIABLE_SIZE (32K)\r
return EFI_INVALID_PARAMETER;\r
} \r
} \r
+\r
+ AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
+ Reclaimed = FALSE;\r
+ Instance = mVariableModuleGlobal->FvbInstance;\r
+ VolatileOffset = &mVariableModuleGlobal->VolatileLastVariableOffset;\r
+\r
+ //\r
+ // Consider reentrant in MCA/INIT/NMI. It needs be reupdated;\r
+ //\r
+ if (1 < InterlockedIncrement (&mVariableModuleGlobal->VariableGlobal.ReentrantState)) {\r
+ Point = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;;\r
+ //\r
+ // Parse non-volatile variable data and get last variable offset\r
+ //\r
+ NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point);\r
+ while (IsValidVariableHeader (NextVariable)) {\r
+ NextVariable = GetNextVariablePtr (NextVariable);\r
+ }\r
+ mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) Point;\r
+ }\r
+\r
+ NonVolatileOffset = &mVariableModuleGlobal->NonVolatileLastVariableOffset;\r
+ \r
+\r
//\r
// Check whether the input variable is already existed\r
//\r
// If the variable is marked valid and the same data has been passed in\r
// then return to the caller immediately.\r
//\r
- if (Variable.CurrPtr->DataSize == DataSize &&\r
+ if (DATASIZE_OF_VARIABLE (Variable.CurrPtr) == DataSize &&\r
(CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize) == 0)) {\r
\r
UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE, FALSE, FALSE);\r
goto Done;\r
}\r
\r
- *NonVolatileOffset = *NonVolatileOffset + VarSize;\r
+ *NonVolatileOffset = HEADER_ALIGN (*NonVolatileOffset + VarSize);\r
\r
} else {\r
//\r
goto Done;\r
}\r
\r
- *VolatileOffset = *VolatileOffset + VarSize;\r
+ *VolatileOffset = HEADER_ALIGN (*VolatileOffset + VarSize);\r
}\r
//\r
// Mark the old variable as deleted\r
UpdateVariableCache (VariableName, VendorGuid, Attributes, DataSize, Data);\r
\r
Done:\r
+ InterlockedDecrement (&mVariableModuleGlobal->VariableGlobal.ReentrantState);\r
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
return Status;\r
}\r
\r
//\r
// Point to the starting address of the variables.\r
//\r
- Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);\r
+ Variable = GetStartPointer (VariableStoreHeader);\r
\r
//\r
// Now walk through the related variable store.\r
\r
\r
EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock, TPL_NOTIFY);\r
+ mVariableModuleGlobal->VariableGlobal.ReentrantState = 0;\r
\r
//\r
// Allocate memory for volatile variable store\r
// Variable Specific Data\r
//\r
mVariableModuleGlobal->VariableGlobal.VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore;\r
- mVariableModuleGlobal->VolatileLastVariableOffset = sizeof (VARIABLE_STORE_HEADER);\r
+ mVariableModuleGlobal->VolatileLastVariableOffset = (UINTN) GetStartPointer (VolatileVariableStore) - (UINTN) VolatileVariableStore;\r
\r
VolatileVariableStore->Signature = VARIABLE_STORE_SIGNATURE;\r
VolatileVariableStore->Size = VARIABLE_STORE_SIZE;\r
//\r
// Parse non-volatile variable data and get last variable offset\r
//\r
- NextVariable = (VARIABLE_HEADER *) (CurrPtr + sizeof (VARIABLE_STORE_HEADER));\r
+ NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *) CurrPtr);\r
Status = EFI_SUCCESS;\r
\r
while (IsValidVariableHeader (NextVariable)) {\r