From: qwang12 Date: Fri, 6 Jul 2007 10:39:15 +0000 (+0000) Subject: Add in EmuVariableRuntimeDxe X-Git-Tag: edk2-stable201903~22832 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=f80315c3c9856fe9ef4f53e94fbf1a417b36d144 Add in EmuVariableRuntimeDxe git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3123 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.c b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.c new file mode 100644 index 0000000000..f56cf04215 --- /dev/null +++ b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.c @@ -0,0 +1,849 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + EmuVariable.c + +Abstract: + +Revision History + +--*/ + +#include "Variable.h" + +// +// Don't use module globals after the SetVirtualAddress map is signaled +// +ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal; + +// +// This is a temperary function which will be removed +// when EfiAcquireLock in UefiLib can handle the +// the call in UEFI Runtimer driver in RT phase. +// +STATIC +VOID +AcquireLockOnlyAtBootTime ( + IN EFI_LOCK *Lock + ) +{ + if (!EfiAtRuntime ()) { + EfiAcquireLock (Lock); + } +} + +// +// This is a temperary function which will be removed +// when EfiAcquireLock in UefiLib can handle the +// the call in UEFI Runtimer driver in RT phase. +// +STATIC +VOID +ReleaseLockOnlyAtBootTime ( + IN EFI_LOCK *Lock + ) +{ + if (!EfiAtRuntime ()) { + EfiReleaseLock (Lock); + } +} + +STATIC +UINT8 * +EFIAPI +GetVariableDataPtr ( + IN VARIABLE_HEADER *Variable + ) +/*++ + +Routine Description: + + This code gets the pointer to the variable data. + +Arguments: + + Variable Pointer to the Variable Header. + +Returns: + + UINT8* Pointer to Variable Data + +--*/ +{ + if (Variable->StartId != VARIABLE_DATA) { + return NULL; + } + // + // Be careful about pad size for alignment + // + return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize)); +} + +STATIC +VARIABLE_HEADER * +EFIAPI +GetNextVariablePtr ( + IN VARIABLE_HEADER *Variable + ) +/*++ + +Routine Description: + + This code gets the pointer to the next variable header. + +Arguments: + + Variable Pointer to the Variable Header. + +Returns: + + VARIABLE_HEADER* Pointer to next variable header. + +--*/ +{ + VARIABLE_HEADER *VarHeader; + + if (Variable->StartId != VARIABLE_DATA) { + return NULL; + } + // + // Be careful about pad size for alignment + // + VarHeader = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize)); + + if (VarHeader->StartId != VARIABLE_DATA || + (sizeof (VARIABLE_HEADER) + VarHeader->DataSize + VarHeader->NameSize) > MAX_VARIABLE_SIZE + ) { + return NULL; + } + + return VarHeader; +} + +STATIC +VARIABLE_HEADER * +EFIAPI +GetEndPointer ( + IN VARIABLE_STORE_HEADER *VolHeader + ) +/*++ + +Routine Description: + + This code gets the pointer to the last variable memory pointer byte + +Arguments: + + Variable Pointer to the Variable Header. + +Returns: + + VARIABLE_HEADER* Pointer to last unavailable Variable Header + +--*/ +{ + // + // The end of variable store + // + return (VARIABLE_HEADER *) ((UINTN) VolHeader + VolHeader->Size); +} + +STATIC +EFI_STATUS +EFIAPI +FindVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT VARIABLE_POINTER_TRACK *PtrTrack, + IN VARIABLE_GLOBAL *Global + ) +/*++ + +Routine Description: + + This code finds variable in storage blocks (Volatile or Non-Volatile) + +Arguments: + + VariableName Name of the variable to be found + VendorGuid Vendor GUID to be found. + PtrTrack Variable Track Pointer structure that contains + Variable Information. + Contains the pointer of Variable header. + Global VARIABLE_GLOBAL pointer + +Returns: + + EFI STATUS + +--*/ +{ + VARIABLE_HEADER *Variable[2]; + VARIABLE_STORE_HEADER *VariableStoreHeader[2]; + UINTN Index; + + // + // We aquire the lock at the entry of FindVariable as GetVariable, GetNextVariableName + // SetVariable all call FindVariable at entry point. Please move "Aquire Lock" to + // the correct places if this assumption does not hold TRUE anymore. + // + AcquireLockOnlyAtBootTime(&Global->VariableServicesLock); + + // + // 0: Non-Volatile, 1: Volatile + // + VariableStoreHeader[0] = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase); + VariableStoreHeader[1] = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase); + + // + // Start Pointers for the variable. + // Actual Data Pointer where data can be written. + // + Variable[0] = (VARIABLE_HEADER *) (VariableStoreHeader[0] + 1); + Variable[1] = (VARIABLE_HEADER *) (VariableStoreHeader[1] + 1); + + if (VariableName[0] != 0 && VendorGuid == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Find the variable by walk through non-volatile and volatile variable store + // + for (Index = 0; Index < 2; Index++) { + PtrTrack->StartPtr = (VARIABLE_HEADER *) (VariableStoreHeader[Index] + 1); + PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]); + + while ((Variable[Index] != NULL) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) { + if (Variable[Index]->StartId == VARIABLE_DATA && Variable[Index]->State == VAR_ADDED) { + if (!(EfiAtRuntime () && !(Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) { + if (VariableName[0] == 0) { + PtrTrack->CurrPtr = Variable[Index]; + PtrTrack->Volatile = (BOOLEAN) Index; + return EFI_SUCCESS; + } else { + if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) { + if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), Variable[Index]->NameSize)) { + PtrTrack->CurrPtr = Variable[Index]; + PtrTrack->Volatile = (BOOLEAN) Index; + return EFI_SUCCESS; + } + } + } + } + } + + Variable[Index] = GetNextVariablePtr (Variable[Index]); + } + } + PtrTrack->CurrPtr = NULL; + return EFI_NOT_FOUND; +} + +EFI_STATUS +EFIAPI +GetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID * VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data, + IN VARIABLE_GLOBAL * Global, + IN UINT32 Instance + ) +/*++ + +Routine Description: + + This code finds variable in storage blocks (Volatile or Non-Volatile) + +Arguments: + + VariableName Name of Variable to be found + VendorGuid Variable vendor GUID + Attributes OPTIONAL Attribute value of the variable found + DataSize Size of Data found. If size is less than the + data, this value contains the required size. + Data Data pointer + Global Pointer to VARIABLE_GLOBAL structure + Instance Instance of the Firmware Volume. + +Returns: + + EFI STATUS + +--*/ +{ + VARIABLE_POINTER_TRACK Variable; + UINTN VarDataSize; + EFI_STATUS Status; + + if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Find existing variable + // + Status = FindVariable (VariableName, VendorGuid, &Variable, Global); + + if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) { + goto Done; + } + // + // Get data size + // + VarDataSize = Variable.CurrPtr->DataSize; + if (*DataSize >= VarDataSize) { + if (Data == NULL) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize); + if (Attributes != NULL) { + *Attributes = Variable.CurrPtr->Attributes; + } + + *DataSize = VarDataSize; + Status = EFI_SUCCESS; + goto Done; + } else { + *DataSize = VarDataSize; + Status = EFI_BUFFER_TOO_SMALL; + goto Done; + } + +Done: + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + return Status; +} + +EFI_STATUS +EFIAPI +GetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid, + IN VARIABLE_GLOBAL *Global, + IN UINT32 Instance + ) +/*++ + +Routine Description: + + This code Finds the Next available variable + +Arguments: + + VariableNameSize Size of the variable + VariableName Pointer to variable name + VendorGuid Variable Vendor Guid + Global VARIABLE_GLOBAL structure pointer. + Instance FV instance + +Returns: + + EFI STATUS + +--*/ +{ + VARIABLE_POINTER_TRACK Variable; + UINTN VarNameSize; + EFI_STATUS Status; + + if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = FindVariable (VariableName, VendorGuid, &Variable, Global); + + if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) { + goto Done; + } + + while (TRUE) { + if (VariableName[0] != 0) { + // + // If variable name is not NULL, get next variable + // + Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr); + } + // + // If both volatile and non-volatile variable store are parsed, + // return not found + // + if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) { + Variable.Volatile = (BOOLEAN) (Variable.Volatile ^ ((BOOLEAN) 0x1)); + if (Variable.Volatile) { + Variable.StartPtr = (VARIABLE_HEADER *) ((UINTN) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER))); + Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase)); + } else { + Status = EFI_NOT_FOUND; + goto Done; + } + + Variable.CurrPtr = Variable.StartPtr; + if (Variable.CurrPtr->StartId != VARIABLE_DATA) { + continue; + } + } + // + // Variable is found + // + if (Variable.CurrPtr->StartId == VARIABLE_DATA && Variable.CurrPtr->State == VAR_ADDED) { + if (!(EfiAtRuntime () && !(Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS))) { + VarNameSize = Variable.CurrPtr->NameSize; + if (VarNameSize <= *VariableNameSize) { + CopyMem ( + VariableName, + GET_VARIABLE_NAME_PTR (Variable.CurrPtr), + VarNameSize + ); + CopyMem ( + VendorGuid, + &Variable.CurrPtr->VendorGuid, + sizeof (EFI_GUID) + ); + Status = EFI_SUCCESS; + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + + *VariableNameSize = VarNameSize; + goto Done; + } + } + } + +Done: + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + return Status; + +} + +EFI_STATUS +EFIAPI +SetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data, + IN VARIABLE_GLOBAL *Global, + IN UINTN *VolatileOffset, + IN UINTN *NonVolatileOffset, + IN UINT32 Instance + ) +/*++ + +Routine Description: + + This code sets variable in storage blocks (Volatile or Non-Volatile) + +Arguments: + + VariableName Name of Variable to be found + VendorGuid Variable vendor GUID + Attributes Attribute value of the variable found + DataSize Size of Data found. If size is less than the + data, this value contains the required size. + Data Data pointer + Global Pointer to VARIABLE_GLOBAL structure + VolatileOffset The offset of last volatile variable + NonVolatileOffset The offset of last non-volatile variable + Instance Instance of the Firmware Volume. + +Returns: + + EFI STATUS + +--*/ +{ + VARIABLE_POINTER_TRACK Variable; + EFI_STATUS Status; + VARIABLE_HEADER *NextVariable; + UINTN VarNameSize; + UINTN VarNameOffset; + UINTN VarDataOffset; + UINTN VarSize; + + if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = FindVariable (VariableName, VendorGuid, &Variable, Global); + + if (Status == EFI_INVALID_PARAMETER) { + goto Done; + } else if (!EFI_ERROR (Status) && Variable.Volatile && EfiAtRuntime()) { + // + // If EfiAtRuntime and the variable is Volatile and Runtime Access, + // the volatile is ReadOnly, and SetVariable should be aborted and + // return EFI_WRITE_PROTECTED. + // + Status = EFI_WRITE_PROTECTED; + goto Done; + } else if (sizeof (VARIABLE_HEADER) + (StrSize (VariableName) + DataSize) > MAX_VARIABLE_SIZE) { + // + // The size of the VariableName, including the Unicode Null in bytes plus + // the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes. + // + Status = EFI_INVALID_PARAMETER; + goto Done; + } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS + ) { + // + // Make sure if runtime bit is set, boot service bit is set also + // + Status = EFI_INVALID_PARAMETER; + goto Done; + } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) { + // + // Runtime but Attribute is not Runtime + // + Status = EFI_INVALID_PARAMETER; + goto Done; + } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) { + // + // Cannot set volatile variable in Runtime + // + Status = EFI_INVALID_PARAMETER; + goto Done; + } else if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) { + // + // Setting a data variable with no access, or zero DataSize attributes + // specified causes it to be deleted. + // + if (!EFI_ERROR (Status)) { + Variable.CurrPtr->State &= VAR_DELETED; + Status = EFI_SUCCESS; + goto Done; + } + + Status = EFI_NOT_FOUND; + goto Done; + } else { + if (!EFI_ERROR (Status)) { + // + // If the variable is marked valid and the same data has been passed in + // then return to the caller immediately. + // + if (Variable.CurrPtr->DataSize == DataSize && + !CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize) + ) { + Status = EFI_SUCCESS; + goto Done; + } else if (Variable.CurrPtr->State == VAR_ADDED) { + // + // Mark the old variable as in delete transition + // + Variable.CurrPtr->State &= VAR_IN_DELETED_TRANSITION; + } + } + // + // Create a new variable and copy the data. + // + VarNameOffset = sizeof (VARIABLE_HEADER); + VarNameSize = StrSize (VariableName); + VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize); + VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize); + + if (Attributes & EFI_VARIABLE_NON_VOLATILE) { + if ((UINT32) (VarSize +*NonVolatileOffset) > + ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size + ) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*NonVolatileOffset + (UINTN) Global->NonVolatileVariableBase); + *NonVolatileOffset = *NonVolatileOffset + VarSize; + } else { + if (EfiAtRuntime ()) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + if ((UINT32) (VarSize +*VolatileOffset) > + ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size + ) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*VolatileOffset + (UINTN) Global->VolatileVariableBase); + *VolatileOffset = *VolatileOffset + VarSize; + } + + NextVariable->StartId = VARIABLE_DATA; + NextVariable->Attributes = Attributes; + NextVariable->State = VAR_ADDED; + NextVariable->Reserved = 0; + + // + // There will be pad bytes after Data, the NextVariable->NameSize and + // NextVariable->NameSize should not include pad size so that variable + // service can get actual size in GetVariable + // + NextVariable->NameSize = (UINT32)VarNameSize; + NextVariable->DataSize = (UINT32)DataSize; + + CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID)); + CopyMem ( + (UINT8 *) ((UINTN) NextVariable + VarNameOffset), + VariableName, + VarNameSize + ); + CopyMem ( + (UINT8 *) ((UINTN) NextVariable + VarDataOffset), + Data, + DataSize + ); + + // + // Mark the old variable as deleted + // + if (!EFI_ERROR (Status)) { + Variable.CurrPtr->State &= VAR_DELETED; + } + } + + Status = EFI_SUCCESS; +Done: + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + return Status; +} + +EFI_STATUS +EFIAPI +QueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize, + IN VARIABLE_GLOBAL *Global, + IN UINT32 Instance + ) +/*++ + +Routine Description: + + This code returns information about the EFI variables. + +Arguments: + + Attributes Attributes bitmask to specify the type of variables + on which to return information. + MaximumVariableStorageSize Pointer to the maximum size of the storage space available + for the EFI variables associated with the attributes specified. + RemainingVariableStorageSize Pointer to the remaining size of the storage space available + for the EFI variables associated with the attributes specified. + MaximumVariableSize Pointer to the maximum size of the individual EFI variables + associated with the attributes specified. + Global Pointer to VARIABLE_GLOBAL structure. + Instance Instance of the Firmware Volume. + +Returns: + + EFI STATUS + EFI_INVALID_PARAMETER - An invalid combination of attribute bits was supplied. + EFI_SUCCESS - Query successfully. + EFI_UNSUPPORTED - The attribute is not supported on this platform. + +--*/ +{ + VARIABLE_HEADER *Variable; + VARIABLE_HEADER *NextVariable; + UINT64 VariableSize; + VARIABLE_STORE_HEADER *VariableStoreHeader; + + if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)) == 0) { + // + // Make sure the Attributes combination is supported by the platform. + // + return EFI_UNSUPPORTED; + } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) { + // + // Make sure if runtime bit is set, boot service bit is set also. + // + return EFI_INVALID_PARAMETER; + } else if (EfiAtRuntime () && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) { + // + // Make sure RT Attribute is set if we are in Runtime phase. + // + return EFI_INVALID_PARAMETER; + } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) { + // + // Cannot Query volatile variable in Runtime + // + return EFI_INVALID_PARAMETER; + } + + AcquireLockOnlyAtBootTime(&Global->VariableServicesLock); + + if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) { + // + // Query is Volatile related. + // + VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase); + } else { + // + // Query is Non-Volatile related. + // + VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->NonVolatileVariableBase); + } + + // + // Now let's fill *MaximumVariableStorageSize *RemainingVariableStorageSize + // with the storage size (excluding the storage header size) + // + *MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER); + *RemainingVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER); + + // + // Let *MaximumVariableSize be MAX_VARIABLE_SIZE + // + *MaximumVariableSize = MAX_VARIABLE_SIZE; + + // + // Point to the starting address of the variables. + // + Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1); + + // + // Now walk through the related variable store. + // + while (Variable < GetEndPointer (VariableStoreHeader)) { + if (Variable->StartId != VARIABLE_DATA) { + break; + } + + NextVariable = (VARIABLE_HEADER *) (GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize)); + VariableSize = (UINT64) (UINTN) NextVariable - (UINT64) (UINTN) Variable; + + if (Variable->State == VAR_ADDED) { + *RemainingVariableStorageSize -= VariableSize; + } + + // + // Go to the next one. + // + Variable = NextVariable; + } + + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +EFIAPI +InitializeVariableStore ( + OUT EFI_PHYSICAL_ADDRESS *VariableBase, + OUT UINTN *LastVariableOffset + ) +/*++ + +Routine Description: + This function initializes variable store + +Arguments: + +Returns: + +--*/ +{ + VARIABLE_STORE_HEADER *VariableStore; + + // + // Allocate memory for volatile variable store + // + VariableStore = (VARIABLE_STORE_HEADER *) AllocateRuntimePool ( + VARIABLE_STORE_SIZE + ); + if (NULL == VariableStore) { + return EFI_OUT_OF_RESOURCES; + } + + SetMem (VariableStore, VARIABLE_STORE_SIZE, 0xff); + + // + // Variable Specific Data + // + *VariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStore; + *LastVariableOffset = sizeof (VARIABLE_STORE_HEADER); + + VariableStore->Signature = VARIABLE_STORE_SIGNATURE; + VariableStore->Size = VARIABLE_STORE_SIZE; + VariableStore->Format = VARIABLE_STORE_FORMATTED; + VariableStore->State = VARIABLE_STORE_HEALTHY; + VariableStore->Reserved = 0; + VariableStore->Reserved1 = 0; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +VariableCommonInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + This function does common initialization for variable services + +Arguments: + +Returns: + +--*/ +{ + EFI_STATUS Status; + + // + // Allocate memory for mVariableModuleGlobal + // + mVariableModuleGlobal = (ESAL_VARIABLE_GLOBAL *) AllocateRuntimePool ( + sizeof (ESAL_VARIABLE_GLOBAL) + ); + if (NULL == mVariableModuleGlobal) { + return EFI_OUT_OF_RESOURCES; + } + + EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal[Physical].VariableServicesLock, TPL_NOTIFY); + + // + // Intialize volatile variable store + // + Status = InitializeVariableStore ( + &mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase, + &mVariableModuleGlobal->VolatileLastVariableOffset + ); + + if (EFI_ERROR (Status)) { + return Status; + } + // + // Intialize non volatile variable store + // + Status = InitializeVariableStore ( + &mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase, + &mVariableModuleGlobal->NonVolatileLastVariableOffset + ); + + return Status; +} diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.infa b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.infa new file mode 100644 index 0000000000..a22d48b23d --- /dev/null +++ b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.infa @@ -0,0 +1,106 @@ +#/** @file +# Emulation Variable for EFI_RUNTIME_SERVICES. +# +# This module provides three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName +# Copyright (c) 2006 - 2007, Intel Corporation +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EmuVariable + FILE_GUID = CBD2E4D5-7068-4FF5-B866-9822B4AD8D61 + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = VariableServiceInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + InitVariable.c + EmuVariable.c + Variable.h + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + BaseLib + UefiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeLib + DebugLib + MemoryAllocationLib + BaseMemoryLib + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols.IA32] + gEfiVariableArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + gEfiVariableWriteArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + +[Protocols.X64] + gEfiVariableArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + gEfiVariableWriteArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +################################################################################ +# +# Dependency Expression Section - list of Dependency expressions that are required for +# this module. +# +################################################################################ + +[Depex] + TRUE + diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.msa b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.msa new file mode 100644 index 0000000000..6e769aa280 --- /dev/null +++ b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariable.msa @@ -0,0 +1,75 @@ + + + + EmuVariable + DXE_RUNTIME_DRIVER + CBD2E4D5-7068-4FF5-B866-9822B4AD8D61 + 1.0 + Emulation Variable for EFI_RUNTIME_SERVICES. + This module provides three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName + Copyright (c) 2006 - 2007, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 EBC + false + EmuVariable + + + + BaseMemoryLib + + + MemoryAllocationLib + + + DebugLib + + + UefiRuntimeLib + + + UefiDriverEntryPoint + + + UefiBootServicesTableLib + + + UefiLib + + + BaseLib + + + + Variable.h + EmuVariable.c + EmuVariable.dxs + InitVariable.c + + + + + + + + gEfiVariableWriteArchProtocolGuid + + + gEfiVariableArchProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + VariableServiceInitialize + + + \ No newline at end of file diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.inf b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.inf new file mode 100644 index 0000000000..b80c814901 --- /dev/null +++ b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.inf @@ -0,0 +1,102 @@ +#/** @file +# Emulation Variable for EFI_RUNTIME_SERVICES. +# +# This module provides three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName +# Copyright (c) 2006 - 2007, Intel Corporation +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EmuVariableIpf + FILE_GUID = A46320E8-0514-489a-BC4E-481624D9CE33 + MODULE_TYPE = DXE_SAL_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = VariableServiceInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IPF +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + Ipf/InitVariable.c + EmuVariable.c + Variable.h + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + ExtendedSalLib + BaseLib + UefiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeLib + DebugLib + MemoryAllocationLib + BaseMemoryLib + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiExtendedSalVariableServicesProtocolGuid # PROTOCOL ALWAYS_CONSUMED + + +################################################################################ +# +# Dependency Expression Section - list of Dependency expressions that are required for +# this module. +# +################################################################################ + +[Depex] + TRUE + diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.msa b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.msa new file mode 100644 index 0000000000..d4102d2b06 --- /dev/null +++ b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableIpf.msa @@ -0,0 +1,75 @@ + + + + EmuVariableIpf + DXE_SAL_DRIVER + A46320E8-0514-489a-BC4E-481624D9CE33 + 1.0 + Emulation Variable for EFI_RUNTIME_SERVICES. + This module provides three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName + Copyright (c) 2006 - 2007, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IPF + false + EmuVariableIpf + + + + BaseMemoryLib + + + MemoryAllocationLib + + + DebugLib + + + UefiRuntimeLib + + + UefiDriverEntryPoint + + + UefiBootServicesTableLib + + + UefiLib + + + BaseLib + + + ExtendedSalLib + + + + Variable.h + EmuVariable.c + EmuVariable.dxs + Ipf/InitVariable.c + + + + + + + + gEfiExtendedSalVariableServicesProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + VariableServiceInitialize + + + \ No newline at end of file diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/InitVariable.c b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/InitVariable.c new file mode 100644 index 0000000000..efff41c253 --- /dev/null +++ b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/InitVariable.c @@ -0,0 +1,214 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + InitVariable.c + +Abstract: + +Revision History + +--*/ + +#include "Variable.h" + +// +// Don't use module globals after the SetVirtualAddress map is signaled +// +extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal; + +EFI_STATUS +EFIAPI +RuntimeServiceGetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID * VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + return GetVariable ( + VariableName, + VendorGuid, + Attributes OPTIONAL, + DataSize, + Data, + &mVariableModuleGlobal->VariableGlobal[Physical], + mVariableModuleGlobal->FvbInstance + ); +} + +EFI_STATUS +EFIAPI +RuntimeServiceGetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + return GetNextVariableName ( + VariableNameSize, + VariableName, + VendorGuid, + &mVariableModuleGlobal->VariableGlobal[Physical], + mVariableModuleGlobal->FvbInstance + ); +} + +EFI_STATUS +EFIAPI +RuntimeServiceSetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + return SetVariable ( + VariableName, + VendorGuid, + Attributes, + DataSize, + Data, + &mVariableModuleGlobal->VariableGlobal[Physical], + &mVariableModuleGlobal->VolatileLastVariableOffset, + &mVariableModuleGlobal->NonVolatileLastVariableOffset, + mVariableModuleGlobal->FvbInstance + ); +} + +EFI_STATUS +EFIAPI +RuntimeServiceQueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + return QueryVariableInfo ( + Attributes, + MaximumVariableStorageSize, + RemainingVariableStorageSize, + MaximumVariableSize, + &mVariableModuleGlobal->VariableGlobal[Physical], + mVariableModuleGlobal->FvbInstance + ); +} + +VOID +EFIAPI +VariableClassAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + EfiConvertPointer ( + 0x0, + (VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase + ); + EfiConvertPointer ( + 0x0, + (VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase + ); + EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal); +} + +EFI_STATUS +EFIAPI +VariableServiceInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + EFI_HANDLE NewHandle; + EFI_STATUS Status; + + Status = VariableCommonInitialize (ImageHandle, SystemTable); + ASSERT_EFI_ERROR (Status); + + SystemTable->RuntimeServices->GetVariable = RuntimeServiceGetVariable; + SystemTable->RuntimeServices->GetNextVariableName = RuntimeServiceGetNextVariableName; + SystemTable->RuntimeServices->SetVariable = RuntimeServiceSetVariable; + SystemTable->RuntimeServices->QueryVariableInfo = RuntimeServiceQueryVariableInfo; + + // + // Now install the Variable Runtime Architectural Protocol on a new handle + // + NewHandle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &NewHandle, + &gEfiVariableArchProtocolGuid, + NULL, + &gEfiVariableWriteArchProtocolGuid, + NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/Ipf/InitVariable.c b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/Ipf/InitVariable.c new file mode 100644 index 0000000000..1b81dd64b9 --- /dev/null +++ b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/Ipf/InitVariable.c @@ -0,0 +1,181 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + IpfVariable.c + +Abstract: + +Revision History + +--*/ + +#include "Variable.h" +#include + +// +// Don't use module globals after the SetVirtualAddress map is signaled +// + +STATIC +SAL_RETURN_REGS +EsalVariableCommonEntry ( + IN UINT64 FunctionId, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN UINT64 Arg5, + IN UINT64 Arg6, + IN UINT64 Arg7, + IN UINT64 Arg8, + IN SAL_EXTENDED_SAL_PROC ExtendedSalProc, + IN BOOLEAN VirtualMode, + IN ESAL_VARIABLE_GLOBAL *Global + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + SAL_RETURN_REGS ReturnVal; + + switch (FunctionId) { + case EsalGetVariable: + ReturnVal.Status = GetVariable ( + (CHAR16 *) Arg2, + (EFI_GUID *) Arg3, + (UINT32 *) Arg4, + (UINTN *) Arg5, + (VOID *) Arg6, + &Global->VariableGlobal[VirtualMode], + Global->FvbInstance + ); + return ReturnVal; + + case EsalGetNextVariableName: + ReturnVal.Status = GetNextVariableName ( + (UINTN *) Arg2, + (CHAR16 *) Arg3, + (EFI_GUID *) Arg4, + &Global->VariableGlobal[VirtualMode], + Global->FvbInstance + ); + return ReturnVal; + + case EsalSetVariable: + ReturnVal.Status = SetVariable ( + (CHAR16 *) Arg2, + (EFI_GUID *) Arg3, + (UINT32) Arg4, + (UINTN) Arg5, + (VOID *) Arg6, + &Global->VariableGlobal[VirtualMode], + (UINTN *) &Global->VolatileLastVariableOffset, + (UINTN *) &Global->NonVolatileLastVariableOffset, + Global->FvbInstance + ); + return ReturnVal; + + case EsalQueryVariableInfo: + ReturnVal.Status = QueryVariableInfo ( + (UINT32) Arg2, + (UINT64 *) Arg3, + (UINT64 *) Arg4, + (UINT64 *) Arg5, + &Global->VariableGlobal[VirtualMode], + Global->FvbInstance + ); + return ReturnVal; + + default: + ReturnVal.Status = EFI_SAL_INVALID_ARGUMENT; + return ReturnVal; + } +} + + +VOID +VariableClassAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + CopyMem ( + &mVariableModuleGlobal->VariableGlobal[Virtual], + &mVariableModuleGlobal->VariableGlobal[Physical], + sizeof (VARIABLE_GLOBAL) + ); + + EfiConvertPointer ( + 0x0, + (VOID **) &mVariableModuleGlobal->VariableGlobal[Virtual].NonVolatileVariableBase + ); + EfiConvertPointer ( + 0x0, + (VOID **) &mVariableModuleGlobal->VariableGlobal[Virtual].VolatileVariableBase + ); + EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal); +} + +EFI_STATUS +VariableServiceInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + +Arguments: + +Returns: + +--*/ +{ + EFI_STATUS Status; + + Status = VariableCommonInitialize (ImageHandle, SystemTable); + ASSERT_EFI_ERROR (Status); + + // + // Register All the Functions with Extended Sal. + // + RegisterEsalClass ( + &gEfiExtendedSalVariableServicesProtocolGuid, + mVariableModuleGlobal, + EsalVariableCommonEntry, + EsalGetVariable, + EsalVariableCommonEntry, + EsalGetNextVariableName, + EsalVariableCommonEntry, + EsalSetVariable, + EsalVariableCommonEntry, + EsalQueryVariableInfo, + NULL + ); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/EmuVariableRuntimeDxe/Variable.h b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/Variable.h new file mode 100644 index 0000000000..1e445c564b --- /dev/null +++ b/MdeModulePkg/Universal/EmuVariableRuntimeDxe/Variable.h @@ -0,0 +1,171 @@ +/*++ + +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + Variable.h + +Abstract: + +--*/ + +#ifndef _VARIABLE_H +#define _VARIABLE_H + +// +// Statements that include other header files +// +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include + +// +// BugBug: We need relcate the head file. +// +#include + +#define VARIABLE_STORE_SIZE (64 * 1024) +#define SCRATCH_SIZE (4 * 1024) + +// +// Define GET_PAD_SIZE to optimize compiler +// +#if ((ALIGNMENT == 0) || (ALIGNMENT == 1)) +#define GET_PAD_SIZE(a) (0) +#else +#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1)) +#endif + +#define GET_VARIABLE_NAME_PTR(a) (CHAR16 *) ((UINTN) (a) + sizeof (VARIABLE_HEADER)) + +typedef enum { + Physical, + Virtual +} VARIABLE_POINTER_TYPE; + +typedef struct { + VARIABLE_HEADER *CurrPtr; + VARIABLE_HEADER *EndPtr; + VARIABLE_HEADER *StartPtr; + BOOLEAN Volatile; +} VARIABLE_POINTER_TRACK; + +typedef struct { + EFI_PHYSICAL_ADDRESS VolatileVariableBase; + EFI_PHYSICAL_ADDRESS NonVolatileVariableBase; + EFI_LOCK VariableServicesLock; +} VARIABLE_GLOBAL; + +typedef struct { + VARIABLE_GLOBAL VariableGlobal[2]; + UINTN VolatileLastVariableOffset; + UINTN NonVolatileLastVariableOffset; + UINT32 FvbInstance; +} ESAL_VARIABLE_GLOBAL; + +extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal; + +// +// Functions +// +EFI_STATUS +EFIAPI +VariableCommonInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +EFI_STATUS +EFIAPI +VariableServiceInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +VOID +EFIAPI +VariableClassAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +; + +EFI_STATUS +EFIAPI +GetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID * VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data, + IN VARIABLE_GLOBAL * Global, + IN UINT32 Instance + ) +; + +EFI_STATUS +EFIAPI +GetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid, + IN VARIABLE_GLOBAL *Global, + IN UINT32 Instance + ) +; + +EFI_STATUS +EFIAPI +SetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data, + IN VARIABLE_GLOBAL *Global, + IN UINTN *VolatileOffset, + IN UINTN *NonVolatileOffset, + IN UINT32 Instance + ) +; + +EFI_STATUS +EFIAPI +QueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize, + IN VARIABLE_GLOBAL *Global, + IN UINT32 Instance + ) +; + +#endif