/** @file\r
\r
- Implement all four UEFI Runtime Variable services for the nonvolatile\r
- and volatile storage space and install variable architecture protocol.\r
+ The common variable operation routines shared by DXE_RINTIME variable \r
+ module and DXE_SMM variable module.\r
\r
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials \r
#include "Variable.h"\r
\r
VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;\r
-EFI_EVENT mVirtualAddressChangeEvent = NULL;\r
-EFI_HANDLE mHandle = NULL;\r
\r
///\r
-/// The current Hii implementation accesses this variable many times on every boot.\r
-/// Other common variables are only accessed once. This is why this cache algorithm\r
-/// only targets a single variable. Probably to get an performance improvement out of\r
-/// a Cache you would need a cache that improves the search performance for a variable.\r
+/// Define a memory cache that improves the search performance for a variable.\r
///\r
-VARIABLE_CACHE_ENTRY mVariableCache[] = {\r
- {\r
- &gEfiGlobalVariableGuid,\r
- L"Lang",\r
- 0x00000000,\r
- 0x00,\r
- NULL\r
- },\r
- {\r
- &gEfiGlobalVariableGuid,\r
- L"PlatformLang",\r
- 0x00000000,\r
- 0x00,\r
- NULL\r
- }\r
-};\r
-\r
-VARIABLE_INFO_ENTRY *gVariableInfo = NULL;\r
-EFI_EVENT mFvbRegistration = NULL;\r
-\r
-/**\r
- Update the variable region with Variable information. These are the same \r
- arguments as the EFI Variable services.\r
-\r
- @param[in] VariableName Name of variable\r
-\r
- @param[in] VendorGuid Guid of variable\r
-\r
- @param[in] Data Variable data\r
-\r
- @param[in] DataSize Size of data. 0 means delete\r
-\r
- @param[in] Attributes Attribues of the variable\r
-\r
- @param[in] Variable The variable information which is used to keep track of variable usage.\r
-\r
- @retval EFI_SUCCESS The update operation is success.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Variable region is full, can not write other data into this region.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UpdateVariable (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes OPTIONAL,\r
- IN VARIABLE_POINTER_TRACK *Variable\r
- );\r
+VARIABLE_STORE_HEADER *mNvVariableCache = NULL;\r
\r
-/**\r
- Acquires lock only at boot time. Simply returns at runtime.\r
-\r
- This is a temperary function which will be removed when\r
- EfiAcquireLock() in UefiLib can handle the call in UEFI\r
- Runtimer driver in RT phase.\r
- It calls EfiAcquireLock() at boot time, and simply returns\r
- at runtime.\r
-\r
- @param Lock A pointer to the lock to acquire\r
-\r
-**/\r
-VOID\r
-AcquireLockOnlyAtBootTime (\r
- IN EFI_LOCK *Lock\r
- )\r
-{\r
- if (!EfiAtRuntime ()) {\r
- EfiAcquireLock (Lock);\r
- }\r
-}\r
-\r
-/**\r
- Releases lock only at boot time. Simply returns at runtime.\r
-\r
- This is a temperary function which will be removed when\r
- EfiReleaseLock() in UefiLib can handle the call in UEFI\r
- Runtimer driver in RT phase.\r
- It calls EfiReleaseLock() at boot time, and simply returns\r
- at runtime.\r
-\r
- @param Lock A pointer to the lock to release\r
-\r
-**/\r
-VOID\r
-ReleaseLockOnlyAtBootTime (\r
- IN EFI_LOCK *Lock\r
- )\r
-{\r
- if (!EfiAtRuntime ()) {\r
- EfiReleaseLock (Lock);\r
- }\r
-}\r
+///\r
+/// The memory entry used for variable statistics data.\r
+///\r
+VARIABLE_INFO_ENTRY *gVariableInfo = NULL;\r
\r
\r
/**\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] 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
\r
if (FeaturePcdGet (PcdVariableCollectStatistics)) {\r
\r
- if (EfiAtRuntime ()) {\r
- // Don't collect statistics at runtime\r
+ if (AtRuntime ()) {\r
+ // Don't collect statistics at runtime.\r
return;\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
+ // 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
ASSERT (gVariableInfo->Name != NULL);\r
StrCpy (gVariableInfo->Name, VariableName);\r
gVariableInfo->Volatile = Volatile;\r
-\r
- gBS->InstallConfigurationTable (&gEfiVariableGuid, gVariableInfo);\r
}\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
+ // 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
This function writes data to the FWH at the correct LBA even if the LBAs\r
are fragmented.\r
\r
- @param Global Pointer to VARAIBLE_GLOBAL structure\r
- @param Volatile Point out the Variable is Volatile or Non-Volatile\r
- @param SetByIndex TRUE if target pointer is given as index\r
- FALSE if target pointer is absolute\r
- @param Fvb Pointer to the writable FVB protocol\r
+ @param Global Pointer to VARAIBLE_GLOBAL structure.\r
+ @param Volatile Point out the Variable is Volatile or Non-Volatile.\r
+ @param SetByIndex TRUE if target pointer is given as index.\r
+ FALSE if target pointer is absolute.\r
+ @param Fvb Pointer to the writable FVB protocol.\r
@param DataPtrIndex Pointer to the Data from the end of VARIABLE_STORE_HEADER\r
- structure\r
- @param DataSize Size of data to be written\r
- @param Buffer Pointer to the buffer from which data is written\r
+ structure.\r
+ @param DataSize Size of data to be written.\r
+ @param Buffer Pointer to the buffer from which data is written.\r
\r
- @retval EFI_INVALID_PARAMETER Parameters not valid\r
- @retval EFI_SUCCESS Variable store successfully updated\r
+ @retval EFI_INVALID_PARAMETER Parameters not valid.\r
+ @retval EFI_SUCCESS Variable store successfully updated.\r
\r
**/\r
EFI_STATUS\r
DataPtr = DataPtrIndex;\r
\r
//\r
- // Check if the Data is Volatile\r
+ // Check if the Data is Volatile.\r
//\r
if (!Volatile) {\r
Status = Fvb->GetPhysicalAddress(Fvb, &FvVolHdr);\r
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvVolHdr);\r
//\r
// Data Pointer should point to the actual Address where data is to be\r
- // written\r
+ // written.\r
//\r
if (SetByIndex) {\r
DataPtr += mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;\r
} else {\r
//\r
// Data Pointer should point to the actual Address where data is to be\r
- // written\r
+ // written.\r
//\r
VolatileBase = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);\r
if (SetByIndex) {\r
}\r
\r
//\r
- // If we are here we are dealing with Non-Volatile Variables\r
+ // If we are here we are dealing with Non-Volatile Variables.\r
//\r
LinearOffset = (UINTN) FwVolHeader;\r
CurrWritePtr = (UINTN) DataPtr;\r
\r
@param VarStoreHeader Pointer to the Variable Store Header.\r
\r
- @retval EfiRaw Variable store status is raw\r
- @retval EfiValid Variable store status is valid\r
- @retval EfiInvalid Variable store status is invalid\r
+ @retval EfiRaw Variable store status is raw.\r
+ @retval EfiValid Variable store status is valid.\r
+ @retval EfiInvalid Variable store status is invalid.\r
\r
**/\r
VARIABLE_STORE_STATUS\r
\r
This code gets the size of name of variable.\r
\r
- @param Variable Pointer to the Variable Header\r
+ @param Variable Pointer to the Variable Header.\r
\r
- @return UINTN Size of variable in bytes\r
+ @return UINTN Size of variable in bytes.\r
\r
**/\r
UINTN\r
\r
This code gets the size of variable data.\r
\r
- @param Variable Pointer to the Variable Header\r
+ @param Variable Pointer to the Variable Header.\r
\r
- @return Size of variable in bytes\r
+ @return Size of variable in bytes.\r
\r
**/\r
UINTN\r
\r
This code gets the pointer to the variable name.\r
\r
- @param Variable Pointer to the Variable Header\r
+ @param Variable Pointer to the Variable Header.\r
\r
- @return Pointer to Variable Name which is Unicode encoding\r
+ @return Pointer to Variable Name which is Unicode encoding.\r
\r
**/\r
CHAR16 *\r
\r
This code gets the pointer to the variable data.\r
\r
- @param Variable Pointer to the Variable Header\r
+ @param Variable Pointer to the Variable Header.\r
\r
- @return Pointer to Variable Data\r
+ @return Pointer to Variable Data.\r
\r
**/\r
UINT8 *\r
UINTN Value;\r
\r
//\r
- // Be careful about pad size for alignment\r
+ // Be careful about pad size for alignment.\r
//\r
Value = (UINTN) GetVariableNamePtr (Variable);\r
Value += NameSizeOfVariable (Variable);\r
\r
This code gets the pointer to the next variable header.\r
\r
- @param Variable Pointer to the Variable Header\r
+ @param Variable Pointer to the Variable Header.\r
\r
- @return Pointer to next variable header\r
+ @return Pointer to next variable header.\r
\r
**/\r
VARIABLE_HEADER *\r
Value += GET_PAD_SIZE (DataSizeOfVariable (Variable));\r
\r
//\r
- // Be careful about pad size for alignment\r
+ // Be careful about pad size for alignment.\r
//\r
return (VARIABLE_HEADER *) HEADER_ALIGN (Value);\r
}\r
\r
@param VarStoreHeader Pointer to the Variable Store Header.\r
\r
- @return Pointer to the first variable header\r
+ @return Pointer to the first variable header.\r
\r
**/\r
VARIABLE_HEADER *\r
)\r
{\r
//\r
- // The end of variable store\r
+ // The end of variable store.\r
//\r
return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1);\r
}\r
This function gets pointer to the end of the variable storage\r
area, according to the input variable store header.\r
\r
- @param VarStoreHeader Pointer to the Variable Store Header\r
+ @param VarStoreHeader Pointer to the Variable Store Header.\r
\r
- @return Pointer to the end of the variable storage area \r
+ @return Pointer to the end of the variable storage area. \r
\r
**/\r
VARIABLE_HEADER *\r
\r
Variable store garbage collection and reclaim operation.\r
\r
- @param VariableBase Base address of variable store\r
- @param LastVariableOffset Offset of last variable\r
- @param IsVolatile The variable store is volatile or not,\r
- if it is non-volatile, need FTW\r
- @param UpdatingVariable Pointer to updateing variable.\r
+ @param VariableBase Base address of variable store.\r
+ @param LastVariableOffset Offset of last variable.\r
+ @param IsVolatile The variable store is volatile or not;\r
+ if it is non-volatile, need FTW.\r
+ @param UpdatingVariable Pointer to updating variable.\r
\r
@return EFI_OUT_OF_RESOURCES\r
@return EFI_SUCCESS\r
\r
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);\r
//\r
- // recaluate the total size of Common/HwErr type variables in non-volatile area.\r
+ // Recalculate the total size of Common/HwErr type variables in non-volatile area.\r
//\r
if (!IsVolatile) {\r
mVariableModuleGlobal->CommonVariableTotalSize = 0;\r
SetMem (ValidBuffer, MaximumBufferSize, 0xff);\r
\r
//\r
- // Copy variable store header\r
+ // Copy variable store header.\r
//\r
CopyMem (ValidBuffer, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));\r
CurrPtr = (UINT8 *) GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer);\r
\r
//\r
- // Reinstall all ADDED variables as long as they are not identical to Updating Variable\r
+ // Reinstall all ADDED variables as long as they are not identical to Updating Variable.\r
// \r
Variable = GetStartPointer (VariableStoreHeader);\r
while (IsValidVariableHeader (Variable)) {\r
}\r
\r
//\r
- // Reinstall the variable being updated if it is not NULL\r
+ // Reinstall the variable being updated if it is not NULL.\r
//\r
if (UpdatingVariable != NULL) {\r
VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - (UINTN)UpdatingVariable;\r
}\r
\r
//\r
- // Reinstall all in delete transition variables\r
+ // Reinstall all in delete transition variables.\r
// \r
Variable = GetStartPointer (VariableStoreHeader);\r
while (IsValidVariableHeader (Variable)) {\r
}\r
if (!FoundAdded) {\r
//\r
- // Promote VAR_IN_DELETED_TRANSITION to VAR_ADDED\r
+ // Promote VAR_IN_DELETED_TRANSITION to VAR_ADDED.\r
//\r
VariableSize = (UINTN) NextVariable - (UINTN) Variable;\r
CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);\r
\r
if (IsVolatile) {\r
//\r
- // If volatile variable store, just copy valid buffer\r
+ // If volatile variable store, just copy valid buffer.\r
//\r
SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);\r
CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - (UINT8 *) ValidBuffer));\r
- Status = EFI_SUCCESS;\r
+ Status = EFI_SUCCESS;\r
} else {\r
//\r
// If non-volatile variable store, perform FTW here.\r
ValidBuffer,\r
(UINTN) (CurrPtr - (UINT8 *) ValidBuffer)\r
);\r
+ CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableBase, VariableStoreHeader->Size);\r
}\r
if (!EFI_ERROR (Status)) {\r
*LastVariableOffset = (UINTN) (CurrPtr - (UINT8 *) ValidBuffer);\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] Attributes Attribues 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
- IN UINT32 Attributes,\r
- IN UINTN DataSize,\r
- IN VOID *Data\r
- )\r
-{\r
- VARIABLE_CACHE_ENTRY *Entry;\r
- UINTN Index;\r
-\r
- if (EfiAtRuntime ()) {\r
- //\r
- // Don't use the cache at runtime\r
- // \r
- return;\r
- }\r
-\r
- for (Index = 0, Entry = mVariableCache; Index < sizeof (mVariableCache)/sizeof (VARIABLE_CACHE_ENTRY); Index++, Entry++) {\r
- if (CompareGuid (VendorGuid, Entry->Guid)) {\r
- if (StrCmp (VariableName, Entry->Name) == 0) { \r
- Entry->Attributes = Attributes;\r
- if (DataSize == 0) {\r
- //\r
- // Delete Case\r
- //\r
- if (Entry->DataSize != 0) {\r
- FreePool (Entry->Data);\r
- }\r
- Entry->DataSize = DataSize;\r
- } else if (DataSize == Entry->DataSize) {\r
- CopyMem (Entry->Data, Data, DataSize);\r
- } else {\r
- Entry->Data = AllocatePool (DataSize);\r
- ASSERT (Entry->Data != NULL);\r
-\r
- Entry->DataSize = DataSize;\r
- CopyMem (Entry->Data, Data, DataSize);\r
- }\r
- }\r
- }\r
- }\r
-}\r
-\r
-\r
-/**\r
- Search the cache to check if the variable is in it.\r
-\r
- This function searches the variable cache. If the variable to find exists, return its data\r
- and attributes.\r
-\r
- @param VariableName A Null-terminated Unicode string that is the name of the vendor's\r
- variable. Each VariableName is unique for each \r
- VendorGuid.\r
- @param VendorGuid A unique identifier for the vendor\r
- @param Attributes Pointer to the attributes bitmask of the variable for output.\r
- @param DataSize On input, size of the buffer of Data.\r
- On output, size of the variable's data.\r
- @param Data Pointer to the data buffer for output.\r
-\r
- @retval EFI_SUCCESS VariableGuid & VariableName data was returned.\r
- @retval EFI_NOT_FOUND No matching variable found in cache.\r
- @retval EFI_BUFFER_TOO_SMALL *DataSize is smaller than size of the variable's data to return.\r
-\r
-**/\r
-EFI_STATUS\r
-FindVariableInCache (\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
- VARIABLE_CACHE_ENTRY *Entry;\r
- UINTN Index;\r
-\r
- if (EfiAtRuntime ()) {\r
- // Don't use the cache at runtime\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- for (Index = 0, Entry = mVariableCache; Index < sizeof (mVariableCache)/sizeof (VARIABLE_CACHE_ENTRY); Index++, Entry++) {\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
- *DataSize = Entry->DataSize;\r
- // Return the data\r
- CopyMem (Data, Entry->Data, Entry->DataSize);\r
- if (Attributes != NULL) {\r
- *Attributes = Entry->Attributes;\r
- }\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- }\r
- }\r
- \r
- return EFI_NOT_FOUND;\r
-}\r
-\r
/**\r
Finds variable in storage blocks of volatile and non-volatile storage areas.\r
\r
qualified variable without comparing VariableName and VendorGuid.\r
Otherwise, VariableName and VendorGuid are compared.\r
\r
- @param VariableName Name of the variable to be found\r
+ @param VariableName Name of the variable to be found.\r
@param VendorGuid Vendor GUID to be found.\r
@param PtrTrack VARIABLE_POINTER_TRACK structure for output,\r
including the range searched and the target position.\r
NV variable storage area, and a lock.\r
\r
@retval EFI_INVALID_PARAMETER If VariableName is not an empty string, while\r
- VendorGuid is NULL\r
- @retval EFI_SUCCESS Variable successfully found\r
+ VendorGuid is NULL.\r
+ @retval EFI_SUCCESS Variable successfully found.\r
@retval EFI_NOT_FOUND Variable not found\r
\r
**/\r
VOID *Point;\r
\r
//\r
- // 0: Volatile, 1: Non-Volatile\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
+ // make use of this mapping to implement search algorithm.\r
//\r
VariableStoreHeader[0] = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);\r
- VariableStoreHeader[1] = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
+ VariableStoreHeader[1] = mNvVariableCache;\r
\r
//\r
// Start Pointers for the variable.\r
}\r
\r
//\r
- // Find the variable by walk through volatile and then non-volatile variable store\r
+ // Find the variable by walk through volatile and then non-volatile variable store.\r
//\r
InDeletedVariable = NULL;\r
InDeletedStorageIndex = 0;\r
if (Variable[Index]->State == VAR_ADDED || \r
Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)\r
) {\r
- if (!EfiAtRuntime () || ((Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {\r
+ if (!AtRuntime () || ((Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {\r
if (VariableName[0] == 0) {\r
if (Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
InDeletedVariable = Variable[Index];\r
@param Lang Configured language.\r
@param Iso639Language A bool value to signify if the handler is operated on ISO639 or RFC4646.\r
\r
- @retval the index of language in the language codes.\r
+ @retval The index of language in the language codes.\r
\r
**/\r
UINTN\r
/**\r
Get language string from supported language codes according to index.\r
\r
- This code is used to get corresponding language string in supported language codes. It can handle\r
+ This code is used to get corresponding language strings in supported language codes. It can handle\r
RFC4646 and ISO639 language tags.\r
In ISO639 language tags, take 3-characters as a delimitation. Find language string according to the index.\r
In RFC4646 language tags, take semicolon as a delimitation. Find language string according to the index.\r
The return value is "fr".\r
\r
@param SupportedLang Platform supported language codes.\r
- @param Index the index in supported language codes.\r
+ @param Index The index in supported language codes.\r
@param Iso639Language A bool value to signify if the handler is operated on ISO639 or RFC4646.\r
\r
- @retval the language string in the language codes.\r
+ @retval The language string in the language codes.\r
\r
**/\r
CHAR8 *\r
Supported = SupportedLang;\r
if (Iso639Language) {\r
//\r
- // according to the index of Lang string in SupportedLang string to get the language.\r
- // As this code will be invoked in RUNTIME, therefore there is not memory allocate/free operation.\r
+ // According to the index of Lang string in SupportedLang string to get the language.\r
+ // This code will be invoked in RUNTIME, therefore there is not a memory allocate/free operation.\r
// In driver entry, it pre-allocates a runtime attribute memory to accommodate this string.\r
//\r
CompareLength = ISO_639_2_ENTRY_SIZE;\r
mVariableModuleGlobal->Lang[CompareLength] = '\0';\r
return CopyMem (mVariableModuleGlobal->Lang, SupportedLang + Index * CompareLength, CompareLength);\r
-\r
+ \r
} else {\r
while (TRUE) {\r
//\r
- // take semicolon as delimitation, sequentially traverse supported language codes.\r
+ // Take semicolon as delimitation, sequentially traverse supported language codes.\r
//\r
for (CompareLength = 0; *Supported != ';' && *Supported != '\0'; CompareLength++) {\r
Supported++;\r
}\r
if (SubIndex == Index) {\r
//\r
- // according to the index of Lang string in SupportedLang string to get the language.\r
+ // According to the index of Lang string in SupportedLang string to get the language.\r
// As this code will be invoked in RUNTIME, therefore there is not memory allocate/free operation.\r
// In driver entry, it pre-allocates a runtime attribute memory to accommodate this string.\r
//\r
return CopyMem (mVariableModuleGlobal->PlatformLang, Supported - CompareLength, CompareLength);\r
}\r
SubIndex++;\r
- \r
+\r
//\r
// Skip ';' characters in Supported\r
//\r
\r
**/\r
CHAR8 *\r
+EFIAPI\r
VariableGetBestLanguage (\r
IN CONST CHAR8 *SupportedLanguages, \r
IN BOOLEAN Iso639Language,\r
According to UEFI spec, PlatformLangCodes/LangCodes are only set once in firmware initialization,\r
and are read-only. Therefore, in variable driver, only store the original value for other use.\r
\r
- @param[in] VariableName Name of variable\r
+ @param[in] VariableName Name of variable.\r
\r
- @param[in] Data Variable data\r
+ @param[in] Data Variable data.\r
\r
- @param[in] DataSize Size of data. 0 means delete\r
+ @param[in] DataSize Size of data. 0 means delete.\r
\r
**/\r
VOID\r
//\r
// PlatformLangCodes is a volatile variable, so it can not be updated at runtime.\r
//\r
- if (EfiAtRuntime ()) {\r
+ if (AtRuntime ()) {\r
return;\r
}\r
\r
//\r
// LangCodes is a volatile variable, so it can not be updated at runtime.\r
//\r
- if (EfiAtRuntime ()) {\r
+ if (AtRuntime ()) {\r
return;\r
}\r
\r
//\r
FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *)mVariableModuleGlobal);\r
\r
- Status = UpdateVariable (L"Lang", &gEfiGlobalVariableGuid, BestLang, ISO_639_2_ENTRY_SIZE + 1, Attributes, &Variable);\r
+ Status = UpdateVariable (L"Lang", &gEfiGlobalVariableGuid, BestLang,\r
+ ISO_639_2_ENTRY_SIZE + 1, Attributes, &Variable);\r
\r
DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a\n", BestPlatformLang, BestLang));\r
\r
Update the variable region with Variable information. These are the same \r
arguments as the EFI Variable services.\r
\r
- @param[in] VariableName Name of variable\r
-\r
- @param[in] VendorGuid Guid of variable\r
-\r
- @param[in] Data Variable data\r
-\r
- @param[in] DataSize Size of data. 0 means delete\r
-\r
- @param[in] Attributes Attribues of the variable\r
-\r
- @param[in] Variable The variable information which is used to keep track of variable usage.\r
-\r
+ @param[in] VariableName Name of variable.\r
+ @param[in] VendorGuid Guid of variable.\r
+ @param[in] Data Variable data.\r
+ @param[in] DataSize Size of data. 0 means delete.\r
+ @param[in] Attributes Attribues of the variable.\r
+ @param[in] CacheVariable The variable information which is used to keep track of variable usage.\r
+ \r
@retval EFI_SUCCESS The update operation is success.\r
-\r
@retval EFI_OUT_OF_RESOURCES Variable region is full, can not write other data into this region.\r
\r
**/\r
EFI_STATUS\r
-EFIAPI\r
UpdateVariable (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *Data,\r
- IN UINTN DataSize,\r
- IN UINT32 Attributes OPTIONAL,\r
- IN VARIABLE_POINTER_TRACK *Variable\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN VOID *Data,\r
+ IN UINTN DataSize,\r
+ IN UINT32 Attributes OPTIONAL,\r
+ IN VARIABLE_POINTER_TRACK *CacheVariable\r
)\r
{\r
EFI_STATUS Status;\r
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
UINT8 State;\r
BOOLEAN Reclaimed;\r
+ VARIABLE_POINTER_TRACK *Variable;\r
+ VARIABLE_POINTER_TRACK NvVariable;\r
+ VARIABLE_STORE_HEADER *VariableStoreHeader;\r
+ UINTN CacheOffset;\r
+\r
+ if ((mVariableModuleGlobal->FvbInstance == NULL) && ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0)) {\r
+ //\r
+ // The FVB protocol is not ready. Trying to update NV variable prior to the installation\r
+ // of EFI_VARIABLE_WRITE_ARCH_PROTOCOL.\r
+ //\r
+ return EFI_NOT_AVAILABLE_YET; \r
+ }\r
+\r
+ if ((CacheVariable->CurrPtr == NULL) || CacheVariable->Volatile) {\r
+ Variable = CacheVariable;\r
+ } else {\r
+ //\r
+ // Update/Delete existing NV variable.\r
+ // CacheVariable points to the variable in the memory copy of Flash area\r
+ // Now let Variable points to the same variable in Flash area.\r
+ //\r
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
+ Variable = &NvVariable; \r
+ Variable->StartPtr = GetStartPointer (VariableStoreHeader);\r
+ Variable->EndPtr = GetEndPointer (VariableStoreHeader);\r
+ Variable->CurrPtr = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->CurrPtr - (UINTN)CacheVariable->StartPtr));\r
+ Variable->Volatile = FALSE;\r
+ } \r
\r
- Fvb = mVariableModuleGlobal->FvbInstance;\r
- Reclaimed = FALSE;\r
+ Fvb = mVariableModuleGlobal->FvbInstance;\r
+ Reclaimed = FALSE;\r
\r
if (Variable->CurrPtr != NULL) {\r
//\r
- // Update/Delete existing variable\r
+ // Update/Delete existing variable.\r
//\r
- Volatile = Variable->Volatile;\r
- \r
- if (EfiAtRuntime ()) { \r
+ if (AtRuntime ()) { \r
//\r
- // If EfiAtRuntime and the variable is Volatile and Runtime Access, \r
+ // If AtRuntime and the variable is Volatile and Runtime Access, \r
// the volatile is ReadOnly, and SetVariable should be aborted and \r
// return EFI_WRITE_PROTECTED.\r
//\r
goto Done;\r
}\r
//\r
- // Only variable have NV attribute can be updated/deleted in Runtime\r
+ // Only variable that have NV attributes can be updated/deleted in Runtime.\r
//\r
if ((Variable->CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done; \r
}\r
}\r
+\r
//\r
// Setting a data variable with no access, or zero DataSize attributes\r
- // specified causes it to be deleted.\r
+ // causes it to be deleted.\r
//\r
if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) { \r
State = Variable->CurrPtr->State;\r
&State\r
); \r
if (!EFI_ERROR (Status)) {\r
- UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, FALSE, TRUE, FALSE);\r
- UpdateVariableCache (VariableName, VendorGuid, Attributes, DataSize, Data);\r
+ UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, FALSE, TRUE, FALSE);\r
+ if (!Variable->Volatile) {\r
+ CacheVariable->CurrPtr->State = State;\r
+ }\r
}\r
goto Done; \r
}\r
//\r
- // If the variable is marked valid and the same data has been passed in\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 (DataSizeOfVariable (Variable->CurrPtr) == DataSize &&\r
(CompareMem (Data, GetVariableDataPtr (Variable->CurrPtr), DataSize) == 0)) {\r
\r
- UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE, FALSE, FALSE);\r
+ UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, TRUE, FALSE, FALSE);\r
Status = EFI_SUCCESS;\r
goto Done;\r
} else if ((Variable->CurrPtr->State == VAR_ADDED) ||\r
(Variable->CurrPtr->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION))) {\r
\r
//\r
- // Mark the old variable as in delete transition\r
+ // Mark the old variable as in delete transition.\r
//\r
State = Variable->CurrPtr->State;\r
State &= VAR_IN_DELETED_TRANSITION;\r
if (EFI_ERROR (Status)) {\r
goto Done; \r
} \r
+ if (!Variable->Volatile) {\r
+ CacheVariable->CurrPtr->State = State;\r
+ }\r
} \r
} else {\r
//\r
- // Not found existing variable. Create a new variable\r
+ // Not found existing variable. Create a new variable.\r
// \r
\r
//\r
// Make sure we are trying to create a new variable.\r
- // Setting a data variable with no access, or zero DataSize attributes means to delete it. \r
+ // Setting a data variable with zero DataSize or no access attributes means to delete it. \r
//\r
if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {\r
Status = EFI_NOT_FOUND;\r
}\r
\r
//\r
- // Only variable have NV|RT attribute can be created in Runtime\r
+ // Only variable have NV|RT attribute can be created in Runtime.\r
//\r
- if (EfiAtRuntime () &&\r
+ if (AtRuntime () &&\r
(((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) || ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0))) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
//\r
// Function part - create a new variable and copy the data.\r
// Both update a variable and create a variable will come here.\r
+\r
//\r
// Tricky part: Use scratch data area at the end of volatile variable store\r
// as a temporary storage.\r
//\r
// NextVariable->State = VAR_ADDED;\r
//\r
- NextVariable->Reserved = 0;\r
- VarNameOffset = sizeof (VARIABLE_HEADER);\r
- VarNameSize = StrSize (VariableName);\r
+ NextVariable->Reserved = 0;\r
+ VarNameOffset = sizeof (VARIABLE_HEADER);\r
+ VarNameSize = StrSize (VariableName);\r
CopyMem (\r
(UINT8 *) ((UINTN) NextVariable + VarNameOffset),\r
VariableName,\r
//\r
// There will be pad bytes after Data, the NextVariable->NameSize and\r
// NextVariable->DataSize should not include pad size so that variable\r
- // service can get actual size in GetVariable\r
+ // service can get actual size in GetVariable.\r
//\r
NextVariable->NameSize = (UINT32)VarNameSize;\r
NextVariable->DataSize = (UINT32)DataSize;\r
VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize);\r
if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
//\r
- // Create a nonvolatile variable\r
+ // Create a nonvolatile variable.\r
//\r
Volatile = FALSE;\r
NonVolatileVarableStoreSize = ((VARIABLE_STORE_HEADER *)(UINTN)(mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase))->Size;\r
&& ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))\r
|| (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) \r
&& ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) {\r
- if (EfiAtRuntime ()) {\r
+ if (AtRuntime ()) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
//\r
- // Perform garbage collection & reclaim operation\r
+ // Perform garbage collection & reclaim operation.\r
//\r
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, \r
&mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr);\r
goto Done;\r
}\r
//\r
- // If still no enough space, return out of resources\r
+ // If still no enough space, return out of resources.\r
//\r
if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) \r
&& ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))\r
Reclaimed = TRUE;\r
}\r
//\r
- // Three steps\r
+ // Four steps\r
// 1. Write variable header\r
// 2. Set variable state to header valid \r
// 3. Write variable data\r
//\r
// Step 1:\r
//\r
+ CacheOffset = mVariableModuleGlobal->NonVolatileLastVariableOffset;\r
Status = UpdateVariableStore (\r
&mVariableModuleGlobal->VariableGlobal,\r
FALSE,\r
FALSE,\r
TRUE,\r
Fvb,\r
- mVariableModuleGlobal->NonVolatileLastVariableOffset,\r
- sizeof (VARIABLE_HEADER),\r
- (UINT8 *) NextVariable\r
+ mVariableModuleGlobal->NonVolatileLastVariableOffset + OFFSET_OF (VARIABLE_HEADER, State),\r
+ sizeof (UINT8),\r
+ &NextVariable->State\r
);\r
\r
if (EFI_ERROR (Status)) {\r
FALSE,\r
TRUE,\r
Fvb,\r
- mVariableModuleGlobal->NonVolatileLastVariableOffset,\r
- sizeof (VARIABLE_HEADER),\r
- (UINT8 *) NextVariable\r
+ mVariableModuleGlobal->NonVolatileLastVariableOffset + OFFSET_OF (VARIABLE_HEADER, State),\r
+ sizeof (UINT8),\r
+ &NextVariable->State\r
);\r
\r
if (EFI_ERROR (Status)) {\r
} else {\r
mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VarSize);\r
}\r
+ //\r
+ // update the memory copy of Flash region.\r
+ //\r
+ CopyMem ((UINT8 *)mNvVariableCache + CacheOffset, (UINT8 *)NextVariable, VarSize);\r
} else {\r
//\r
- // Create a volatile variable\r
+ // Create a volatile variable.\r
// \r
Volatile = TRUE;\r
\r
if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) >\r
((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size) {\r
//\r
- // Perform garbage collection & reclaim operation\r
+ // Perform garbage collection & reclaim operation.\r
//\r
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase, \r
&mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr);\r
goto Done;\r
}\r
//\r
- // If still no enough space, return out of resources\r
+ // If still no enough space, return out of resources.\r
//\r
if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) >\r
((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size\r
}\r
\r
//\r
- // Mark the old variable as deleted\r
+ // Mark the old variable as deleted.\r
//\r
if (!Reclaimed && !EFI_ERROR (Status) && Variable->CurrPtr != NULL) {\r
State = Variable->CurrPtr->State;\r
sizeof (UINT8),\r
&State\r
);\r
+ if (!EFI_ERROR (Status) && !Variable->Volatile) { \r
+ CacheVariable->CurrPtr->State = State;\r
+ }\r
}\r
\r
if (!EFI_ERROR (Status)) {\r
UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE, FALSE, FALSE);\r
- UpdateVariableCache (VariableName, VendorGuid, Attributes, DataSize, Data);\r
}\r
\r
Done:\r
data, this value contains the required size.\r
@param Data Data pointer.\r
\r
- @return EFI_INVALID_PARAMETER Invalid parameter\r
- @return EFI_SUCCESS Find the specified variable\r
- @return EFI_NOT_FOUND Not found\r
- @return EFI_BUFFER_TO_SMALL DataSize is too small for the result\r
+ @return EFI_INVALID_PARAMETER Invalid parameter.\r
+ @return EFI_SUCCESS Find the specified variable.\r
+ @return EFI_NOT_FOUND Not found.\r
+ @return EFI_BUFFER_TO_SMALL DataSize is too small for the result.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-RuntimeServiceGetVariable (\r
+VariableServiceGetVariable (\r
IN CHAR16 *VariableName,\r
IN EFI_GUID *VendorGuid,\r
OUT UINT32 *Attributes OPTIONAL,\r
}\r
\r
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
-\r
- //\r
- // Find existing variable\r
- //\r
- Status = FindVariableInCache (VariableName, VendorGuid, Attributes, DataSize, Data);\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
- goto Done;\r
- }\r
\r
Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
\r
*DataSize = VarDataSize;\r
UpdateVariableInfo (VariableName, VendorGuid, Variable.Volatile, TRUE, FALSE, FALSE, FALSE);\r
- UpdateVariableCache (VariableName, VendorGuid, Variable.CurrPtr->Attributes, VarDataSize, Data);\r
\r
Status = EFI_SUCCESS;\r
goto Done;\r
\r
This code Finds the Next available variable.\r
\r
- @param VariableNameSize Size of the variable name\r
- @param VariableName Pointer to variable name\r
- @param VendorGuid Variable Vendor Guid\r
+ @param VariableNameSize Size of the variable name.\r
+ @param VariableName Pointer to variable name.\r
+ @param VendorGuid Variable Vendor Guid.\r
\r
- @return EFI_INVALID_PARAMETER Invalid parameter\r
- @return EFI_SUCCESS Find the specified variable\r
- @return EFI_NOT_FOUND Not found\r
- @return EFI_BUFFER_TO_SMALL DataSize is too small for the result\r
+ @return EFI_INVALID_PARAMETER Invalid parameter.\r
+ @return EFI_SUCCESS Find the specified variable.\r
+ @return EFI_NOT_FOUND Not found.\r
+ @return EFI_BUFFER_TO_SMALL DataSize is too small for the result.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-RuntimeServiceGetNextVariableName (\r
+VariableServiceGetNextVariableName (\r
IN OUT UINTN *VariableNameSize,\r
IN OUT CHAR16 *VariableName,\r
IN OUT EFI_GUID *VendorGuid\r
\r
if (VariableName[0] != 0) {\r
//\r
- // If variable name is not NULL, get next variable\r
+ // If variable name is not NULL, get next variable.\r
//\r
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
}\r
while (TRUE) {\r
//\r
// If both volatile and non-volatile variable store are parsed,\r
- // return not found\r
+ // return not found.\r
//\r
if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {\r
Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1));\r
// Variable is found\r
//\r
if (IsValidVariableHeader (Variable.CurrPtr) && Variable.CurrPtr->State == VAR_ADDED) {\r
- if ((EfiAtRuntime () && ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) == 0) {\r
+ if ((AtRuntime () && ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) == 0) {\r
VarNameSize = NameSizeOfVariable (Variable.CurrPtr);\r
ASSERT (VarNameSize != 0);\r
\r
\r
This code sets variable in storage blocks (Volatile or Non-Volatile).\r
\r
- @param VariableName Name of Variable to be found\r
- @param VendorGuid Variable vendor GUID\r
+ @param VariableName Name of Variable to be found.\r
+ @param VendorGuid Variable vendor GUID.\r
@param Attributes Attribute value of the variable found\r
@param DataSize Size of Data found. If size is less than the\r
data, this value contains the required size.\r
- @param Data Data pointer\r
+ @param Data Data pointer.\r
\r
- @return EFI_INVALID_PARAMETER Invalid parameter\r
- @return EFI_SUCCESS Set successfully\r
- @return EFI_OUT_OF_RESOURCES Resource not enough to set variable\r
- @return EFI_NOT_FOUND Not found\r
- @return EFI_WRITE_PROTECTED Variable is read-only\r
+ @return EFI_INVALID_PARAMETER Invalid parameter.\r
+ @return EFI_SUCCESS Set successfully.\r
+ @return EFI_OUT_OF_RESOURCES Resource not enough to set variable.\r
+ @return EFI_NOT_FOUND Not found.\r
+ @return EFI_WRITE_PROTECTED Variable is read-only.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-RuntimeServiceSetVariable (\r
+VariableServiceSetVariable (\r
IN CHAR16 *VariableName,\r
IN EFI_GUID *VendorGuid,\r
IN UINT32 Attributes,\r
EFI_PHYSICAL_ADDRESS Point;\r
\r
//\r
- // Check input parameters\r
+ // Check input parameters.\r
//\r
if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {\r
return EFI_INVALID_PARAMETER;\r
- }\r
+ } \r
\r
if (DataSize != 0 && Data == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
- // Make sure if runtime bit is set, boot service bit is set also\r
+ // Make sure if runtime bit is set, boot service bit is set also.\r
//\r
if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {\r
return EFI_INVALID_PARAMETER;\r
return EFI_INVALID_PARAMETER;\r
}\r
//\r
- // According to UEFI spec, HARDWARE_ERROR_RECORD variable name convention should be L"HwErrRecXXXX"\r
+ // According to UEFI spec, HARDWARE_ERROR_RECORD variable name convention should be L"HwErrRecXXXX".\r
//\r
if (StrnCmp(VariableName, L"HwErrRec", StrLen(L"HwErrRec")) != 0) {\r
return EFI_INVALID_PARAMETER;\r
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
//\r
- // Consider reentrant in MCA/INIT/NMI. It needs be reupdated;\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
+ Point = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;\r
//\r
- // Parse non-volatile variable data and get last variable offset\r
+ // Parse non-volatile variable data and get last variable offset.\r
//\r
NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point);\r
while ((NextVariable < GetEndPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point)) \r
}\r
\r
//\r
- // Check whether the input variable is already existed\r
+ // Check whether the input variable is already existed.\r
//\r
FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal);\r
\r
//\r
- // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang\r
+ // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang.\r
//\r
AutoUpdateLangVariable (VariableName, Data, DataSize);\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-RuntimeServiceQueryVariableInfo (\r
+VariableServiceQueryVariableInfo (\r
IN UINT32 Attributes,\r
OUT UINT64 *MaximumVariableStorageSize,\r
OUT UINT64 *RemainingVariableStorageSize,\r
// Make sure if runtime bit is set, boot service bit is set also.\r
//\r
return EFI_INVALID_PARAMETER;\r
- } else if (EfiAtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {\r
+ } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {\r
//\r
// Make sure RT Attribute is set if we are in Runtime phase.\r
//\r
//\r
// Query is Non-Volatile related.\r
//\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);\r
+ VariableStoreHeader = mNvVariableCache;\r
}\r
\r
//\r
NextVariable = GetNextVariablePtr (Variable);\r
VariableSize = (UINT64) (UINTN) NextVariable - (UINT64) (UINTN) Variable;\r
\r
- if (EfiAtRuntime ()) {\r
+ if (AtRuntime ()) {\r
//\r
- // we don't take the state of the variables in mind\r
+ // We don't take the state of the variables in mind\r
// when calculating RemainingVariableStorageSize,\r
// since the space occupied by variables not marked with\r
// VAR_ADDED is not allowed to be reclaimed in Runtime.\r
}\r
} else {\r
//\r
- // Only care about Variables with State VAR_ADDED,because\r
+ // Only care about Variables with State VAR_ADDED, because\r
// the space not marked as VAR_ADDED is reclaimable now.\r
//\r
if (Variable->State == VAR_ADDED) {\r
}\r
\r
//\r
- // Go to the next one\r
+ // Go to the next one.\r
//\r
Variable = NextVariable;\r
}\r
\r
\r
/**\r
- Notification function of EVT_GROUP_READY_TO_BOOT event group.\r
-\r
- This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.\r
- When the Boot Manager is about to load and execute a boot option, it reclaims variable\r
- storage if free size is below the threshold.\r
-\r
- @param Event Event whose notification function is being invoked\r
- @param Context Pointer to the notification function's context\r
-\r
+ This function reclaims variable storage if free size is below the threshold.\r
+ \r
**/\r
VOID\r
-EFIAPI\r
ReclaimForOS(\r
- EFI_EVENT Event,\r
- VOID *Context\r
+ VOID\r
)\r
{\r
EFI_STATUS Status;\r
}\r
}\r
\r
+\r
/**\r
- Initializes variable store area for non-volatile and volatile variable.\r
+ Initializes variable write service after FVB was ready.\r
\r
- @param FvbProtocol Pointer to an instance of EFI Firmware Volume Block Protocol.\r
+ @retval EFI_SUCCESS Function successfully executed.\r
+ @retval Others Fail to initialize the variable service.\r
+\r
+**/\r
+EFI_STATUS\r
+VariableWriteServiceInitialize (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VARIABLE_STORE_HEADER *VariableStoreHeader;\r
+ UINTN Index;\r
+ UINT8 Data;\r
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r
+ EFI_PHYSICAL_ADDRESS BaseAddress;\r
+ UINT64 Length;\r
+ EFI_PHYSICAL_ADDRESS VariableStoreBase;\r
+ UINT64 VariableStoreLength;\r
+\r
+ VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;\r
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;\r
+ VariableStoreLength = VariableStoreHeader->Size;\r
+ \r
+ //\r
+ // Check if the free area is really free.\r
+ //\r
+ for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < VariableStoreLength; Index++) {\r
+ Data = ((UINT8 *) mNvVariableCache)[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.NonVolatileVariableBase,\r
+ &mVariableModuleGlobal->NonVolatileLastVariableOffset,\r
+ FALSE,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Mark the variable storage region of the FLASH as RUNTIME.\r
+ //\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
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));\r
+ } else {\r
+ Status = gDS->SetMemorySpaceAttributes (\r
+ BaseAddress,\r
+ Length,\r
+ GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));\r
+ }\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Initializes variable store area for non-volatile and volatile variable.\r
\r
@retval EFI_SUCCESS Function successfully executed.\r
@retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resource.\r
**/\r
EFI_STATUS\r
VariableCommonInitialize (\r
- IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol\r
+ VOID\r
)\r
{\r
EFI_STATUS Status;\r
VARIABLE_STORE_HEADER *VariableStoreHeader;\r
VARIABLE_HEADER *NextVariable;\r
EFI_PHYSICAL_ADDRESS TempVariableStoreHeader;\r
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;\r
- EFI_PHYSICAL_ADDRESS BaseAddress;\r
- UINT64 Length;\r
- UINTN Index;\r
- UINT8 Data;\r
EFI_PHYSICAL_ADDRESS VariableStoreBase;\r
UINT64 VariableStoreLength;\r
- EFI_EVENT ReadyToBootEvent;\r
UINTN ScratchSize;\r
UINTN VariableSize;\r
\r
- Status = EFI_SUCCESS;\r
//\r
// Allocate runtime memory for variable driver global structure.\r
//\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock, TPL_NOTIFY);\r
+ InitializeLock (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock, TPL_NOTIFY);\r
\r
//\r
// Note that in EdkII variable driver implementation, Hardware Error Record type variable\r
SetMem (VolatileVariableStore, PcdGet32 (PcdVariableStoreSize) + ScratchSize, 0xff);\r
\r
//\r
- // Variable Specific Data\r
+ // Initialize Variable Specific Data.\r
//\r
mVariableModuleGlobal->VariableGlobal.VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore;\r
mVariableModuleGlobal->VolatileLastVariableOffset = (UINTN) GetStartPointer (VolatileVariableStore) - (UINTN) VolatileVariableStore;\r
- mVariableModuleGlobal->FvbInstance = FvbProtocol;\r
+ mVariableModuleGlobal->FvbInstance = NULL;\r
\r
CopyGuid (&VolatileVariableStore->Signature, &gEfiVariableGuid);\r
- VolatileVariableStore->Size = PcdGet32 (PcdVariableStoreSize);\r
- VolatileVariableStore->Format = VARIABLE_STORE_FORMATTED;\r
- VolatileVariableStore->State = VARIABLE_STORE_HEALTHY;\r
- VolatileVariableStore->Reserved = 0;\r
- VolatileVariableStore->Reserved1 = 0;\r
+ VolatileVariableStore->Size = PcdGet32 (PcdVariableStoreSize);\r
+ VolatileVariableStore->Format = VARIABLE_STORE_FORMATTED;\r
+ VolatileVariableStore->State = VARIABLE_STORE_HEALTHY;\r
+ VolatileVariableStore->Reserved = 0;\r
+ VolatileVariableStore->Reserved1 = 0;\r
\r
//\r
- // Get non volatile varaible store\r
+ // Get non-volatile varaible store.\r
//\r
\r
TempVariableStoreHeader = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);\r
if (TempVariableStoreHeader == 0) {\r
TempVariableStoreHeader = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);\r
}\r
- \r
- VariableStoreBase = TempVariableStoreHeader + \\r
+ VariableStoreBase = TempVariableStoreHeader + \\r
+ (((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(TempVariableStoreHeader)) -> HeaderLength);\r
+ VariableStoreLength = (UINT64) PcdGet32 (PcdFlashNvStorageVariableSize) - \\r
(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(TempVariableStoreHeader)) -> HeaderLength);\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 = 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
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
\r
- Status = gDS->SetMemorySpaceAttributes (\r
- BaseAddress,\r
- Length,\r
- GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME\r
- );\r
- if (EFI_ERROR (Status)) {\r
+ mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;\r
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;\r
+ if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) {\r
+ Status = EFI_VOLUME_CORRUPTED;\r
+ DEBUG((EFI_D_INFO, "Variable Store header is corrupted\n"));\r
goto Done;\r
- }\r
+ } \r
+ ASSERT(VariableStoreHeader->Size == VariableStoreLength);\r
+ \r
//\r
- // Get address of non volatile variable store base\r
+ // Parse non-volatile variable data and get last variable offset.\r
//\r
- mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;\r
- VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;\r
- if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {\r
- if (~VariableStoreHeader->Size == 0) {\r
- Status = UpdateVariableStore (\r
- &mVariableModuleGlobal->VariableGlobal,\r
- FALSE,\r
- FALSE,\r
- mVariableModuleGlobal->FvbInstance,\r
- (UINTN) &VariableStoreHeader->Size,\r
- sizeof (UINT32),\r
- (UINT8 *) &VariableStoreLength\r
- );\r
- //\r
- // As Variables are stored in NV storage, which are slow devices,such as flash.\r
- // Variable operation may skip checking variable program result to improve performance,\r
- // We can assume Variable program is OK through some check point.\r
- // Variable Store Size Setting should be the first Variable write operation,\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 == VariableStoreLength);\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- }\r
-\r
- //\r
- // Parse non-volatile variable data and get last variable offset\r
- //\r
- NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase);\r
- Status = EFI_SUCCESS;\r
-\r
- while (IsValidVariableHeader (NextVariable)) {\r
- VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);\r
- if ((NextVariable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
- mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);\r
- } else {\r
- mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);\r
- }\r
-\r
- NextVariable = GetNextVariablePtr (NextVariable);\r
+ NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase);\r
+ while (IsValidVariableHeader (NextVariable)) {\r
+ VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);\r
+ if ((NextVariable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
+ mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);\r
+ } else {\r
+ mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);\r
}\r
\r
- mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) VariableStoreBase;\r
-\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.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.NonVolatileVariableBase,\r
- &mVariableModuleGlobal->NonVolatileLastVariableOffset,\r
- FALSE,\r
- NULL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- break;\r
- }\r
- }\r
+ NextVariable = GetNextVariablePtr (NextVariable);\r
+ }\r
\r
- //\r
- // Register the event handling function to reclaim variable for OS usage.\r
- //\r
- Status = EfiCreateEventReadyToBootEx (\r
- TPL_NOTIFY, \r
- ReclaimForOS, \r
- NULL, \r
- &ReadyToBootEvent\r
- );\r
- } else {\r
- Status = EFI_VOLUME_CORRUPTED;\r
- DEBUG((EFI_D_INFO, "Variable Store header is corrupted\n"));\r
+ mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) VariableStoreBase;\r
+ \r
+ //\r
+ // Allocate runtime memory used for a memory copy of the FLASH region.\r
+ // Keep the memory and the FLASH in sync as updates occur\r
+ //\r
+ mNvVariableCache = AllocateRuntimeZeroPool ((UINTN)VariableStoreLength);\r
+ if (mNvVariableCache == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
}\r
+ CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableStoreBase, (UINTN)VariableStoreLength);\r
+ Status = EFI_SUCCESS;\r
\r
Done:\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
-/**\r
- Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE\r
-\r
- This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
- It convers pointer to new virtual address.\r
-\r
- @param Event Event whose notification function is being invoked\r
- @param Context Pointer to the notification function's context\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-VariableClassAddressChangeEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetAttributes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->SetAttributes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Read);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Write);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->EraseBlocks);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);\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
- Firmware Volume Block Protocol notification event handler.\r
+ Get the proper fvb handle and/or fvb protocol by the given Flash address.\r
\r
- Discover NV Variable Store and install Variable Arch Protocol.\r
+ @param[in] Address The Flash address.\r
+ @param[out] FvbHandle In output, if it is not NULL, it points to the proper FVB handle.\r
+ @param[out] FvbProtocol In output, if it is not NULL, it points to the proper FVB protocol.\r
\r
- @param[in] Event Event whose notification function is being invoked.\r
- @param[in] Context Pointer to the notification function's context.\r
**/\r
-VOID\r
-EFIAPI\r
-FvbNotificationEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
+EFI_STATUS\r
+GetFvbInfoByAddress (\r
+ IN EFI_PHYSICAL_ADDRESS Address,\r
+ OUT EFI_HANDLE *FvbHandle OPTIONAL,\r
+ OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvbProtocol OPTIONAL\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN HandleCount;\r
- UINTN Index;\r
- EFI_PHYSICAL_ADDRESS FvbBaseAddress;\r
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
- EFI_FVB_ATTRIBUTES_2 Attributes;\r
- EFI_SYSTEM_TABLE *SystemTable;\r
- EFI_PHYSICAL_ADDRESS NvStorageVariableBase;\r
-\r
- SystemTable = (EFI_SYSTEM_TABLE *)Context;\r
- Fvb = NULL;\r
- \r
+ EFI_STATUS Status;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN HandleCount;\r
+ UINTN Index;\r
+ EFI_PHYSICAL_ADDRESS FvbBaseAddress;\r
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
+ EFI_FVB_ATTRIBUTES_2 Attributes;\r
+ \r
//\r
- // Locate all handles of Fvb protocol\r
+ // Get all FVB handles.\r
//\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
+ Status = GetFvbCountAndBuffer (&HandleCount, &HandleBuffer);\r
if (EFI_ERROR (Status)) {\r
- return ;\r
+ return EFI_NOT_FOUND;\r
}\r
- \r
+\r
//\r
- // Get the FVB to access variable store\r
+ // Get the FVB to access variable store.\r
//\r
+ Fvb = NULL;\r
for (Index = 0; Index < HandleCount; Index += 1, Status = EFI_NOT_FOUND, Fvb = NULL) {\r
- Status = gBS->HandleProtocol (\r
- HandleBuffer[Index],\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- (VOID **) &Fvb\r
- );\r
+ Status = GetFvbByHandle (HandleBuffer[Index], &Fvb);\r
if (EFI_ERROR (Status)) {\r
Status = EFI_NOT_FOUND;\r
break;\r
if (EFI_ERROR (Status) || ((Attributes & EFI_FVB2_WRITE_STATUS) == 0)) {\r
continue; \r
}\r
+ \r
//\r
- // Compare the address and select the right one\r
+ // Compare the address and select the right one.\r
//\r
Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);\r
if (EFI_ERROR (Status)) {\r
}\r
\r
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);\r
- NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);\r
- if (NvStorageVariableBase == 0) {\r
- NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);\r
- }\r
- \r
- if ((NvStorageVariableBase >= FvbBaseAddress) && (NvStorageVariableBase < (FvbBaseAddress + FwVolHeader->FvLength))) {\r
- Status = EFI_SUCCESS;\r
+ if ((Address >= FvbBaseAddress) && (Address < (FvbBaseAddress + FwVolHeader->FvLength))) {\r
+ if (FvbHandle != NULL) {\r
+ *FvbHandle = HandleBuffer[Index];\r
+ }\r
+ if (FvbProtocol != NULL) {\r
+ *FvbProtocol = Fvb;\r
+ }\r
+ Status = EFI_SUCCESS;\r
break;\r
}\r
}\r
-\r
FreePool (HandleBuffer);\r
- if (!EFI_ERROR (Status) && Fvb != NULL) {\r
- //\r
- // Close the notify event to avoid install gEfiVariableArchProtocolGuid & gEfiVariableWriteArchProtocolGuid again.\r
- //\r
- Status = gBS->CloseEvent (Event); \r
- ASSERT_EFI_ERROR (Status);\r
\r
- Status = VariableCommonInitialize (Fvb);\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->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- VariableClassAddressChangeEvent,\r
- NULL,\r
- &gEfiEventVirtualAddressChangeGuid,\r
- &mVirtualAddressChangeEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+ if (Fvb == NULL) {\r
+ Status = EFI_NOT_FOUND;\r
}\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. It also registers\r
- notification function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\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 Variable service successfully initialized.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-VariableServiceInitialize (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- //\r
- // Register FvbNotificationEvent () notify function.\r
- // \r
- EfiCreateProtocolNotifyEvent (\r
- &gEfiFirmwareVolumeBlockProtocolGuid,\r
- TPL_CALLBACK,\r
- FvbNotificationEvent,\r
- (VOID *)SystemTable,\r
- &mFvbRegistration\r
- );\r
-\r
- return EFI_SUCCESS;\r
+ return Status; \r
}\r
\r