-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\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
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- Variable.c\r
-\r
-Abstract:\r
+/** @file\r
+ EFI Runtime Variable services.\r
+ \r
+ Copyright (c) 2006 - 2007, Intel Corporation \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
+ http://opensource.org/licenses/bsd-license.php \r
\r
-Revision History\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
\r
---*/\r
+**/\r
\r
\r
#include "Variable.h"\r
-#include <Guid/FlashMapHob.h>\r
-#include <Guid/VariableInfo.h>\r
-#include <Guid/GlobalVariable.h>\r
\r
\r
-\r
-\r
-//\r
-// Don't use module globals after the SetVirtualAddress map is signaled\r
-//\r
-ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;\r
+VARIABLE_MODULE_GLOBAL mRuntimeData;\r
+VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal = &mRuntimeData;\r
+EFI_EVENT mVirtualAddressChangeEvent = NULL;\r
+EFI_HANDLE mHandle = NULL;\r
\r
\r
//\r
GLOBAL_REMOVE_IF_UNREFERENCED VARIABLE_INFO_ENTRY *gVariableInfo = NULL;\r
\r
\r
+/**\r
+ Routine used to track statistical information about variable usage. \r
+ The data is stored in the EFI system table so it can be accessed later.\r
+ VariableInfo.efi can dump out the table. Only Boot Services variable \r
+ accesses are tracked by this code. The PcdVariableCollectStatistics\r
+ build flag controls if this feature is enabled. \r
+\r
+ A read that hits in the cache will have Read and Cache true for \r
+ the transaction. Data is allocated by this routine, but never\r
+ freed.\r
+\r
+ @param[in] VariableName Name of the Variable to track\r
+ @param[in] VendorGuid Guid of the Variable to track\r
+ @param[in] Volatile TRUE if volatile FALSE if non-volatile\r
+ @param[in] Read TRUE if GetVariable() was called\r
+ @param[in] Write TRUE if SetVariable() was called\r
+ @param[in] Delete TRUE if deleted via SetVariable()\r
+ @param[in] Cache TRUE for a cache hit.\r
+\r
+**/\r
VOID\r
UpdateVariableInfo (\r
IN CHAR16 *VariableName,\r
}\r
\r
if (gVariableInfo == NULL) {\r
+ //\r
+ // on the first call allocate a entry and place a pointer to it in\r
+ // the EFI System Table\r
+ //\r
gVariableInfo = AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY));\r
+ ASSERT (gVariableInfo != NULL);\r
+\r
CopyGuid (&gVariableInfo->VendorGuid, VendorGuid);\r
gVariableInfo->Name = AllocatePool (StrLen (VariableName));\r
StrCpy (gVariableInfo->Name, VariableName);\r
}\r
\r
if (Entry->Next == NULL) {\r
+ //\r
+ // If the entry is not in the table add it.\r
+ // Next iteration of the loop will fill in the data\r
+ //\r
Entry->Next = AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY));\r
+ ASSERT (Entry->Next != NULL);\r
\r
CopyGuid (&Entry->Next->VendorGuid, VendorGuid);\r
Entry->Next->Name = AllocatePool (StrLen (VariableName));\r
\r
\r
\r
-STATIC\r
BOOLEAN\r
-EFIAPI\r
IsValidVariableHeader (\r
IN VARIABLE_HEADER *Variable\r
)\r
return TRUE;\r
}\r
\r
-STATIC\r
+\r
EFI_STATUS\r
-EFIAPI\r
UpdateVariableStore (\r
IN VARIABLE_GLOBAL *Global,\r
IN BOOLEAN Volatile,\r
// written\r
//\r
if (SetByIndex) {\r
- DataPtr += Global->NonVolatileVariableBase;\r
+ DataPtr += mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;\r
}\r
\r
if ((DataPtr + DataSize) >= ((EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) FwVolHeader + FwVolHeader->FvLength))) {\r
// Data Pointer should point to the actual Address where data is to be\r
// written\r
//\r
- VolatileBase = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);\r
+ VolatileBase = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);\r
if (SetByIndex) {\r
- DataPtr += Global->VolatileVariableBase;\r
+ DataPtr += mVariableModuleGlobal->VariableGlobal.VolatileVariableBase;\r
}\r
\r
if ((DataPtr + DataSize) >= ((UINTN) ((UINT8 *) VolatileBase + VolatileBase->Size))) {\r
return EFI_SUCCESS;\r
}\r
\r
-STATIC\r
+\r
VARIABLE_STORE_STATUS\r
-EFIAPI\r
GetVariableStoreStatus (\r
IN VARIABLE_STORE_HEADER *VarStoreHeader\r
)\r
}\r
}\r
\r
-STATIC\r
+\r
UINT8 *\r
-EFIAPI\r
GetVariableDataPtr (\r
IN VARIABLE_HEADER *Variable\r
)\r
return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize));\r
}\r
\r
-STATIC\r
+\r
VARIABLE_HEADER *\r
GetNextVariablePtr (\r
IN VARIABLE_HEADER *Variable\r
return (VARIABLE_HEADER *) ((UINTN) GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));\r
}\r
\r
-STATIC\r
+\r
VARIABLE_HEADER *\r
-EFIAPI\r
GetEndPointer (\r
IN VARIABLE_STORE_HEADER *VarStoreHeader\r
)\r
return (VARIABLE_HEADER *) ((UINTN) VarStoreHeader + VarStoreHeader->Size);\r
}\r
\r
-STATIC\r
+\r
EFI_STATUS\r
-EFIAPI\r
Reclaim (\r
IN EFI_PHYSICAL_ADDRESS VariableBase,\r
OUT UINTN *LastVariableOffset,\r
return Status;\r
}\r
\r
-typedef struct {\r
- EFI_GUID *Guid;\r
- CHAR16 *Name;\r
- UINT32 Attributes;\r
- UINTN DataSize;\r
- VOID *Data;\r
-} VARIABLE_CACHE_ENTRY;\r
\r
//\r
// The current Hii implementation accesses this variable a larg # of times on every boot.\r
}\r
};\r
\r
+\r
+/**\r
+ Update the Cache with Variable information. These are the same \r
+ arguments as the EFI Variable services.\r
+\r
+ @param[in] VariableName Name of variable\r
+ @param[in] VendorGuid Guid of variable\r
+ @param[in] Attribute Attribue of the variable\r
+ @param[in] DataSize Size of data. 0 means delete\r
+ @param[in] Data Variable data\r
+\r
+**/\r
VOID\r
UpdateVariableCache (\r
IN CHAR16 *VariableName,\r
IN EFI_GUID *VendorGuid,\r
- OUT UINT32 Attributes,\r
- IN OUT UINTN DataSize,\r
- OUT VOID *Data\r
+ IN UINT32 Attributes,\r
+ IN UINTN DataSize,\r
+ IN VOID *Data\r
)\r
{\r
VARIABLE_CACHE_ENTRY *Entry;\r
}\r
\r
\r
+/**\r
+ Search the cache to see if the variable is in the cache.\r
+\r
+ @param[in] VariableName Name of variable\r
+ @param[in] VendorGuid Guid of variable\r
+ @param[in] Attribute Attribue returned \r
+ @param[in] DataSize Size of data returned\r
+ @param[in] Data Variable data returned\r
+\r
+ @retval EFI_SUCCESS VariableGuid & VariableName data was returned.\r
+ @retval other Not found.\r
+\r
+**/\r
EFI_STATUS\r
FindVariableInCache (\r
IN CHAR16 *VariableName,\r
if (CompareGuid (VendorGuid, Entry->Guid)) {\r
if (StrCmp (VariableName, Entry->Name) == 0) {\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
+ // If the buffer is too small return correct size\r
*DataSize = Entry->DataSize;\r
return EFI_BUFFER_TOO_SMALL;\r
} else {\r
+ // Return the data\r
CopyMem (Data, Entry->Data, Entry->DataSize);\r
if (Attributes != NULL) {\r
*Attributes = Entry->Attributes;\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(&Global->VariableServicesLock);\r
+ AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
//\r
// 0: Volatile, 1: Non-Volatile\r
//\r
- VariableStoreHeader[0] = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);\r
- VariableStoreHeader[1] = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);\r
+ VariableStoreHeader[0] = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);\r
+ VariableStoreHeader[1] = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
\r
//\r
// Start Pointers for the variable.\r
}\r
\r
\r
-EFI_STATUS\r
-EFIAPI\r
-GetVariable (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- OUT UINT32 *Attributes OPTIONAL,\r
- IN OUT UINTN *DataSize,\r
- OUT VOID *Data,\r
- IN VARIABLE_GLOBAL *Global,\r
- IN UINT32 Instance\r
- )\r
+\r
/*++\r
\r
Routine Description:\r
\r
\r
--*/\r
+EFI_STATUS\r
+EFIAPI\r
+RuntimeServiceGetVariable (\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ OUT UINT32 *Attributes OPTIONAL,\r
+ IN OUT UINTN *DataSize,\r
+ OUT VOID *Data\r
+ )\r
{\r
+ EFI_STATUS Status;\r
VARIABLE_POINTER_TRACK Variable;\r
UINTN VarDataSize;\r
- EFI_STATUS Status;\r
\r
if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) {\r
return EFI_INVALID_PARAMETER;\r
return Status;\r
}\r
\r
- Status = FindVariable (VariableName, VendorGuid, &Variable, Global);\r
+ Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
goto Done;\r
}\r
}\r
\r
Done:\r
- ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);\r
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
return Status;\r
}\r
\r
-EFI_STATUS\r
-EFIAPI\r
-GetNextVariableName (\r
- IN OUT UINTN *VariableNameSize,\r
- IN OUT CHAR16 *VariableName,\r
- IN OUT EFI_GUID *VendorGuid,\r
- IN VARIABLE_GLOBAL *Global,\r
- IN UINT32 Instance\r
- )\r
+\r
+\r
/*++\r
\r
Routine Description:\r
EFI STATUS\r
\r
--*/\r
+EFI_STATUS\r
+EFIAPI\r
+RuntimeServiceGetNextVariableName (\r
+ IN OUT UINTN *VariableNameSize,\r
+ IN OUT CHAR16 *VariableName,\r
+ IN OUT EFI_GUID *VendorGuid\r
+ )\r
{\r
VARIABLE_POINTER_TRACK Variable;\r
UINTN VarNameSize;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Status = FindVariable (VariableName, VendorGuid, &Variable, Global);\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) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER)));\r
- Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));\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
} else {\r
Status = EFI_NOT_FOUND;\r
goto Done;\r
}\r
\r
Done:\r
- ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);\r
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
return Status;\r
}\r
\r
-EFI_STATUS\r
-EFIAPI\r
-SetVariable (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN UINT32 Attributes,\r
- IN UINTN DataSize,\r
- IN VOID *Data,\r
- IN VARIABLE_GLOBAL *Global,\r
- IN UINTN *VolatileOffset,\r
- IN UINTN *NonVolatileOffset,\r
- IN UINT32 Instance\r
- )\r
+\r
/*++\r
\r
Routine Description:\r
EFI_WRITE_PROTECTED - Variable is read-only\r
\r
--*/\r
+EFI_STATUS\r
+EFIAPI\r
+RuntimeServiceSetVariable (\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN UINT32 Attributes,\r
+ IN UINTN DataSize,\r
+ IN VOID *Data\r
+ )\r
{\r
VARIABLE_POINTER_TRACK Variable;\r
EFI_STATUS Status;\r
UINTN VarSize;\r
UINT8 State;\r
BOOLEAN Reclaimed;\r
+ UINTN *VolatileOffset;\r
+ UINTN *NonVolatileOffset;\r
+ UINT32 Instance;\r
\r
- Reclaimed = FALSE;\r
+ Reclaimed = FALSE;\r
+ VolatileOffset = &mVariableModuleGlobal->VolatileLastVariableOffset;\r
+ NonVolatileOffset = &mVariableModuleGlobal->NonVolatileLastVariableOffset;\r
+ Instance = mVariableModuleGlobal->FvbInstance;\r
\r
//\r
// Check input parameters\r
// Check whether the input variable is already existed\r
//\r
\r
- Status = FindVariable (VariableName, VendorGuid, &Variable, Global);\r
+ Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
\r
if (Status == EFI_SUCCESS && Variable.CurrPtr != NULL) {\r
//\r
State &= VAR_DELETED;\r
\r
Status = UpdateVariableStore (\r
- Global,\r
+ &mVariableModuleGlobal->VariableGlobal,\r
Variable.Volatile,\r
FALSE,\r
Instance,\r
State &= VAR_IN_DELETED_TRANSITION;\r
\r
Status = UpdateVariableStore (\r
- Global,\r
+ &mVariableModuleGlobal->VariableGlobal,\r
Variable.Volatile,\r
FALSE,\r
Instance,\r
// Tricky part: Use scratch data area at the end of volatile variable store\r
// as a temporary storage.\r
//\r
- NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase));\r
+ NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));\r
\r
SetMem (NextVariable, SCRATCH_SIZE, 0xff);\r
\r
Variable.Volatile = FALSE;\r
\r
if ((UINT32) (VarSize +*NonVolatileOffset) >\r
- ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size\r
+ ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase)))->Size\r
) {\r
if (EfiAtRuntime ()) {\r
Status = EFI_OUT_OF_RESOURCES;\r
//\r
// Perform garbage collection & reclaim operation\r
//\r
- Status = Reclaim (Global->NonVolatileVariableBase, NonVolatileOffset, FALSE);\r
+ Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, NonVolatileOffset, FALSE);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
// If still no enough space, return out of resources\r
//\r
if ((UINT32) (VarSize +*NonVolatileOffset) >\r
- ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size\r
+ ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase)))->Size\r
) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
// Step 1:\r
//\r
Status = UpdateVariableStore (\r
- Global,\r
+ &mVariableModuleGlobal->VariableGlobal,\r
FALSE,\r
TRUE,\r
Instance,\r
// Step 2:\r
//\r
Status = UpdateVariableStore (\r
- Global,\r
+ &mVariableModuleGlobal->VariableGlobal,\r
FALSE,\r
TRUE,\r
Instance,\r
//\r
NextVariable->State = VAR_ADDED;\r
Status = UpdateVariableStore (\r
- Global,\r
+ &mVariableModuleGlobal->VariableGlobal,\r
FALSE,\r
TRUE,\r
Instance,\r
Variable.Volatile = TRUE;\r
\r
if ((UINT32) (VarSize +*VolatileOffset) >\r
- ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size) {\r
+ ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size) {\r
//\r
// Perform garbage collection & reclaim operation\r
//\r
- Status = Reclaim (Global->VolatileVariableBase, VolatileOffset, TRUE);\r
+ Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase, VolatileOffset, TRUE);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
// If still no enough space, return out of resources\r
//\r
if ((UINT32) (VarSize +*VolatileOffset) >\r
- ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size\r
+ ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size\r
) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
\r
NextVariable->State = VAR_ADDED;\r
Status = UpdateVariableStore (\r
- Global,\r
+ &mVariableModuleGlobal->VariableGlobal,\r
TRUE,\r
TRUE,\r
Instance,\r
State &= VAR_DELETED;\r
\r
Status = UpdateVariableStore (\r
- Global,\r
+ &mVariableModuleGlobal->VariableGlobal,\r
Variable.Volatile,\r
FALSE,\r
Instance,\r
UpdateVariableCache (VariableName, VendorGuid, Attributes, DataSize, Data);\r
\r
Done:\r
- ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);\r
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
return Status;\r
}\r
\r
-EFI_STATUS\r
-EFIAPI\r
-QueryVariableInfo (\r
- IN UINT32 Attributes,\r
- OUT UINT64 *MaximumVariableStorageSize,\r
- OUT UINT64 *RemainingVariableStorageSize,\r
- OUT UINT64 *MaximumVariableSize,\r
- IN VARIABLE_GLOBAL *Global,\r
- IN UINT32 Instance\r
- )\r
+\r
/*++\r
\r
Routine Description:\r
EFI_UNSUPPORTED - The attribute is not supported on this platform.\r
\r
--*/\r
+EFI_STATUS\r
+EFIAPI\r
+RuntimeServiceQueryVariableInfo (\r
+ IN UINT32 Attributes,\r
+ OUT UINT64 *MaximumVariableStorageSize,\r
+ OUT UINT64 *RemainingVariableStorageSize,\r
+ OUT UINT64 *MaximumVariableSize\r
+ )\r
{\r
VARIABLE_HEADER *Variable;\r
VARIABLE_HEADER *NextVariable;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- AcquireLockOnlyAtBootTime(&Global->VariableServicesLock);\r
+ AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {\r
//\r
// Query is Volatile related.\r
//\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase);\r
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);\r
} else {\r
//\r
// Query is Non-Volatile related.\r
//\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase);\r
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
}\r
\r
//\r
*MaximumVariableSize = *RemainingVariableStorageSize - sizeof (VARIABLE_HEADER);\r
}\r
\r
- ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock);\r
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
return EFI_SUCCESS;\r
}\r
\r
EFI_STATUS\r
-EFIAPI\r
VariableCommonInitialize (\r
IN EFI_HANDLE ImageHandle,\r
IN EFI_SYSTEM_TABLE *SystemTable\r
EFI_PHYSICAL_ADDRESS FvVolHdr;\r
UINT64 TempVariableStoreHeader;\r
EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r
- EFI_FLASH_SUBAREA_ENTRY VariableStoreEntry;\r
UINT64 BaseAddress;\r
UINT64 Length;\r
UINTN Index;\r
UINT8 Data;\r
+ UINT64 VariableStoreBase;\r
+ UINT64 VariableStoreLength;\r
\r
- mVariableModuleGlobal = AllocateRuntimePool (sizeof (ESAL_VARIABLE_GLOBAL));\r
- if (mVariableModuleGlobal == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
\r
- EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal[Physical].VariableServicesLock, TPL_NOTIFY);\r
+ EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock, TPL_NOTIFY);\r
\r
//\r
// Allocate memory for volatile variable store\r
//\r
// Variable Specific Data\r
//\r
- mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore;\r
+ mVariableModuleGlobal->VariableGlobal.VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore;\r
mVariableModuleGlobal->VolatileLastVariableOffset = sizeof (VARIABLE_STORE_HEADER);\r
\r
VolatileVariableStore->Signature = VARIABLE_STORE_SIGNATURE;\r
//\r
\r
TempVariableStoreHeader = (UINT64) PcdGet32 (PcdFlashNvStorageVariableBase);\r
- VariableStoreEntry.Base = TempVariableStoreHeader + \\r
+ VariableStoreBase = TempVariableStoreHeader + \\r
(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (TempVariableStoreHeader)) -> HeaderLength);\r
- VariableStoreEntry.Length = (UINT64) PcdGet32 (PcdFlashNvStorageVariableSize) - \\r
+ VariableStoreLength = (UINT64) PcdGet32 (PcdFlashNvStorageVariableSize) - \\r
(((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (TempVariableStoreHeader)) -> HeaderLength);\r
//\r
// Mark the variable storage region of the FLASH as RUNTIME\r
//\r
- BaseAddress = VariableStoreEntry.Base & (~EFI_PAGE_MASK);\r
- Length = VariableStoreEntry.Length + (VariableStoreEntry.Base - BaseAddress);\r
+ BaseAddress = VariableStoreBase & (~EFI_PAGE_MASK);\r
+ Length = VariableStoreLength + (VariableStoreBase - BaseAddress);\r
Length = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK);\r
\r
Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor);\r
//\r
// Get address of non volatile variable store base\r
//\r
- mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase = VariableStoreEntry.Base;\r
+ mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;\r
\r
//\r
// Check Integrity\r
// Find the Correct Instance of the FV Block Service.\r
//\r
Instance = 0;\r
- CurrPtr = (CHAR8 *) ((UINTN) mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase);\r
+ CurrPtr = (CHAR8 *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
while (EfiFvbGetPhysicalAddress (Instance, &FvVolHdr) == EFI_SUCCESS) {\r
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvVolHdr);\r
if (CurrPtr >= (CHAR8 *) FwVolHeader && CurrPtr < (((CHAR8 *) FwVolHeader) + FwVolHeader->FvLength)) {\r
if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {\r
if (~VariableStoreHeader->Size == 0) {\r
Status = UpdateVariableStore (\r
- &mVariableModuleGlobal->VariableGlobal[Physical],\r
+ &mVariableModuleGlobal->VariableGlobal,\r
FALSE,\r
FALSE,\r
mVariableModuleGlobal->FvbInstance,\r
(UINTN) &VariableStoreHeader->Size,\r
sizeof (UINT32),\r
- (UINT8 *) &VariableStoreEntry.Length\r
+ (UINT8 *) &VariableStoreLength\r
);\r
//\r
// As Variables are stored in NV storage, which are slow devices,such as flash.\r
// We can assume all Read/Write is OK if we can set Variable store size successfully.\r
// If write fail, we will assert here\r
//\r
- ASSERT(VariableStoreHeader->Size == VariableStoreEntry.Length);\r
+ ASSERT(VariableStoreHeader->Size == VariableStoreLength);\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
}\r
\r
- mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) CurrPtr);\r
+ mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) CurrPtr);\r
//\r
// Parse non-volatile variable data and get last variable offset\r
//\r
//\r
if ((((VARIABLE_STORE_HEADER *)((UINTN) CurrPtr))->Size - mVariableModuleGlobal->NonVolatileLastVariableOffset) < VARIABLE_RECLAIM_THRESHOLD) {\r
Status = Reclaim (\r
- mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase,\r
+ mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,\r
&mVariableModuleGlobal->NonVolatileLastVariableOffset,\r
FALSE\r
);\r
// Check if the free area is really free.\r
//\r
for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < VariableStoreHeader->Size; Index++) {\r
- Data = ((UINT8 *) (UINTN) mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase)[Index];\r
+ Data = ((UINT8 *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase)[Index];\r
if (Data != 0xff) {\r
//\r
// There must be something wrong in variable store, do reclaim operation.\r
//\r
Status = Reclaim (\r
- mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase,\r
+ mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,\r
&mVariableModuleGlobal->NonVolatileLastVariableOffset,\r
FALSE\r
);\r
\r
return Status;\r
}\r
+\r
+\r
+\r
+\r
+VOID\r
+EFIAPI\r
+VariableClassAddressChangeEvent (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EfiConvertPointer (\r
+ 0x0,\r
+ (VOID **) &mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase\r
+ );\r
+ EfiConvertPointer (\r
+ 0x0,\r
+ (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase\r
+ );\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);\r
+}\r
+\r
+\r
+/**\r
+ Variable Driver main entry point. The Variable driver places the 4 EFI\r
+ runtime services in the EFI System Table and installs arch protocols \r
+ for variable read and write services being availible. \r
+\r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
+ @param[in] SystemTable A pointer to the EFI System Table.\r
+ \r
+ @retval EFI_SUCCESS The entry point is executed successfully.\r
+ @retval other Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VariableServiceInitialize (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = VariableCommonInitialize (ImageHandle, SystemTable);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ SystemTable->RuntimeServices->GetVariable = RuntimeServiceGetVariable;\r
+ SystemTable->RuntimeServices->GetNextVariableName = RuntimeServiceGetNextVariableName;\r
+ SystemTable->RuntimeServices->SetVariable = RuntimeServiceSetVariable;\r
+ SystemTable->RuntimeServices->QueryVariableInfo = RuntimeServiceQueryVariableInfo;\r
+\r
+ //\r
+ // Now install the Variable Runtime Architectural Protocol on a new handle\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mHandle,\r
+ &gEfiVariableArchProtocolGuid, NULL,\r
+ &gEfiVariableWriteArchProtocolGuid, NULL,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = gBS->CreateEvent (\r
+ EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\r
+ TPL_NOTIFY,\r
+ VariableClassAddressChangeEvent,\r
+ NULL,\r
+ &mVirtualAddressChangeEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r