From 8d3a5c82a408c6a7c4c8aa96d0be6c99b8070ac5 Mon Sep 17 00:00:00 2001 From: yshang1 Date: Thu, 19 Jul 2007 10:09:07 +0000 Subject: [PATCH] Move VariablePei/VariableDxe/EmuVarible to /Variable folder of MdeModulePkg. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3370 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/MdeModulePkg.dsc | 9 +- .../Variable/EmuRuntimeDxe/EmuVariable.c | 849 ++++++++++ .../Variable/EmuRuntimeDxe/EmuVariable.msa | 75 + .../EmuRuntimeDxe/EmuVariableRuntimeDxe.inf | 106 ++ .../Variable/EmuRuntimeDxe/InitVariable.c | 214 +++ .../Variable/EmuRuntimeDxe/Variable.h | 171 ++ .../Variable/Pei/Ipf/VariableWorker.c | 57 + .../Universal/Variable/Pei/Variable.c | 522 ++++++ .../Universal/Variable/Pei/Variable.dxs | 32 + .../Universal/Variable/Pei/Variable.h | 193 +++ .../Universal/Variable/Pei/Variable.msa | 76 + .../Universal/Variable/Pei/VariablePei.inf | 69 + .../Universal/Variable/Pei/VariableWorker.c | 63 + .../Variable/RuntimeDxe/InitVariable.c | 229 +++ .../Universal/Variable/RuntimeDxe/Variable.c | 1477 +++++++++++++++++ .../Universal/Variable/RuntimeDxe/Variable.h | 175 ++ .../Variable/RuntimeDxe/Variable.msa | 108 ++ .../RuntimeDxe/VariableRuntimeDxe.inf | 74 + .../Universal/Variable/RuntimeDxe/reclaim.c | 242 +++ Nt32Pkg/Nt32Pkg.dsc | 4 +- Nt32Pkg/Nt32Pkg.fdf | 4 +- 21 files changed, 4740 insertions(+), 9 deletions(-) create mode 100644 MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariable.c create mode 100644 MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariable.msa create mode 100644 MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf create mode 100644 MdeModulePkg/Universal/Variable/EmuRuntimeDxe/InitVariable.c create mode 100644 MdeModulePkg/Universal/Variable/EmuRuntimeDxe/Variable.h create mode 100644 MdeModulePkg/Universal/Variable/Pei/Ipf/VariableWorker.c create mode 100644 MdeModulePkg/Universal/Variable/Pei/Variable.c create mode 100644 MdeModulePkg/Universal/Variable/Pei/Variable.dxs create mode 100644 MdeModulePkg/Universal/Variable/Pei/Variable.h create mode 100644 MdeModulePkg/Universal/Variable/Pei/Variable.msa create mode 100644 MdeModulePkg/Universal/Variable/Pei/VariablePei.inf create mode 100644 MdeModulePkg/Universal/Variable/Pei/VariableWorker.c create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/InitVariable.c create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.msa create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/reclaim.c diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index f9cb7fb454..46221b7c4a 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -412,7 +412,6 @@ $(WORKSPACE)/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf $(WORKSPACE)/MdeModulePkg/Universal/WatchDogTimerDxe/WatchDogTimer.inf - $(WORKSPACE)/MdeModulePkg/Universal/VariablePei/VariablePei.inf $(WORKSPACE)/MdeModulePkg/Universal/DebugPortDxe/DebugPortDxe.inf $(WORKSPACE)/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf $(WORKSPACE)/MdeModulePkg/Universal/PCD/Pei/Pcd.inf @@ -429,10 +428,12 @@ $(WORKSPACE)/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf $(WORKSPACE)/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf + $(WORKSPACE)/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf + $(WORKSPACE)/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf + $(WORKSPACE)/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf + [Components.Ia32] $(WORKSPACE)/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf - $(WORKSPACE)/MdeModulePkg/Universal/VariableRuntimeDxe/VariableRuntimeDxe.inf - $(WORKSPACE)/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableRuntimeDxe.inf $(WORKSPACE)/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf $(WORKSPACE)/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf $(WORKSPACE)/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf @@ -440,8 +441,6 @@ [Components.X64] $(WORKSPACE)/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf - $(WORKSPACE)/MdeModulePkg/Universal/VariableRuntimeDxe/Variable.inf - $(WORKSPACE)/MdeModulePkg/Universal/EmuVariableRuntimeDxe/EmuVariableRuntimeDxe.inf $(WORKSPACE)/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf $(WORKSPACE)/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf $(WORKSPACE)/MdeModulePkg/Universal/DebugSupportDxe/DebugSupport.inf diff --git a/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariable.c b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariable.c new file mode 100644 index 0000000000..f56cf04215 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/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/Variable/EmuRuntimeDxe/EmuVariable.msa b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariable.msa new file mode 100644 index 0000000000..6e769aa280 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/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/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf new file mode 100644 index 0000000000..acd3b15b9e --- /dev/null +++ b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf @@ -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 = EmuVariableRuntimeDxe + 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/Variable/EmuRuntimeDxe/InitVariable.c b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/InitVariable.c new file mode 100644 index 0000000000..efff41c253 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/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/Variable/EmuRuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/Variable.h new file mode 100644 index 0000000000..1e445c564b --- /dev/null +++ b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/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 diff --git a/MdeModulePkg/Universal/Variable/Pei/Ipf/VariableWorker.c b/MdeModulePkg/Universal/Variable/Pei/Ipf/VariableWorker.c new file mode 100644 index 0000000000..0a4ee95774 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/Pei/Ipf/VariableWorker.c @@ -0,0 +1,57 @@ +/** @file + Variable worker functions. + + Copyright (c) 2006, 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. + +**/ + +#include + + +/** + Get one variable by the index count. + + @param IndexTable The pointer to variable index table. + @param Count The index count of variable in index table. + + @return The pointer to variable header indexed by count. + +**/ +VARIABLE_HEADER * +GetVariableByIndex ( + IN VARIABLE_INDEX_TABLE *IndexTable, + IN UINT32 Count + ) +{ + return (VARIABLE_HEADER *) (UINTN) ((((UINT32)IndexTable->Index[Count]) << 2) + ((UINT32)(UINTN)IndexTable->StartPtr & 0xFFFC0000) ); +} + +/** + Record Variable in VariableIndex HOB. + + Record Variable in VariableIndex HOB and update the length of variable index table. + + @param IndexTable The pointer to variable index table. + @param Variable The pointer to the variable that will be recorded. + + @retval VOID + +**/ +VOID +VariableIndexTableUpdate ( + IN OUT VARIABLE_INDEX_TABLE *IndexTable, + IN VARIABLE_HEADER *Variable + ) +{ + IndexTable->Index[IndexTable->Length++] = (UINT16) (((UINT32)(UINTN) Variable) >> 2); + + return; +} + diff --git a/MdeModulePkg/Universal/Variable/Pei/Variable.c b/MdeModulePkg/Universal/Variable/Pei/Variable.c new file mode 100644 index 0000000000..ba8a23d67a --- /dev/null +++ b/MdeModulePkg/Universal/Variable/Pei/Variable.c @@ -0,0 +1,522 @@ +/*++ + +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.c + +Abstract: + + Framework PEIM to provide the Variable functionality + +--*/ + + +#include "Variable.h" + +// +// Module globals +// +static EFI_PEI_READ_ONLY_VARIABLE2_PPI mVariablePpi = { + PeiGetVariable, + PeiGetNextVariableName +}; + +static EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiReadOnlyVariable2PpiGuid, + &mVariablePpi +}; + +EFI_GUID mEfiVariableIndexTableGuid = EFI_VARIABLE_INDEX_TABLE_GUID; + +EFI_STATUS +EFIAPI +PeimInitializeVariableServices ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +/*++ + +Routine Description: + + Provide the functionality of the variable services. + +Arguments: + + FfsHeadher - The FFS file header + PeiServices - General purpose services available to every PEIM. + +Returns: + + Status - EFI_SUCCESS if the interface could be successfully + installed + +--*/ +{ + // + // Publish the variable capability to other modules + // + return (**PeiServices).InstallPpi (PeiServices, &mPpiListVariable); + +} + +STATIC +VARIABLE_HEADER * +GetNextVariablePtr ( + IN VARIABLE_HEADER *Variable + ) +/*++ + +Routine Description: + + This code checks if variable header is valid or not. + +Arguments: + Variable Pointer to the Variable Header. + +Returns: + TRUE Variable header is valid. + FALSE Variable header is not valid. + +--*/ +{ + return (VARIABLE_HEADER *) ((UINTN) GET_VARIABLE_DATA_PTR (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize)); +} + +STATIC +BOOLEAN +EFIAPI +IsValidVariableHeader ( + IN VARIABLE_HEADER *Variable + ) +/*++ + +Routine Description: + + This code checks if variable header is valid or not. + +Arguments: + Variable Pointer to the Variable Header. + +Returns: + TRUE Variable header is valid. + FALSE Variable header is not valid. + +--*/ +{ + if (Variable == NULL || + Variable->StartId != VARIABLE_DATA || + (sizeof (VARIABLE_HEADER) + Variable->DataSize + Variable->NameSize) > MAX_VARIABLE_SIZE + ) { + return FALSE; + } + + return TRUE; +} + +STATIC +VARIABLE_STORE_STATUS +EFIAPI +GetVariableStoreStatus ( + IN VARIABLE_STORE_HEADER *VarStoreHeader + ) +/*++ + +Routine Description: + + This code gets the pointer to the variable name. + +Arguments: + + VarStoreHeader Pointer to the Variable Store Header. + +Returns: + + EfiRaw Variable store is raw + EfiValid Variable store is valid + EfiInvalid Variable store is invalid + +--*/ +{ + if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE && + VarStoreHeader->Format == VARIABLE_STORE_FORMATTED && + VarStoreHeader->State == VARIABLE_STORE_HEALTHY + ) { + + return EfiValid; + } + + if (VarStoreHeader->Signature == 0xffffffff && + VarStoreHeader->Size == 0xffffffff && + VarStoreHeader->Format == 0xff && + VarStoreHeader->State == 0xff + ) { + + return EfiRaw; + } else { + return EfiInvalid; + } +} + +STATIC +EFI_STATUS +CompareWithValidVariable ( + IN VARIABLE_HEADER *Variable, + IN CONST CHAR16 *VariableName, + IN CONST EFI_GUID *VendorGuid, + OUT VARIABLE_POINTER_TRACK *PtrTrack + ) +/*++ + +Routine Description: + + This function compares a variable with variable entries in database + +Arguments: + + Variable - Pointer to the variable in our database + VariableName - Name of the variable to compare to 'Variable' + VendorGuid - GUID of the variable to compare to 'Variable' + PtrTrack - Variable Track Pointer structure that contains + Variable Information. + +Returns: + + EFI_SUCCESS - Found match variable + EFI_NOT_FOUND - Variable not found + +--*/ +{ + if (VariableName[0] == 0) { + PtrTrack->CurrPtr = Variable; + return EFI_SUCCESS; + } else { + // + // Don't use CompareGuid function here for performance reasons. + // Instead we compare the GUID a UINT32 at a time and branch + // on the first failed comparison. + // + if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &Variable->VendorGuid)[0]) && + (((INT32 *) VendorGuid)[1] == ((INT32 *) &Variable->VendorGuid)[1]) && + (((INT32 *) VendorGuid)[2] == ((INT32 *) &Variable->VendorGuid)[2]) && + (((INT32 *) VendorGuid)[3] == ((INT32 *) &Variable->VendorGuid)[3]) + ) { + if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable), Variable->NameSize)) { + PtrTrack->CurrPtr = Variable; + return EFI_SUCCESS; + } + } + } + + return EFI_NOT_FOUND; +} + +STATIC +EFI_STATUS +EFIAPI +FindVariable ( + IN EFI_PEI_SERVICES **PeiServices, + IN CONST CHAR16 *VariableName, + IN CONST EFI_GUID *VendorGuid, + OUT VARIABLE_POINTER_TRACK *PtrTrack + ) +/*++ + +Routine Description: + + This code finds variable in storage blocks (Non-Volatile) + +Arguments: + + PeiServices - General purpose services available to every PEIM. + VariableName - Name of the variable to be found + VendorGuid - Vendor GUID to be found. + PtrTrack - Variable Track Pointer structure that contains + Variable Information. + +Returns: + + EFI_SUCCESS - Variable found successfully + EFI_NOT_FOUND - Variable not found + EFI_INVALID_PARAMETER - Invalid variable name + +--*/ +{ + EFI_HOB_GUID_TYPE *GuidHob; + VARIABLE_STORE_HEADER *VariableStoreHeader; + VARIABLE_HEADER *Variable; + VARIABLE_HEADER *MaxIndex; + VARIABLE_INDEX_TABLE *IndexTable; + UINT32 Count; + UINT8 *VariableBase; + + if (VariableName != 0 && VendorGuid == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // No Variable Address equals zero, so 0 as initial value is safe. + // + MaxIndex = 0; + + GuidHob = GetFirstGuidHob (&mEfiVariableIndexTableGuid); + if (GuidHob == NULL) { + IndexTable = BuildGuidHob (&mEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE)); + IndexTable->Length = 0; + IndexTable->StartPtr = NULL; + IndexTable->EndPtr = NULL; + IndexTable->GoneThrough = 0; + } else { + IndexTable = GET_GUID_HOB_DATA (GuidHob); + for (Count = 0; Count < IndexTable->Length; Count++) + { + MaxIndex = GetVariableByIndex (IndexTable, Count); + + if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) { + PtrTrack->StartPtr = IndexTable->StartPtr; + PtrTrack->EndPtr = IndexTable->EndPtr; + + return EFI_SUCCESS; + } + } + + if (IndexTable->GoneThrough) { + return EFI_NOT_FOUND; + } + } + // + // If not found in HOB, then let's start from the MaxIndex we've found. + // + if (MaxIndex != NULL) { + Variable = GetNextVariablePtr (MaxIndex); + } else { + if (IndexTable->StartPtr || IndexTable->EndPtr) { + Variable = IndexTable->StartPtr; + } else { + VariableBase = (UINT8 *) (UINTN) PcdGet32 (PcdFlashNvStorageVariableBase); + VariableStoreHeader = (VARIABLE_STORE_HEADER *) (VariableBase + \ + ((EFI_FIRMWARE_VOLUME_HEADER *) (VariableBase)) -> HeaderLength); + + if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) { + return EFI_UNSUPPORTED; + } + + if (~VariableStoreHeader->Size == 0) { + return EFI_NOT_FOUND; + } + // + // Find the variable by walk through non-volatile variable store + // + IndexTable->StartPtr = (VARIABLE_HEADER *) (VariableStoreHeader + 1); + IndexTable->EndPtr = (VARIABLE_HEADER *) ((UINTN) VariableStoreHeader + VariableStoreHeader->Size); + + // + // Start Pointers for the variable. + // Actual Data Pointer where data can be written. + // + Variable = IndexTable->StartPtr; + } + } + // + // Find the variable by walk through non-volatile variable store + // + PtrTrack->StartPtr = IndexTable->StartPtr; + PtrTrack->EndPtr = IndexTable->EndPtr; + + while (IsValidVariableHeader (Variable) && (Variable <= IndexTable->EndPtr)) { + if (Variable->State == VAR_ADDED) { + // + // Record Variable in VariableIndex HOB + // + if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) + { + VariableIndexTableUpdate (IndexTable, Variable); + } + + if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) { + return EFI_SUCCESS; + } + } + + Variable = GetNextVariablePtr (Variable); + } + // + // If gone through the VariableStore, that means we never find in Firmware any more. + // + if (IndexTable->Length < VARIABLE_INDEX_TABLE_VOLUME) { + IndexTable->GoneThrough = 1; + } + + PtrTrack->CurrPtr = NULL; + + return EFI_NOT_FOUND; +} + +EFI_STATUS +EFIAPI +PeiGetVariable ( + IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This, + IN CONST CHAR16 *VariableName, + IN CONST EFI_GUID *VariableGuid, + OUT UINT32 *Attributes, + IN OUT UINTN *DataSize, + OUT VOID *Data + ) +/*++ + +Routine Description: + + Provide the read variable functionality of the variable services. + +Arguments: + + PeiServices - General purpose services available to every PEIM. + + VariableName - The variable name + + VendorGuid - The vendor's GUID + + Attributes - Pointer to the attribute + + DataSize - Size of data + + Data - Pointer to data + +Returns: + + EFI_SUCCESS - The interface could be successfully installed + + EFI_NOT_FOUND - The variable could not be discovered + + EFI_BUFFER_TOO_SMALL - The caller buffer is not large enough + +--*/ +{ + VARIABLE_POINTER_TRACK Variable; + UINTN VarDataSize; + EFI_STATUS Status; + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer (); + if (VariableName == NULL || VariableGuid == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Find existing variable + // + Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable); + if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) { + return Status; + } + // + // Get data size + // + VarDataSize = Variable.CurrPtr->DataSize; + if (*DataSize >= VarDataSize) { + (*PeiServices)->CopyMem (Data, GET_VARIABLE_DATA_PTR (Variable.CurrPtr), VarDataSize); + + if (Attributes != NULL) { + *Attributes = Variable.CurrPtr->Attributes; + } + + *DataSize = VarDataSize; + return EFI_SUCCESS; + } else { + *DataSize = VarDataSize; + return EFI_BUFFER_TOO_SMALL; + } +} + +EFI_STATUS +EFIAPI +PeiGetNextVariableName ( + IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This, + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VariableGuid + ) +/*++ + +Routine Description: + + Provide the get next variable functionality of the variable services. + +Arguments: + + PeiServices - General purpose services available to every PEIM. + VariabvleNameSize - The variable name's size. + VariableName - A pointer to the variable's name. + VariableGuid - A pointer to the EFI_GUID structure. + + VariableNameSize - Size of the variable name + + VariableName - The variable name + + VendorGuid - The vendor's GUID + +Returns: + + EFI_SUCCESS - The interface could be successfully installed + + EFI_NOT_FOUND - The variable could not be discovered + +--*/ +{ + VARIABLE_POINTER_TRACK Variable; + UINTN VarNameSize; + EFI_STATUS Status; + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer (); + if (VariableName == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = FindVariable (PeiServices, VariableName, VariableGuid, &Variable); + if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) { + return Status; + } + + if (VariableName[0] != 0) { + // + // If variable name is not NULL, get next variable + // + Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr); + } + + while (!(Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL)) { + if (IsValidVariableHeader (Variable.CurrPtr)) { + if (Variable.CurrPtr->State == VAR_ADDED) { + VarNameSize = (UINTN) Variable.CurrPtr->NameSize; + if (VarNameSize <= *VariableNameSize) { + (*PeiServices)->CopyMem (VariableName, GET_VARIABLE_NAME_PTR (Variable.CurrPtr), VarNameSize); + + (*PeiServices)->CopyMem (VariableGuid, &Variable.CurrPtr->VendorGuid, sizeof (EFI_GUID)); + + Status = EFI_SUCCESS; + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + + *VariableNameSize = VarNameSize; + return Status; + // + // Variable is found + // + } else { + Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr); + } + } else { + break; + } + } + + return EFI_NOT_FOUND; +} diff --git a/MdeModulePkg/Universal/Variable/Pei/Variable.dxs b/MdeModulePkg/Universal/Variable/Pei/Variable.dxs new file mode 100644 index 0000000000..8c2255a446 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/Pei/Variable.dxs @@ -0,0 +1,32 @@ +/*++ + +Copyright (c) 2006, 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.dxs + +Abstract: + + Dependency expression file for Variable PEIM. + +--*/ +// +// Include common header file for this module. +// +#include "CommonHeader.h" + +#include + +DEPENDENCY_START + TRUE +DEPENDENCY_END + + diff --git a/MdeModulePkg/Universal/Variable/Pei/Variable.h b/MdeModulePkg/Universal/Variable/Pei/Variable.h new file mode 100644 index 0000000000..9747a8d426 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/Pei/Variable.h @@ -0,0 +1,193 @@ +/*++ + +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: + + Tiano PEIM to provide the variable functionality + +--*/ + +#ifndef _PEI_VARIABLE_H +#define _PEI_VARIABLE_H + +#include +#include +#include +#include +#include +#include +#include +#include + + +// +// BugBug: We need relcate the head file. +// +#include + +// +// 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)) + +#define GET_VARIABLE_DATA_PTR(a) \ + (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (a) + (a)->NameSize + GET_PAD_SIZE ((a)->NameSize)) + +typedef struct { + VARIABLE_HEADER *CurrPtr; + VARIABLE_HEADER *EndPtr; + VARIABLE_HEADER *StartPtr; +} VARIABLE_POINTER_TRACK; + +#define VARIABLE_INDEX_TABLE_VOLUME 122 + +#define EFI_VARIABLE_INDEX_TABLE_GUID \ + { 0x8cfdb8c8, 0xd6b2, 0x40f3, { 0x8e, 0x97, 0x02, 0x30, 0x7c, 0xc9, 0x8b, 0x7c } } + +typedef struct { + UINT16 Length; + UINT16 GoneThrough; + VARIABLE_HEADER *EndPtr; + VARIABLE_HEADER *StartPtr; + UINT16 Index[VARIABLE_INDEX_TABLE_VOLUME]; +} VARIABLE_INDEX_TABLE; + + +// +// Functions +// +EFI_STATUS +EFIAPI +PeimInitializeVariableServices ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + FfsHeader - TODO: add argument description + PeiServices - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PeiGetVariable ( + IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This, + IN CONST CHAR16 *VariableName, + IN CONST EFI_GUID *VariableGuid, + OUT UINT32 *Attributes, + IN OUT UINTN *DataSize, + OUT VOID *Data + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PeiServices - TODO: add argument description + VariableName - TODO: add argument description + VendorGuid - TODO: add argument description + Attributes - TODO: add argument description + DataSize - TODO: add argument description + Data - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +PeiGetNextVariableName ( + IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This, + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VariableGuid + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PeiServices - TODO: add argument description + VariableNameSize - TODO: add argument description + VariableName - TODO: add argument description + VendorGuid - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +/** + Get one variable by the index count. + + @param IndexTable The pointer to variable index table. + @param Count The index count of variable in index table. + + @return The pointer to variable header indexed by count. + +**/ +VARIABLE_HEADER * +GetVariableByIndex ( + IN VARIABLE_INDEX_TABLE *IndexTable, + IN UINT32 Count + ); + +/** + Record Variable in VariableIndex HOB. + + Record Variable in VariableIndex HOB and update the length of variable index table. + + @param IndexTable The pointer to variable index table. + @param Variable The pointer to the variable that will be recorded. + + @retval VOID + +**/ +VOID +VariableIndexTableUpdate ( + IN OUT VARIABLE_INDEX_TABLE *IndexTable, + IN VARIABLE_HEADER *Variable + ); + +#endif // _PEI_VARIABLE_H diff --git a/MdeModulePkg/Universal/Variable/Pei/Variable.msa b/MdeModulePkg/Universal/Variable/Pei/Variable.msa new file mode 100644 index 0000000000..565ae31a13 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/Pei/Variable.msa @@ -0,0 +1,76 @@ + + + + PeiVariable + PEIM + 34C8C28F-B61C-45a2-8F2E-89E46BECC63B + 1.0 + Component description file for PeiVariable module. + Framework PEIM to provide the Variable functionality. + 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 IPF EBC + false + PeiVariable + + + + DebugLib + + + PeimEntryPoint + + + HobLib + + + PcdLib + + + BaseMemoryLib + + + + Variable.h + Variable.c + Variable.dxs + VariableWorker.c + Ipf/VariableWorker.c + Ia32/VarMachine.h + Ebc/VarMachine.h + x64/VarMachine.h + Ipf/VarMachine.h + + + + + + + + gEfiPeiReadOnlyVariablePpiGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + PeimInitializeVariableServices + + + + + PcdFlashNvStorageVariableBase + gEfiGenericPlatformTokenSpaceGuid + The driver gets the Variable store base address from this PCD. This base address point to + an EFI_FIRMWARE_VOLUMN_HEADER struct. + + + \ No newline at end of file diff --git a/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf b/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf new file mode 100644 index 0000000000..72a6b796fe --- /dev/null +++ b/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf @@ -0,0 +1,69 @@ +#/** @file +# Component description file for PeiVariable module. +# +# Framework PEIM to provide the Variable functionality. +# 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] + INF_VERSION = 0x00010005 + BASE_NAME = PeiVariable + FILE_GUID = 34C8C28F-B61C-45a2-8F2E-89E46BECC63B + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = PeimInitializeVariableServices + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.common] + Variable.c + Variable.h + +[Sources.Ia32] + VariableWorker.c + +[Sources.X64] + VariableWorker.c + +[Sources.IPF] + Ipf/VariableWorker.c + +[Sources.EBC] + VariableWorker.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseMemoryLib + PcdLib + HobLib + PeimEntryPoint + DebugLib + PeiServiceTablePointerLib + +[Ppis] + gEfiPeiReadOnlyVariable2PpiGuid # PPI ALWAYS_CONSUMED + +[PcdsDynamic.common] + PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid + +[Depex] + TRUE diff --git a/MdeModulePkg/Universal/Variable/Pei/VariableWorker.c b/MdeModulePkg/Universal/Variable/Pei/VariableWorker.c new file mode 100644 index 0000000000..1a49ee8c98 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/Pei/VariableWorker.c @@ -0,0 +1,63 @@ +/*++ + +Copyright (c) 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: + + VariableWorker.c + +Abstract: + + Framework PEIM to provide the Variable functionality + +--*/ + +#include + +/** + Get one variable by the index count. + + @param IndexTable The pointer to variable index table. + @param Count The index count of variable in index table. + + @return The pointer to variable header indexed by count. + +**/ +VARIABLE_HEADER * +GetVariableByIndex ( + IN VARIABLE_INDEX_TABLE *IndexTable, + IN UINT32 Count + ) +{ + return (VARIABLE_HEADER *) (UINTN) (IndexTable->Index[Count] + ((UINTN) IndexTable->StartPtr & 0xFFFF0000)); +} + +/** + Record Variable in VariableIndex HOB. + + Record Variable in VariableIndex HOB and update the length of variable index table. + + @param IndexTable The pointer to variable index table. + @param Variable The pointer to the variable that will be recorded. + + @retval VOID + +**/ +VOID +VariableIndexTableUpdate ( + IN OUT VARIABLE_INDEX_TABLE *IndexTable, + IN VARIABLE_HEADER *Variable + ) +{ + IndexTable->Index[IndexTable->Length++] = (UINT16) (UINTN) Variable; + + return; +} + diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/InitVariable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/InitVariable.c new file mode 100644 index 0000000000..59403e91e7 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/InitVariable.c @@ -0,0 +1,229 @@ +/*++ + +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" + +// +// Event for Exit Boot Services Callback +// +STATIC EFI_EVENT mExitBootServicesEvent = NULL; + + +// +// 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); + + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_NOTIFY, + VariableClassAddressChangeEvent, + NULL, + &mExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c new file mode 100644 index 0000000000..784a1987a8 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -0,0 +1,1477 @@ +/*++ + +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.c + +Abstract: + +Revision History + +--*/ + + +#include "Variable.h" +#include + +// +// 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 +BOOLEAN +EFIAPI +IsValidVariableHeader ( + IN VARIABLE_HEADER *Variable + ) +/*++ + +Routine Description: + + This code checks if variable header is valid or not. + +Arguments: + Variable Pointer to the Variable Header. + +Returns: + TRUE Variable header is valid. + FALSE Variable header is not valid. + +--*/ +{ + if (Variable == NULL || + Variable->StartId != VARIABLE_DATA || + (sizeof (VARIABLE_HEADER) + Variable->NameSize + Variable->DataSize) > MAX_VARIABLE_SIZE + ) { + return FALSE; + } + + return TRUE; +} + +STATIC +EFI_STATUS +EFIAPI +UpdateVariableStore ( + IN VARIABLE_GLOBAL *Global, + IN BOOLEAN Volatile, + IN BOOLEAN SetByIndex, + IN UINTN Instance, + IN UINTN DataPtrIndex, + IN UINT32 DataSize, + IN UINT8 *Buffer + ) +/*++ + +Routine Description: + + This function writes data to the FWH at the correct LBA even if the LBAs + are fragmented. + +Arguments: + + Global Pointer to VARAIBLE_GLOBAL structure + Volatile If the Variable is Volatile or Non-Volatile + SetByIndex TRUE: Target pointer is given as index + FALSE: Target pointer is absolute + Instance Instance of FV Block services + DataPtrIndex Pointer to the Data from the end of VARIABLE_STORE_HEADER + structure + DataSize Size of data to be written. + Buffer Pointer to the buffer from which data is written + +Returns: + + EFI STATUS + +--*/ +{ + EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; + UINTN BlockIndex2; + UINTN LinearOffset; + UINTN CurrWriteSize; + UINTN CurrWritePtr; + UINT8 *CurrBuffer; + EFI_LBA LbaNumber; + UINTN Size; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + VARIABLE_STORE_HEADER *VolatileBase; + EFI_PHYSICAL_ADDRESS FvVolHdr; + EFI_PHYSICAL_ADDRESS DataPtr; + EFI_STATUS Status; + + FwVolHeader = NULL; + DataPtr = DataPtrIndex; + + // + // Check if the Data is Volatile + // + if (!Volatile) { + EfiFvbGetPhysicalAddress (Instance, &FvVolHdr); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvVolHdr); + // + // Data Pointer should point to the actual Address where data is to be + // written + // + if (SetByIndex) { + DataPtr += Global->NonVolatileVariableBase; + } + + if ((DataPtr + DataSize) >= ((EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) FwVolHeader + FwVolHeader->FvLength))) { + return EFI_INVALID_PARAMETER; + } + } else { + // + // Data Pointer should point to the actual Address where data is to be + // written + // + VolatileBase = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase); + if (SetByIndex) { + DataPtr += Global->VolatileVariableBase; + } + + if ((DataPtr + DataSize) >= ((UINTN) ((UINT8 *) VolatileBase + VolatileBase->Size))) { + return EFI_INVALID_PARAMETER; + } + } + // + // If Volatile Variable just do a simple mem copy. + // + if (Volatile) { + CopyMem ((UINT8 *) ((UINTN) DataPtr), Buffer, DataSize); + return EFI_SUCCESS; + } + // + // If we are here we are dealing with Non-Volatile Variables + // + LinearOffset = (UINTN) FwVolHeader; + CurrWritePtr = (UINTN) DataPtr; + CurrWriteSize = DataSize; + CurrBuffer = Buffer; + LbaNumber = 0; + + if (CurrWritePtr < LinearOffset) { + return EFI_INVALID_PARAMETER; + } + + for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) { + for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) { + // + // Check to see if the Variable Writes are spanning through multiple + // blocks. + // + if ((CurrWritePtr >= LinearOffset) && (CurrWritePtr < LinearOffset + PtrBlockMapEntry->Length)) { + if ((CurrWritePtr + CurrWriteSize) <= (LinearOffset + PtrBlockMapEntry->Length)) { + Status = EfiFvbWriteBlock ( + Instance, + LbaNumber, + (UINTN) (CurrWritePtr - LinearOffset), + &CurrWriteSize, + CurrBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + Size = (UINT32) (LinearOffset + PtrBlockMapEntry->Length - CurrWritePtr); + Status = EfiFvbWriteBlock ( + Instance, + LbaNumber, + (UINTN) (CurrWritePtr - LinearOffset), + &Size, + CurrBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + CurrWritePtr = LinearOffset + PtrBlockMapEntry->Length; + CurrBuffer = CurrBuffer + Size; + CurrWriteSize = CurrWriteSize - Size; + } + } + + LinearOffset += PtrBlockMapEntry->Length; + LbaNumber++; + } + } + + return EFI_SUCCESS; +} + +STATIC +VARIABLE_STORE_STATUS +EFIAPI +GetVariableStoreStatus ( + IN VARIABLE_STORE_HEADER *VarStoreHeader + ) +/*++ + +Routine Description: + + This code gets the current status of Variable Store. + +Arguments: + + VarStoreHeader Pointer to the Variable Store Header. + +Returns: + + EfiRaw Variable store status is raw + EfiValid Variable store status is valid + EfiInvalid Variable store status is invalid + +--*/ +{ + if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE && + VarStoreHeader->Format == VARIABLE_STORE_FORMATTED && + VarStoreHeader->State == VARIABLE_STORE_HEALTHY + ) { + + return EfiValid; + } else if (VarStoreHeader->Signature == 0xffffffff && + VarStoreHeader->Size == 0xffffffff && + VarStoreHeader->Format == 0xff && + VarStoreHeader->State == 0xff + ) { + + return EfiRaw; + } else { + return EfiInvalid; + } +} + +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 + +--*/ +{ + // + // 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. + +--*/ +{ + if (!IsValidVariableHeader (Variable)) { + return NULL; + } + // + // Be careful about pad size for alignment + // + return (VARIABLE_HEADER *) ((UINTN) GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize)); +} + +STATIC +VARIABLE_HEADER * +EFIAPI +GetEndPointer ( + IN VARIABLE_STORE_HEADER *VarStoreHeader + ) +/*++ + +Routine Description: + + This code gets the pointer to the last variable memory pointer byte + +Arguments: + + VarStoreHeader Pointer to the Variable Store Header. + +Returns: + + VARIABLE_HEADER* Pointer to last unavailable Variable Header + +--*/ +{ + // + // The end of variable store + // + return (VARIABLE_HEADER *) ((UINTN) VarStoreHeader + VarStoreHeader->Size); +} + +STATIC +EFI_STATUS +EFIAPI +Reclaim ( + IN EFI_PHYSICAL_ADDRESS VariableBase, + OUT UINTN *LastVariableOffset, + IN BOOLEAN IsVolatile + ) +/*++ + +Routine Description: + + Variable store garbage collection and reclaim operation + +Arguments: + + VariableBase Base address of variable store + LastVariableOffset Offset of last variable + IsVolatile The variable store is volatile or not, + if it is non-volatile, need FTW + +Returns: + + EFI STATUS + +--*/ +{ + VARIABLE_HEADER *Variable; + VARIABLE_HEADER *NextVariable; + VARIABLE_STORE_HEADER *VariableStoreHeader; + UINT8 *ValidBuffer; + UINTN ValidBufferSize; + UINTN VariableSize; + UINT8 *CurrPtr; + EFI_STATUS Status; + + VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase); + + // + // Start Pointers for the variable. + // + Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1); + + ValidBufferSize = sizeof (VARIABLE_STORE_HEADER); + + while (IsValidVariableHeader (Variable)) { + NextVariable = GetNextVariablePtr (Variable); + if (Variable->State == VAR_ADDED) { + VariableSize = (UINTN) NextVariable - (UINTN) Variable; + ValidBufferSize += VariableSize; + } + + Variable = NextVariable; + } + + ValidBuffer = AllocatePool (ValidBufferSize); + if (ValidBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SetMem (ValidBuffer, ValidBufferSize, 0xff); + + CurrPtr = ValidBuffer; + + // + // Copy variable store header + // + CopyMem (CurrPtr, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER)); + CurrPtr += sizeof (VARIABLE_STORE_HEADER); + + // + // Start Pointers for the variable. + // + Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1); + + while (IsValidVariableHeader (Variable)) { + NextVariable = GetNextVariablePtr (Variable); + if (Variable->State == VAR_ADDED) { + VariableSize = (UINTN) NextVariable - (UINTN) Variable; + CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize); + CurrPtr += VariableSize; + } + + Variable = NextVariable; + } + + if (IsVolatile) { + // + // If volatile variable store, just copy valid buffer + // + SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff); + CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, ValidBufferSize); + *LastVariableOffset = ValidBufferSize; + Status = EFI_SUCCESS; + } else { + // + // If non-volatile variable store, perform FTW here. + // + Status = FtwVariableSpace ( + VariableBase, + ValidBuffer, + ValidBufferSize + ); + if (!EFI_ERROR (Status)) { + *LastVariableOffset = ValidBufferSize; + } + } + + FreePool (ValidBuffer); + + if (EFI_ERROR (Status)) { + *LastVariableOffset = 0; + } + + return Status; +} + +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 (IsValidVariableHeader (Variable[Index]) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) { + if (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]); + } + // + // While (...) + // + } + // + // for (...) + // + 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; + } + + if (VariableName[0] != 0) { + // + // If variable name is not NULL, get next variable + // + Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr); + } + + while (TRUE) { + // + // 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 (!IsValidVariableHeader (Variable.CurrPtr)) { + continue; + } + } + // + // Variable is found + // + if (IsValidVariableHeader (Variable.CurrPtr) && 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; + } + } + + Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr); + } + +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 + EFI_INVALID_PARAMETER - Invalid parameter + EFI_SUCCESS - Set successfully + EFI_OUT_OF_RESOURCES - Resource not enough to set variable + EFI_NOT_FOUND - Not found + +--*/ +{ + VARIABLE_POINTER_TRACK Variable; + EFI_STATUS Status; + VARIABLE_HEADER *NextVariable; + UINTN VarNameSize; + UINTN VarNameOffset; + UINTN VarDataOffset; + UINTN VarSize; + UINT8 State; + BOOLEAN Reclaimed; + + Reclaimed = FALSE; + + 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_NON_VOLATILE) { + // + // Make sure not only EFI_VARIABLE_NON_VOLATILE is set + // + 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)) { + State = Variable.CurrPtr->State; + State &= VAR_DELETED; + + Status = UpdateVariableStore ( + Global, + Variable.Volatile, + FALSE, + Instance, + (UINTN) &Variable.CurrPtr->State, + sizeof (UINT8), + &State + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + 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 + // + State = Variable.CurrPtr->State; + State &= VAR_IN_DELETED_TRANSITION; + + Status = UpdateVariableStore ( + Global, + Variable.Volatile, + FALSE, + Instance, + (UINTN) &Variable.CurrPtr->State, + sizeof (UINT8), + &State + ); + if (EFI_ERROR (Status)) { + goto Done; + } + } + } + // + // Create a new variable and copy the data. + // + // Tricky part: Use scratch data area at the end of volatile variable store + // as a temporary storage. + // + NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase)); + + SetMem (NextVariable, SCRATCH_SIZE, 0xff); + + NextVariable->StartId = VARIABLE_DATA; + NextVariable->Attributes = Attributes; + // + // NextVariable->State = VAR_ADDED; + // + NextVariable->Reserved = 0; + VarNameOffset = sizeof (VARIABLE_HEADER); + VarNameSize = StrSize (VariableName); + CopyMem ( + (UINT8 *) ((UINTN) NextVariable + VarNameOffset), + VariableName, + VarNameSize + ); + VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize); + CopyMem ( + (UINT8 *) ((UINTN) NextVariable + VarDataOffset), + Data, + DataSize + ); + CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID)); + // + // There will be pad bytes after Data, the NextVariable->NameSize and + // NextVariable->DataSize should not include pad size so that variable + // service can get actual size in GetVariable + // + NextVariable->NameSize = (UINT32)VarNameSize; + NextVariable->DataSize = (UINT32)DataSize; + + // + // The actual size of the variable that stores in storage should + // include pad size. + // + VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize); + if (Attributes & EFI_VARIABLE_NON_VOLATILE) { + if ((UINT32) (VarSize +*NonVolatileOffset) > + ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size + ) { + if (EfiAtRuntime ()) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + // + // Perform garbage collection & reclaim operation + // + Status = Reclaim (Global->NonVolatileVariableBase, NonVolatileOffset, FALSE); + if (EFI_ERROR (Status)) { + goto Done; + } + // + // If still no enough space, return out of resources + // + if ((UINT32) (VarSize +*NonVolatileOffset) > + ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size + ) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Reclaimed = TRUE; + } + // + // Three steps + // 1. Write variable header + // 2. Write variable data + // 3. Set variable state to valid + // + // + // Step 1: + // + Status = UpdateVariableStore ( + Global, + FALSE, + TRUE, + Instance, + *NonVolatileOffset, + sizeof (VARIABLE_HEADER), + (UINT8 *) NextVariable + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + // + // Step 2: + // + Status = UpdateVariableStore ( + Global, + FALSE, + TRUE, + Instance, + *NonVolatileOffset + sizeof (VARIABLE_HEADER), + (UINT32) VarSize - sizeof (VARIABLE_HEADER), + (UINT8 *) NextVariable + sizeof (VARIABLE_HEADER) + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + // + // Step 3: + // + NextVariable->State = VAR_ADDED; + Status = UpdateVariableStore ( + Global, + FALSE, + TRUE, + Instance, + *NonVolatileOffset, + sizeof (VARIABLE_HEADER), + (UINT8 *) NextVariable + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + + *NonVolatileOffset = *NonVolatileOffset + VarSize; + + } else { + if (EfiAtRuntime ()) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + if ((UINT32) (VarSize +*VolatileOffset) > + ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size + ) { + // + // Perform garbage collection & reclaim operation + // + Status = Reclaim (Global->VolatileVariableBase, VolatileOffset, TRUE); + if (EFI_ERROR (Status)) { + goto Done; + } + // + // If still no enough space, return out of resources + // + if ((UINT32) (VarSize +*VolatileOffset) > + ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size + ) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Reclaimed = TRUE; + } + + NextVariable->State = VAR_ADDED; + Status = UpdateVariableStore ( + Global, + TRUE, + TRUE, + Instance, + *VolatileOffset, + (UINT32) VarSize, + (UINT8 *) NextVariable + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + + *VolatileOffset = *VolatileOffset + VarSize; + } + // + // Mark the old variable as deleted + // + if (!Reclaimed && !EFI_ERROR (Status) && Variable.CurrPtr != NULL) { + State = Variable.CurrPtr->State; + State &= VAR_DELETED; + + Status = UpdateVariableStore ( + Global, + Variable.Volatile, + FALSE, + Instance, + (UINTN) &Variable.CurrPtr->State, + sizeof (UINT8), + &State + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + } + } + + 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; + } + + 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 (IsValidVariableHeader (Variable) && (Variable < GetEndPointer (VariableStoreHeader))) { + NextVariable = GetNextVariablePtr (Variable); + VariableSize = (UINT64) (UINTN) NextVariable - (UINT64) (UINTN) Variable; + + if (EfiAtRuntime ()) { + // + // we don't take the state of the variables in mind + // when calculating RemainingVariableStorageSize, + // since the space occupied by variables not marked with + // VAR_ADDED is not allowed to be reclaimed in Runtime. + // + *RemainingVariableStorageSize -= VariableSize; + } else { + // + // Only care about Variables with State VAR_ADDED,because + // the space not marked as VAR_ADDED is reclaimable now. + // + if (Variable->State == VAR_ADDED) { + *RemainingVariableStorageSize -= VariableSize; + } + } + + // + // Go to the next one + // + Variable = NextVariable; + } + + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + 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: + + ImageHandle - The firmware allocated handle for the EFI image. + SystemTable - A pointer to the EFI System Table. + +Returns: + + Status code. + + EFI_NOT_FOUND - Variable store area not found. + EFI_UNSUPPORTED - Currently only one non-volatile variable store is supported. + EFI_SUCCESS - Variable services successfully initialized. + +--*/ +{ + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + CHAR8 *CurrPtr; + VARIABLE_STORE_HEADER *VolatileVariableStore; + VARIABLE_STORE_HEADER *VariableStoreHeader; + VARIABLE_HEADER *NextVariable; + UINT32 Instance; + EFI_PHYSICAL_ADDRESS FvVolHdr; + + UINT64 TempVariableStoreHeader; + + EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; + EFI_FLASH_SUBAREA_ENTRY VariableStoreEntry; + UINT64 BaseAddress; + UINT64 Length; + UINTN Index; + UINT8 Data; + + mVariableModuleGlobal = AllocateRuntimePool (sizeof (ESAL_VARIABLE_GLOBAL)); + if (mVariableModuleGlobal == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal[Physical].VariableServicesLock, TPL_NOTIFY); + + // + // Allocate memory for volatile variable store + // + VolatileVariableStore = AllocateRuntimePool (VARIABLE_STORE_SIZE + SCRATCH_SIZE); + if (VolatileVariableStore == NULL) { + FreePool (mVariableModuleGlobal); + return EFI_OUT_OF_RESOURCES; + } + + SetMem (VolatileVariableStore, VARIABLE_STORE_SIZE + SCRATCH_SIZE, 0xff); + + // + // Variable Specific Data + // + mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore; + mVariableModuleGlobal->VolatileLastVariableOffset = sizeof (VARIABLE_STORE_HEADER); + + VolatileVariableStore->Signature = VARIABLE_STORE_SIGNATURE; + VolatileVariableStore->Size = VARIABLE_STORE_SIZE; + VolatileVariableStore->Format = VARIABLE_STORE_FORMATTED; + VolatileVariableStore->State = VARIABLE_STORE_HEALTHY; + VolatileVariableStore->Reserved = 0; + VolatileVariableStore->Reserved1 = 0; + + // + // Get non volatile varaible store + // + + TempVariableStoreHeader = (UINT64) PcdGet32 (PcdFlashNvStorageVariableBase); + VariableStoreEntry.Base = TempVariableStoreHeader + \ + (((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (TempVariableStoreHeader)) -> HeaderLength); + VariableStoreEntry.Length = (UINT64) PcdGet32 (PcdFlashNvStorageVariableSize) - \ + (((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (TempVariableStoreHeader)) -> HeaderLength); + // + // Mark the variable storage region of the FLASH as RUNTIME + // + BaseAddress = VariableStoreEntry.Base & (~EFI_PAGE_MASK); + Length = VariableStoreEntry.Length + (VariableStoreEntry.Base - BaseAddress); + Length = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK); + + Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor); + if (EFI_ERROR (Status)) { + FreePool (mVariableModuleGlobal); + FreePool (VolatileVariableStore); + return EFI_UNSUPPORTED; + } + + Status = gDS->SetMemorySpaceAttributes ( + BaseAddress, + Length, + GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME + ); + if (EFI_ERROR (Status)) { + FreePool (mVariableModuleGlobal); + FreePool (VolatileVariableStore); + return EFI_UNSUPPORTED; + } + // + // Get address of non volatile variable store base + // + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase = VariableStoreEntry.Base; + + // + // Check Integrity + // + // + // Find the Correct Instance of the FV Block Service. + // + Instance = 0; + CurrPtr = (CHAR8 *) ((UINTN) mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase); + while (EfiFvbGetPhysicalAddress (Instance, &FvVolHdr) == EFI_SUCCESS) { + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvVolHdr); + if (CurrPtr >= (CHAR8 *) FwVolHeader && CurrPtr < (((CHAR8 *) FwVolHeader) + FwVolHeader->FvLength)) { + mVariableModuleGlobal->FvbInstance = Instance; + break; + } + + Instance++; + } + + VariableStoreHeader = (VARIABLE_STORE_HEADER *) CurrPtr; + if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) { + if (~VariableStoreHeader->Size == 0) { + Status = UpdateVariableStore ( + &mVariableModuleGlobal->VariableGlobal[Physical], + FALSE, + FALSE, + mVariableModuleGlobal->FvbInstance, + (UINTN) &VariableStoreHeader->Size, + sizeof (UINT32), + (UINT8 *) &VariableStoreEntry.Length + ); + // + // As Variables are stored in NV storage, which are slow devices,such as flash. + // Variable operation may skip checking variable program result to improve performance, + // We can assume Variable program is OK through some check point. + // Variable Store Size Setting should be the first Variable write operation, + // We can assume all Read/Write is OK if we can set Variable store size successfully. + // If write fail, we will assert here + // + ASSERT(VariableStoreHeader->Size == VariableStoreEntry.Length); + + if (EFI_ERROR (Status)) { + return Status; + } + } + + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) CurrPtr); + // + // Parse non-volatile variable data and get last variable offset + // + NextVariable = (VARIABLE_HEADER *) (CurrPtr + sizeof (VARIABLE_STORE_HEADER)); + Status = EFI_SUCCESS; + + while (IsValidVariableHeader (NextVariable)) { + NextVariable = GetNextVariablePtr (NextVariable); + } + + mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) CurrPtr; + + // + // Check if the free area is blow a threshold + // + if ((((VARIABLE_STORE_HEADER *)((UINTN) CurrPtr))->Size - mVariableModuleGlobal->NonVolatileLastVariableOffset) < VARIABLE_RECLAIM_THRESHOLD) { + Status = Reclaim ( + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase, + &mVariableModuleGlobal->NonVolatileLastVariableOffset, + FALSE + ); + } + + if (EFI_ERROR (Status)) { + FreePool (mVariableModuleGlobal); + FreePool (VolatileVariableStore); + return Status; + } + + // + // Check if the free area is really free. + // + for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < VariableStoreHeader->Size; Index++) { + Data = ((UINT8 *) (UINTN) mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase)[Index]; + if (Data != 0xff) { + // + // There must be something wrong in variable store, do reclaim operation. + // + Status = Reclaim ( + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase, + &mVariableModuleGlobal->NonVolatileLastVariableOffset, + FALSE + ); + break; + } + } + } + + if (EFI_ERROR (Status)) { + FreePool (mVariableModuleGlobal); + FreePool (VolatileVariableStore); + } + + return Status; +} diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h new file mode 100644 index 0000000000..904a681c33 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h @@ -0,0 +1,175 @@ +/*++ + +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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// BugBug: We need relcate the head file. +// +#include + +#define VARIABLE_RECLAIM_THRESHOLD (1024) + +#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 + ); + +EFI_STATUS +GetFvbHandleByAddress ( + IN EFI_PHYSICAL_ADDRESS VariableStoreBase, + OUT EFI_HANDLE *FvbHandle + ); + +EFI_STATUS +FtwVariableSpace ( + IN EFI_PHYSICAL_ADDRESS VariableBaseAddress, + IN UINT8 *Buffer, + IN UINTN BufferSize + ); + +#endif diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.msa b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.msa new file mode 100644 index 0000000000..56f19b0437 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.msa @@ -0,0 +1,108 @@ + + + + Variable + DXE_RUNTIME_DRIVER + CBD2E4D5-7068-4FF5-B462-9822B4AD8D60 + 1.0 + Component description file for Variable module. + This module installs 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 + false + Variable + + + + PcdLib + + + UefiDriverEntryPoint + + + DxeServicesTableLib + + + UefiRuntimeLib + + + DebugLib + + + BaseMemoryLib + + + EdkFvbServiceLib + + + UefiBootServicesTableLib + + + UefiLib + + + BaseLib + + + MemoryAllocationLib + + + + Variable.h + Variable.c + reclaim.h + reclaim.c + InitVariable.c + Variable.dxs + + + + + + + + gEfiVariableArchProtocolGuid + + + gEfiVariableWriteArchProtocolGuid + + + gEfiFaultTolerantWriteLiteProtocolGuid + + + gEfiFirmwareVolumeBlockProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + VariableServiceInitialize + + + VariableClassAddressChangeEvent + + + + + PcdFlashNvStorageVariableBase + gEfiGenericPlatformTokenSpaceGuid + The driver gets the Variable store base address from this PCD. This base address point to + an EFI_FIRMWARE_VOLUMN_HEADER struct. + + + PcdFlashNvStorageVariableSize + gEfiGenericPlatformTokenSpaceGuid + The driver gets the NvStorage Variable Size from this PCD. + + + \ No newline at end of file diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf new file mode 100644 index 0000000000..b8b4ecce8d --- /dev/null +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -0,0 +1,74 @@ +#/** @file +# Component description file for Variable module. +# +# This module installs 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] + INF_VERSION = 0x00010005 + BASE_NAME = VariableRuntimeDxe + FILE_GUID = CBD2E4D5-7068-4FF5-B462-9822B4AD8D60 + 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 +# +# VIRTUAL_ADDRESS_MAP_CALLBACK = VariableClassAddressChangeEvent +# + +[Sources.common] + InitVariable.c + reclaim.c + Variable.c + Variable.h + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + MemoryAllocationLib + BaseLib + UefiLib + UefiBootServicesTableLib + FvbServiceLib + BaseMemoryLib + DebugLib + UefiRuntimeLib + DxeServicesTableLib + UefiDriverEntryPoint + PcdLib + HobLib + +[Guids] + gEfiFlashMapHobGuid + +[Protocols] + gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL SOMETIMES_CONSUMED + gEfiFaultTolerantWriteLiteProtocolGuid # PROTOCOL SOMETIMES_CONSUMED + gEfiVariableWriteArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + gEfiVariableArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + +[PcdsDynamic.common] + PcdFlashNvStorageVariableSize|gEfiMdeModulePkgTokenSpaceGuid + PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid + +[Depex] + gEfiFirmwareVolumeBlockProtocolGuid AND gEfiAlternateFvBlockGuid AND gEfiFaultTolerantWriteLiteProtocolGuid + diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/reclaim.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/reclaim.c new file mode 100644 index 0000000000..0adaa8787c --- /dev/null +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/reclaim.c @@ -0,0 +1,242 @@ +/*++ + +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: + + reclaim.c + +Abstract: + + Handles non-volatile variable store garbage collection, using FTW + (Fault Tolerant Write) protocol. + +Revision History + +--*/ + + +#include +#include "Common/Variable.h" + +EFI_STATUS +GetFvbHandleByAddress ( + IN EFI_PHYSICAL_ADDRESS Address, + OUT EFI_HANDLE *FvbHandle + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN HandleCount; + UINTN Index; + EFI_PHYSICAL_ADDRESS FvbBaseAddress; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + + *FvbHandle = NULL; + // + // Locate all handles of Fvb protocol + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolumeBlockProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + // + // Get the FVB to access variable store + // + for (Index = 0; Index < HandleCount; Index += 1) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID **) &Fvb + ); + if (EFI_ERROR (Status)) { + Status = EFI_NOT_FOUND; + break; + } + // + // Compare the address and select the right one + // + Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress); + if (EFI_ERROR (Status)) { + continue; + } + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress); + if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + FwVolHeader->FvLength))) { + *FvbHandle = HandleBuffer[Index]; + Status = EFI_SUCCESS; + break; + } + } + + FreePool (HandleBuffer); + return Status; +} + +STATIC +EFI_STATUS +GetLbaAndOffsetByAddress ( + IN EFI_PHYSICAL_ADDRESS Address, + OUT EFI_LBA *Lba, + OUT UINTN *Offset + ) +{ + EFI_STATUS Status; + EFI_HANDLE FvbHandle; + EFI_PHYSICAL_ADDRESS FvbBaseAddress; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_FV_BLOCK_MAP_ENTRY *FvbMapEntry; + UINT32 LbaIndex; + + *Lba = (EFI_LBA) (-1); + *Offset = 0; + + // + // Get the proper FVB + // + Status = GetFvbHandleByAddress (Address, &FvbHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->HandleProtocol ( + FvbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID **) &Fvb + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Get the Base Address of FV + // + Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress); + if (EFI_ERROR (Status)) { + return Status; + } + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress); + + // + // Get the (LBA, Offset) of Address + // + if ((Address >= FvbBaseAddress) && (Address <= (FvbBaseAddress + FwVolHeader->FvLength))) { + if ((FwVolHeader->FvLength) > (FwVolHeader->HeaderLength)) { + // + // BUGBUG: Assume one FV has one type of BlockLength + // + FvbMapEntry = &FwVolHeader->BlockMap[0]; + for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) { + if (Address < (FvbBaseAddress + FvbMapEntry->Length * LbaIndex)) { + // + // Found the (Lba, Offset) + // + *Lba = LbaIndex - 1; + *Offset = (UINTN) (Address - (FvbBaseAddress + FvbMapEntry->Length * (LbaIndex - 1))); + return EFI_SUCCESS; + } + } + } + } + + return EFI_ABORTED; +} + +EFI_STATUS +FtwVariableSpace ( + IN EFI_PHYSICAL_ADDRESS VariableBase, + IN UINT8 *Buffer, + IN UINTN BufferSize + ) +/*++ + +Routine Description: + Write a buffer to Variable space, in the working block. + +Arguments: + FvbHandle - Indicates a handle to FVB to access variable store + Buffer - Point to the input buffer + BufferSize - The number of bytes of the input Buffer + +Returns: + EFI_SUCCESS - The function completed successfully + EFI_ABORTED - The function could not complete successfully + EFI_NOT_FOUND - Locate FVB protocol by handle fails + +--*/ +{ + EFI_STATUS Status; + EFI_HANDLE FvbHandle; + EFI_FTW_LITE_PROTOCOL *FtwLiteProtocol; + EFI_LBA VarLba; + UINTN VarOffset; + UINT8 *FtwBuffer; + UINTN FtwBufferSize; + + // + // Locate fault tolerant write protocol + // + Status = gBS->LocateProtocol ( + &gEfiFaultTolerantWriteLiteProtocolGuid, + NULL, + (VOID **) &FtwLiteProtocol + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + // + // Locate Fvb handle by address + // + Status = GetFvbHandleByAddress (VariableBase, &FvbHandle); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Get LBA and Offset by address + // + Status = GetLbaAndOffsetByAddress (VariableBase, &VarLba, &VarOffset); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + // + // Prepare for the variable data + // + FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size; + FtwBuffer = AllocateRuntimePool (FtwBufferSize); + if (FtwBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff); + CopyMem (FtwBuffer, Buffer, BufferSize); + + // + // FTW write record + // + Status = FtwLiteProtocol->Write ( + FtwLiteProtocol, + FvbHandle, + VarLba, // LBA + VarOffset, // Offset + &FtwBufferSize, // NumBytes, + FtwBuffer + ); + + FreePool (FtwBuffer); + return Status; +} diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc index dea84599b0..a525b3e032 100644 --- a/Nt32Pkg/Nt32Pkg.dsc +++ b/Nt32Pkg/Nt32Pkg.dsc @@ -364,7 +364,7 @@ $(WORKSPACE)/Nt32Pkg/BootModePei/BootModePei.inf $(WORKSPACE)/Nt32Pkg/WinNtFlashMapPei/WinNtFlashMapPei.inf $(WORKSPACE)/MdeModulePkg/Universal/MemoryTest/BaseMemoryTestPei/BaseMemoryTestPei.inf - $(WORKSPACE)/MdeModulePkg/Universal/VariablePei/VariablePei.inf + $(WORKSPACE)/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf $(WORKSPACE)/Nt32Pkg/WinNtAutoScanPei/WinNtAutoScanPei.inf $(WORKSPACE)/Nt32Pkg/WinNtFirmwareVolumePei/WinNtFirmwareVolumePei.inf $(WORKSPACE)/Nt32Pkg/WinNtThunkPPIToProtocolPei/WinNtThunkPPIToProtocolPei.inf @@ -397,7 +397,7 @@ $(WORKSPACE)/Nt32Pkg/MiscSubClassPlatformDxe/MiscSubClassPlatformDxe.inf $(WORKSPACE)/Nt32Pkg/TimerDxe/TimerDxe.inf $(WORKSPACE)/IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.inf - $(WORKSPACE)/MdeModulePkg/Universal/VariableRuntimeDxe/VariableRuntimeDxe.inf + $(WORKSPACE)/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf $(WORKSPACE)/MdeModulePkg/Universal/WatchDogTimerDxe/WatchDogTimer.inf $(WORKSPACE)/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf $(WORKSPACE)/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf diff --git a/Nt32Pkg/Nt32Pkg.fdf b/Nt32Pkg/Nt32Pkg.fdf index 64f481e610..0987e987a7 100644 --- a/Nt32Pkg/Nt32Pkg.fdf +++ b/Nt32Pkg/Nt32Pkg.fdf @@ -118,7 +118,7 @@ INF $(WORKSPACE)/IntelFrameworkModulePkg/Universal/StatusCode/Pei/PeiStatusCode INF $(WORKSPACE)/Nt32Pkg/BootModePei/BootModePei.inf INF $(WORKSPACE)/Nt32Pkg/WinNtFlashMapPei/WinNtFlashMapPei.inf INF $(WORKSPACE)/MdeModulePkg/Universal/MemoryTest/BaseMemoryTestPei/BaseMemoryTestPei.inf -INF $(WORKSPACE)/MdeModulePkg/Universal/VariablePei/VariablePei.inf +INF $(WORKSPACE)/MdeModulePkg/Universal/Variable/Pei/VariablePei.inf INF $(WORKSPACE)/Nt32Pkg/WinNtAutoScanPei/WinNtAutoScanPei.inf INF $(WORKSPACE)/Nt32Pkg/WinNtFirmwareVolumePei/WinNtFirmwareVolumePei.inf INF $(WORKSPACE)/Nt32Pkg/WinNtThunkPPIToProtocolPei/WinNtThunkPPIToProtocolPei.inf @@ -148,7 +148,7 @@ INF $(WORKSPACE)/IntelFrameworkModulePkg/Universal/DataHubStdErrDxe/DataHubStdE INF $(WORKSPACE)/Nt32Pkg/MiscSubClassPlatformDxe/MiscSubClassPlatformDxe.inf INF $(WORKSPACE)/Nt32Pkg/TimerDxe/TimerDxe.inf INF $(WORKSPACE)/IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.inf -INF $(WORKSPACE)/MdeModulePkg/Universal/VariableRuntimeDxe/VariableRuntimeDxe.inf +INF $(WORKSPACE)/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf INF $(WORKSPACE)/MdeModulePkg/Universal/WatchDogTimerDxe/WatchDogTimer.inf INF $(WORKSPACE)/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf INF $(WORKSPACE)/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf -- 2.39.2