diff options
Diffstat (limited to 'EdkModulePkg/Universal/Variable')
26 files changed, 4297 insertions, 0 deletions
diff --git a/EdkModulePkg/Universal/Variable/Pei/Ia32/VarMachine.h b/EdkModulePkg/Universal/Variable/Pei/Ia32/VarMachine.h new file mode 100644 index 0000000000..83031e9788 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/Pei/Ia32/VarMachine.h @@ -0,0 +1,27 @@ +/*++
+
+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:
+
+ VarMachine.h
+
+Abstract:
+
+ Variable Machine Type
+
+--*/
+
+#ifndef _VAR_MACHINE_H
+#define _VAR_MACHINE_H
+
+#define ALIGNMENT 1
+
+#endif
diff --git a/EdkModulePkg/Universal/Variable/Pei/Ipf/VarMachine.h b/EdkModulePkg/Universal/Variable/Pei/Ipf/VarMachine.h new file mode 100644 index 0000000000..c5b5753f9e --- /dev/null +++ b/EdkModulePkg/Universal/Variable/Pei/Ipf/VarMachine.h @@ -0,0 +1,27 @@ +/*++
+
+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:
+
+ VarMachine.h
+
+Abstract:
+
+ Variable Machine Type
+
+--*/
+
+#ifndef _VAR_MACHINE_H
+#define _VAR_MACHINE_H
+
+#define ALIGNMENT 8
+
+#endif
diff --git a/EdkModulePkg/Universal/Variable/Pei/Variable.c b/EdkModulePkg/Universal/Variable/Pei/Variable.c new file mode 100644 index 0000000000..b2286c1860 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/Pei/Variable.c @@ -0,0 +1,563 @@ +/*++
+
+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.c
+
+Abstract:
+
+ Framework PEIM to provide the Variable functionality
+
+--*/
+
+
+#include <Ppi/ReadOnlyVariable.h>
+#include <Variable.h>
+#include <Library/BaseLib.h>
+
+//
+// Module globals
+//
+static EFI_PEI_READ_ONLY_VARIABLE_PPI mVariablePpi = {
+ PeiGetVariable,
+ PeiGetNextVariableName
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiReadOnlyVariablePpiGuid,
+ &mVariablePpi
+};
+
+EFI_GUID gEfiVariableIndexTableGuid = 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);
+
+}
+
+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));
+}
+
+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;
+}
+
+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;
+ }
+}
+
+EFI_STATUS
+CompareWithValidVariable (
+ IN VARIABLE_HEADER *Variable,
+ IN CHAR16 *VariableName,
+ IN 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 (!StrCmp (VariableName, GET_VARIABLE_NAME_PTR (Variable))) {
+ PtrTrack->CurrPtr = Variable;
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+EFIAPI
+FindVariable (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CHAR16 *VariableName,
+ IN 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
+
+--*/
+{
+ PEI_FLASH_MAP_PPI *FlashMapPpi;
+ EFI_FLASH_SUBAREA_ENTRY *VariableStoreEntry;
+ UINT32 NumEntries;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ VARIABLE_HEADER *Variable;
+
+ EFI_STATUS Status;
+
+ VARIABLE_HEADER *MaxIndex;
+ VARIABLE_INDEX_TABLE *IndexTable;
+ UINT32 Count;
+
+ 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 (&gEfiVariableIndexTableGuid);
+ if (GuidHob == NULL) {
+ IndexTable = BuildGuidHob (&gEfiVariableIndexTableGuid, 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++)
+ {
+#if ALIGNMENT <= 1
+ MaxIndex = (VARIABLE_HEADER *) (UINTN) (IndexTable->Index[Count] + ((UINTN) IndexTable->StartPtr & 0xFFFF0000));
+#else
+#if ALIGNMENT >= 4
+ MaxIndex = (VARIABLE_HEADER *) (UINTN) ((((UINT32)IndexTable->Index[Count]) << 2) + ((UINT32)(UINTN)IndexTable->StartPtr & 0xFFFC0000) );
+#endif
+#endif
+ 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 {
+ //
+ // Locate FlashMap PPI
+ //
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gPeiFlashMapPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &FlashMapPpi
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get flash area info for variables
+ //
+ Status = FlashMapPpi->GetAreaInfo (
+ PeiServices,
+ FlashMapPpi,
+ EFI_FLASH_AREA_EFI_VARIABLES,
+ NULL,
+ &NumEntries,
+ &VariableStoreEntry
+ );
+
+ //
+ // Currently only one non-volatile variable store is supported
+ //
+ if (NumEntries != 1) {
+ return EFI_UNSUPPORTED;
+ }
+
+ VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) (VariableStoreEntry->Base);
+
+ 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)
+ {
+#if ALIGNMENT <= 1
+ IndexTable->Index[IndexTable->Length++] = (UINT16) (UINTN) Variable;
+#else
+#if ALIGNMENT >= 4
+ IndexTable->Index[IndexTable->Length++] = (UINT16) (((UINT32)(UINTN) Variable) >> 2);
+#endif
+#endif
+ }
+
+ 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 EFI_PEI_SERVICES **PeiServices,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID * VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ 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;
+
+ if (VariableName == NULL || VendorGuid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Find existing variable
+ //
+ Status = FindVariable (PeiServices, VariableName, VendorGuid, &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 EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName,
+ IN OUT EFI_GUID *VendorGuid
+ )
+/*++
+
+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.
+ VendorGuid - 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;
+
+ if (VariableName == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = FindVariable (PeiServices, VariableName, VendorGuid, &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 (VendorGuid, &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/EdkModulePkg/Universal/Variable/Pei/Variable.dxs b/EdkModulePkg/Universal/Variable/Pei/Variable.dxs new file mode 100644 index 0000000000..d16ad10db2 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/Pei/Variable.dxs @@ -0,0 +1,28 @@ +/*++
+
+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 <AutoGen.h>
+#include <PeimDepex.h>
+
+DEPENDENCY_START
+ PEI_FLASH_MAP_PPI_GUID
+DEPENDENCY_END
+
+
diff --git a/EdkModulePkg/Universal/Variable/Pei/Variable.h b/EdkModulePkg/Universal/Variable/Pei/Variable.h new file mode 100644 index 0000000000..2a6f861def --- /dev/null +++ b/EdkModulePkg/Universal/Variable/Pei/Variable.h @@ -0,0 +1,154 @@ +/*++
+
+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.h
+
+Abstract:
+
+ Tiano PEIM to provide the variable functionality
+
+--*/
+
+#ifndef _PEI_VARIABLE_H
+#define _PEI_VARIABLE_H
+
+//
+// BugBug: We need relcate the head file.
+//
+#include <Common/Variable.h>
+
+#define ALIGNMENT 1
+
+//
+// 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;
+
+extern EFI_GUID gEfiVariableIndexTableGuid;
+
+//
+// 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 EFI_PEI_SERVICES **PeiServices,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID * VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ 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 EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName,
+ IN OUT EFI_GUID *VendorGuid
+ )
+/*++
+
+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
+
+--*/
+;
+
+#endif // _PEI_VARIABLE_H
diff --git a/EdkModulePkg/Universal/Variable/Pei/Variable.mbd b/EdkModulePkg/Universal/Variable/Pei/Variable.mbd new file mode 100644 index 0000000000..036758dc62 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/Pei/Variable.mbd @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MbdHeader>
+ <BaseName>PeiVariable</BaseName>
+ <Guid>34C8C28F-B61C-45a2-8F2E-89E46BECC63B</Guid>
+ <Version>0</Version>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ 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.
+ </License>
+ <Created>2006-03-12 17:09</Created>
+ <Modified>2006-03-19 15:19</Modified>
+ </MbdHeader>
+ <Libraries>
+ <Library>PeiReportStatusCodeLib</Library>
+ <Library>BaseDebugLibReportStatusCode</Library>
+ <Library>BaseLib</Library>
+ <Library>PeiMemoryLib</Library>
+ <Library>PeiCoreLib</Library>
+ <Library>PeiServicesTablePointerLib</Library>
+ <Library>PeiHobLib</Library>
+ <Library>PeimEntryPoint</Library>
+ </Libraries>
+ <BuildOptions ToolChain="MSFT">
+ <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
+ </BuildOptions>
+</ModuleBuildDescription>
diff --git a/EdkModulePkg/Universal/Variable/Pei/Variable.msa b/EdkModulePkg/Universal/Variable/Pei/Variable.msa new file mode 100644 index 0000000000..79c086bdb1 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/Pei/Variable.msa @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MsaHeader>
+ <BaseName>PeiVariable</BaseName>
+ <ModuleType>PEIM</ModuleType>
+ <ComponentType>PE32_PEIM</ComponentType>
+ <Guid>34C8C28F-B61C-45a2-8F2E-89E46BECC63B</Guid>
+ <Version>0</Version>
+ <Abstract>Component description file for DiskIo module.</Abstract>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ 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.
+ </License>
+ <Specification>0</Specification>
+ <Created>2006-03-12 17:09</Created>
+ <Updated>2006-03-19 15:19</Updated>
+ </MsaHeader>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">PeimEntryPoint</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">PeiCoreLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>Variable.c</Filename>
+ <Filename>Variable.dxs</Filename>
+ </SourceFiles>
+ <Includes>
+ <PackageName>MdePkg</PackageName>
+ <PackageName>EdkModulePkg</PackageName>
+ </Includes>
+ <PPIs>
+ <Ppi Usage="ALWAYS_CONSUMED">FlashMap</Ppi>
+ <Ppi Usage="ALWAYS_CONSUMED">ReadOnlyVariable</Ppi>
+ </PPIs>
+ <Externs>
+ <Extern>
+ <ModuleEntryPoint>PeimInitializeVariableServices</ModuleEntryPoint>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Universal/Variable/Pei/build.xml b/EdkModulePkg/Universal/Variable/Pei/build.xml new file mode 100644 index 0000000000..c6b57f9f77 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/Pei/build.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
+<project basedir="." default="PeiVariable"><!--Apply external ANT tasks-->
+ <taskdef resource="GenBuild.tasks"/>
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+ <property environment="env"/>
+ <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+ <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+ <property name="MODULE_RELATIVE_PATH" value="Universal\Variable\Pei"/>
+ <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
+ <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
+ <target name="PeiVariable">
+ <GenBuild baseName="PeiVariable" mbdFilename="${MODULE_DIR}\Variable.mbd" msaFilename="${MODULE_DIR}\Variable.msa"/>
+ </target>
+ <target depends="PeiVariable_clean" name="clean"/>
+ <target depends="PeiVariable_cleanall" name="cleanall"/>
+ <target name="PeiVariable_clean">
+ <OutputDirSetup baseName="PeiVariable" mbdFilename="${MODULE_DIR}\Variable.mbd" msaFilename="${MODULE_DIR}\Variable.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\PeiVariable_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\PeiVariable_build.xml" target="clean"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+ </target>
+ <target name="PeiVariable_cleanall">
+ <OutputDirSetup baseName="PeiVariable" mbdFilename="${MODULE_DIR}\Variable.mbd" msaFilename="${MODULE_DIR}\Variable.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\PeiVariable_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\PeiVariable_build.xml" target="cleanall"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}"/>
+ <delete dir="${DEST_DIR_DEBUG}"/>
+ <delete>
+ <fileset dir="${BIN_DIR}" includes="**PeiVariable*"/>
+ </delete>
+ </target>
+</project>
\ No newline at end of file diff --git a/EdkModulePkg/Universal/Variable/Pei/x64/VarMachine.h b/EdkModulePkg/Universal/Variable/Pei/x64/VarMachine.h new file mode 100644 index 0000000000..83031e9788 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/Pei/x64/VarMachine.h @@ -0,0 +1,27 @@ +/*++
+
+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:
+
+ VarMachine.h
+
+Abstract:
+
+ Variable Machine Type
+
+--*/
+
+#ifndef _VAR_MACHINE_H
+#define _VAR_MACHINE_H
+
+#define ALIGNMENT 1
+
+#endif
diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.c b/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.c new file mode 100644 index 0000000000..beb404f42c --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.c @@ -0,0 +1,754 @@ +/*++
+
+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:
+
+ EmuVariable.c
+
+Abstract:
+
+Revision History
+
+--*/
+
+#include "Variable.h"
+
+//
+// Don't use module globals after the SetVirtualAddress map is signaled
+//
+ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;
+
+UINT32
+EFIAPI
+ArrayLength (
+ IN CHAR16 *String
+ )
+/*++
+
+Routine Description:
+
+ Determine the length of null terminated char16 array.
+
+Arguments:
+
+ String Null-terminated CHAR16 array pointer.
+
+Returns:
+
+ UINT32 Number of bytes in the string, including the double NULL at the end;
+
+--*/
+{
+ UINT32 Count;
+
+ if (NULL == String) {
+ return 0;
+ }
+
+ Count = 0;
+
+ while (0 != String[Count]) {
+ Count++;
+ }
+
+ return (Count * 2) + 2;
+}
+
+UINTN
+EFIAPI
+GetPadSize (
+ IN UINTN Value
+ )
+/*++
+
+Routine Description:
+
+ This function return the pad size for alignment
+
+Arguments:
+
+ Value The value need to align
+
+Returns:
+
+ Pad size for value
+
+--*/
+{
+ //
+ // If alignment is 0 or 1, means no alignment required
+ //
+ if (ALIGNMENT == 0 || ALIGNMENT == 1) {
+ return 0;
+ }
+
+ return ALIGNMENT - (Value % ALIGNMENT);
+}
+
+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:
+
+ EfiHealthy Variable store is healthy
+ EfiRaw Variable store is raw
+ EfiInvalid Variable store 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;
+ }
+}
+
+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 + GetPadSize (Variable->NameSize));
+}
+
+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;
+}
+
+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);
+}
+
+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;
+
+ //
+ // 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]), ArrayLength (VariableName))) {
+ 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)) {
+ return Status;
+ }
+ //
+ // Get data size
+ //
+ VarDataSize = Variable.CurrPtr->DataSize;
+ if (*DataSize >= VarDataSize) {
+ CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);
+ if (Attributes) {
+ *Attributes = Variable.CurrPtr->Attributes;
+ }
+
+ *DataSize = VarDataSize;
+ return EFI_SUCCESS;
+ } else {
+ *DataSize = VarDataSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+}
+
+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 || VendorGuid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = FindVariable (VariableName, VendorGuid, &Variable, Global);
+
+ if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ 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 {
+ return EFI_NOT_FOUND;
+ }
+
+ 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;
+ return Status;
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+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) {
+ return Status;
+ }
+ //
+ // 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.
+ //
+ else if (sizeof (VARIABLE_HEADER) + (ArrayLength (VariableName) + DataSize) > MAX_VARIABLE_SIZE) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Make sure if runtime bit is set, boot service bit is set also
+ //
+ else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Runtime but Attribute is not Runtime
+ //
+ else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Cannot set volatile variable in Runtime
+ //
+ else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Setting a data variable with no access, or zero DataSize attributes
+ // specified causes it to be deleted.
+ //
+ else if (DataSize == 0 || Attributes == 0) {
+ if (!EFI_ERROR (Status)) {
+ Variable.CurrPtr->State &= VAR_DELETED;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+ } 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)
+ ) {
+ return EFI_SUCCESS;
+ } 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 = ArrayLength (VariableName);
+ VarDataOffset = VarNameOffset + VarNameSize + GetPadSize (VarNameSize);
+ VarSize = VarDataOffset + DataSize + GetPadSize (DataSize);
+
+ if (Attributes & EFI_VARIABLE_NON_VOLATILE) {
+ if ((UINT32) (VarSize +*NonVolatileOffset) >
+ ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size
+ ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NextVariable = (VARIABLE_HEADER *) (UINT8 *) (*NonVolatileOffset + (UINTN) Global->NonVolatileVariableBase);
+ *NonVolatileOffset = *NonVolatileOffset + VarSize;
+ } else {
+ if (EfiAtRuntime ()) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((UINT32) (VarSize +*VolatileOffset) >
+ ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size
+ ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ 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;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+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;
+ }
+ //
+ // Intialize volatile variable store
+ //
+ Status = InitializeVariableStore (
+ &mVariableModuleGlobal->VariableBase[Physical].VolatileVariableBase,
+ &mVariableModuleGlobal->VolatileLastVariableOffset
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Intialize non volatile variable store
+ //
+ Status = InitializeVariableStore (
+ &mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase,
+ &mVariableModuleGlobal->NonVolatileLastVariableOffset
+ );
+
+ return Status;
+}
diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.dxs b/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.dxs new file mode 100644 index 0000000000..51c93d7657 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.dxs @@ -0,0 +1,25 @@ +/*++
+
+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:
+
+ EmuVariable.dxs
+
+Abstract:
+
+ Dependency expression source file.
+
+--*/
+#include "DxeDepex.h"
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
\ No newline at end of file diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.mbd b/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.mbd new file mode 100644 index 0000000000..4cc2c2085d --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.mbd @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MbdHeader>
+ <BaseName>EmuVariable</BaseName>
+ <Guid>CBD2E4D5-7068-4FF5-B866-9822B4AD8D60</Guid>
+ <Version>0</Version>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ 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.
+ </License>
+ <Created>2006-03-23 16:05</Created>
+ </MbdHeader>
+ <Libraries>
+ <Library>UefiBootServicesTableLib</Library>
+ <Library>BaseMemoryLib</Library>
+ <Library>BaseDebugLibReportStatusCode</Library>
+ <Library>UefiDriverEntryPoint</Library>
+ <Library>EdkDxeRuntimeDriverLib</Library>
+ <Library>DxeMemoryAllocationLib</Library>
+ <Library>BaseLib</Library>
+ <Library>DxeReportStatusCodeLib</Library>
+ <Arch ArchType="IPF">
+ <Library>EdkDxeSalLib</Library>
+ </Arch>
+ </Libraries>
+ <BuildOptions ToolChain="MSFT">
+ <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
+ </BuildOptions>
+</ModuleBuildDescription>
diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.msa b/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.msa new file mode 100644 index 0000000000..5a7a5f8447 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/EmuVariable.msa @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MsaHeader>
+ <BaseName>EmuVariable</BaseName>
+ <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>
+ <ComponentType>RT_DRIVER</ComponentType>
+ <Guid>CBD2E4D5-7068-4FF5-B866-9822B4AD8D60</Guid>
+ <Version>0</Version>
+ <Abstract>Component description file for DiskIo module.</Abstract>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ 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.
+ </License>
+ <Specification>0</Specification>
+ <Created>2006-03-23 16:05</Created>
+ </MsaHeader>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">EdkDxeSalLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>EmuVariable.c</Filename>
+ <Filename>EmuVariable.dxs</Filename>
+ <Arch ArchType="IA32">
+ <Filename>..\Ia32\Ia32Variable.c</Filename>
+ </Arch>
+ <Arch ArchType="X64">
+ <Filename>..\x64\x64Variable.c</Filename>
+ </Arch>
+ <Arch ArchType="IPF">
+ <Filename>..\Ipf\IpfVariable.c</Filename>
+ </Arch>
+ </SourceFiles>
+ <Includes>
+ <PackageName>MdePkg</PackageName>
+ <PackageName>EdkModulePkg</PackageName>
+ </Includes>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">VariableWrite</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">VariableWrite</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalVariableServices</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalBootService</Protocol>
+ </Protocols>
+ <Externs>
+ <Extern>
+ <ModuleEntryPoint>VariableServiceInitialize</ModuleEntryPoint>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/build.xml b/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/build.xml new file mode 100644 index 0000000000..0035ab957b --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Emu/build.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
+<project basedir="." default="EmuVariable"><!--Apply external ANT tasks-->
+ <taskdef resource="GenBuild.tasks"/>
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+ <property environment="env"/>
+ <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+ <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+ <property name="MODULE_RELATIVE_PATH" value="Universal\Variable\RuntimeDxe\Emu"/>
+ <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
+ <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
+ <target name="EmuVariable">
+ <GenBuild baseName="EmuVariable" mbdFilename="${MODULE_DIR}\EmuVariable.mbd" msaFilename="${MODULE_DIR}\EmuVariable.msa"/>
+ </target>
+ <target depends="EmuVariable_clean" name="clean"/>
+ <target depends="EmuVariable_cleanall" name="cleanall"/>
+ <target name="EmuVariable_clean">
+ <OutputDirSetup baseName="EmuVariable" mbdFilename="${MODULE_DIR}\EmuVariable.mbd" msaFilename="${MODULE_DIR}\EmuVariable.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\EmuVariable_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\EmuVariable_build.xml" target="clean"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+ </target>
+ <target name="EmuVariable_cleanall">
+ <OutputDirSetup baseName="EmuVariable" mbdFilename="${MODULE_DIR}\EmuVariable.mbd" msaFilename="${MODULE_DIR}\EmuVariable.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\EmuVariable_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\EmuVariable_build.xml" target="cleanall"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}"/>
+ <delete dir="${DEST_DIR_DEBUG}"/>
+ <delete>
+ <fileset dir="${BIN_DIR}" includes="**EmuVariable*"/>
+ </delete>
+ </target>
+</project>
\ No newline at end of file diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Ia32Variable.dxs b/EdkModulePkg/Universal/Variable/RuntimeDxe/Ia32Variable.dxs new file mode 100644 index 0000000000..821e27df4a --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Ia32Variable.dxs @@ -0,0 +1,28 @@ +/*++
+
+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:
+
+ Ia32Variable.dxs
+
+Abstract:
+
+ Dependency expression source file.
+
+--*/
+#include <AutoGen.h>
+#include <DxeDepex.h>
+
+DEPENDENCY_START
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID AND
+ EFI_ALTERNATE_FV_BLOCK_GUID AND
+ EFI_FTW_LITE_PROTOCOL_GUID
+DEPENDENCY_END
\ No newline at end of file diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/InitVariable.c b/EdkModulePkg/Universal/Variable/RuntimeDxe/InitVariable.c new file mode 100644 index 0000000000..0ad86642ea --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/InitVariable.c @@ -0,0 +1,185 @@ +/*++
+
+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:
+
+ 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->VariableBase[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->VariableBase[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->VariableBase[Physical],
+ &mVariableModuleGlobal->VolatileLastVariableOffset,
+ &mVariableModuleGlobal->NonVolatileLastVariableOffset,
+ mVariableModuleGlobal->FvbInstance
+ );
+}
+
+VOID
+EFIAPI
+VariableClassAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EfiConvertPointer (
+ 0x0,
+ (VOID **) &mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase
+ );
+ EfiConvertPointer (
+ 0x0,
+ (VOID **) &mVariableModuleGlobal->VariableBase[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;
+
+ //
+ // 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/EdkModulePkg/Universal/Variable/RuntimeDxe/Ipf/InitVariable.c b/EdkModulePkg/Universal/Variable/RuntimeDxe/Ipf/InitVariable.c new file mode 100644 index 0000000000..061e6db73d --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Ipf/InitVariable.c @@ -0,0 +1,167 @@ +/*++
+
+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:
+
+ IpfVariable.c
+
+Abstract:
+
+Revision History
+
+--*/
+
+#include "Variable.h"
+
+//
+// Don't use module globals after the SetVirtualAddress map is signaled
+//
+extern ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;
+
+SAL_RETURN_REGS
+EsalVariableCommonEntry (
+ IN UINT64 FunctionId,
+ IN UINT64 Arg2,
+ IN UINT64 Arg3,
+ IN UINT64 Arg4,
+ IN UINT64 Arg5,
+ IN UINT64 Arg6,
+ IN UINT64 Arg7,
+ IN UINT64 Arg8,
+ IN SAL_EXTENDED_SAL_PROC ExtendedSalProc,
+ IN BOOLEAN VirtualMode,
+ IN ESAL_VARIABLE_GLOBAL *Global
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ SAL_RETURN_REGS ReturnVal;
+
+ switch (FunctionId) {
+ case EsalGetVariable:
+ ReturnVal.Status = GetVariable (
+ (CHAR16 *) Arg2,
+ (EFI_GUID *) Arg3,
+ (UINT32 *) Arg4,
+ (UINTN *) Arg5,
+ (VOID *) Arg6,
+ &Global->VariableBase[VirtualMode],
+ Global->FvbInstance
+ );
+ return ReturnVal;
+
+ case EsalGetNextVariableName:
+ ReturnVal.Status = GetNextVariableName (
+ (UINTN *) Arg2,
+ (CHAR16 *) Arg3,
+ (EFI_GUID *) Arg4,
+ &Global->VariableBase[VirtualMode],
+ Global->FvbInstance
+ );
+ return ReturnVal;
+
+ case EsalSetVariable:
+ ReturnVal.Status = SetVariable (
+ (CHAR16 *) Arg2,
+ (EFI_GUID *) Arg3,
+ (UINT32) Arg4,
+ (UINTN) Arg5,
+ (VOID *) Arg6,
+ &Global->VariableBase[VirtualMode],
+ (UINTN *) &Global->VolatileLastVariableOffset,
+ (UINTN *) &Global->NonVolatileLastVariableOffset,
+ Global->FvbInstance
+ );
+ return ReturnVal;
+
+ default:
+ ReturnVal.Status = EFI_SAL_INVALID_ARGUMENT;
+ return ReturnVal;
+ }
+}
+
+
+VOID
+VariableClassAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ CopyMem (
+ &mVariableModuleGlobal->VariableBase[Virtual],
+ &mVariableModuleGlobal->VariableBase[Physical],
+ sizeof (VARIABLE_GLOBAL)
+ );
+
+ EfiConvertPointer (
+ 0x0,
+ (VOID **) &mVariableModuleGlobal->VariableBase[Virtual].NonVolatileVariableBase
+ );
+ EfiConvertPointer (
+ 0x0,
+ (VOID **) &mVariableModuleGlobal->VariableBase[Virtual].VolatileVariableBase
+ );
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
+}
+
+EFI_STATUS
+VariableServiceInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = VariableCommonInitialize (ImageHandle, SystemTable);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register All the Functions with Extended Sal.
+ //
+ RegisterEsalClass (
+ &gEfiExtendedSalVariableServicesProtocolGuid,
+ mVariableModuleGlobal,
+ EsalVariableCommonEntry,
+ EsalGetVariable,
+ EsalVariableCommonEntry,
+ EsalGetNextVariableName,
+ EsalVariableCommonEntry,
+ EsalSetVariable,
+ NULL
+ );
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/IpfVariable.dxs b/EdkModulePkg/Universal/Variable/RuntimeDxe/IpfVariable.dxs new file mode 100644 index 0000000000..a11dae680c --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/IpfVariable.dxs @@ -0,0 +1,28 @@ +/*++
+
+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:
+
+ IpfVariable.dxs
+
+Abstract:
+
+ Dependency expression source file.
+
+--*/
+#include <AutoGen.h>
+#include <DxeDepex.h>
+
+DEPENDENCY_START
+ EXTENDED_SAL_BOOT_SERVICE_PROTOCOL_GUID AND
+ EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID AND
+ EFI_FTW_LITE_PROTOCOL_GUID
+DEPENDENCY_END
\ No newline at end of file diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c new file mode 100644 index 0000000000..0d91520d97 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -0,0 +1,1311 @@ +/*++
+
+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.c
+
+Abstract:
+
+Revision History
+
+--*/
+
+#include "Variable.h"
+#include "reclaim.h"
+
+//
+// Don't use module globals after the SetVirtualAddress map is signaled
+//
+ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal;
+
+UINT32
+EFIAPI
+ArrayLength (
+ IN CHAR16 *String
+ )
+/*++
+
+Routine Description:
+
+ Determine the length of null terminated char16 array.
+
+Arguments:
+
+ String Null-terminated CHAR16 array pointer.
+
+Returns:
+
+ UINT32 Number of bytes in the string, including the double NULL at the end;
+
+--*/
+{
+ UINT32 Count;
+
+ if (NULL == String) {
+ return 0;
+ }
+
+ Count = 0;
+
+ while (0 != String[Count]) {
+ Count++;
+ }
+
+ return (Count * 2) + 2;
+}
+
+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;
+}
+
+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->FvBlockMap; 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->BlockLength)) {
+ if ((CurrWritePtr + CurrWriteSize) <= (LinearOffset + PtrBlockMapEntry->BlockLength)) {
+ Status = EfiFvbWriteBlock (
+ Instance,
+ LbaNumber,
+ (UINTN) (CurrWritePtr - LinearOffset),
+ &CurrWriteSize,
+ CurrBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ } else {
+ Size = (UINT32) (LinearOffset + PtrBlockMapEntry->BlockLength - CurrWritePtr);
+ Status = EfiFvbWriteBlock (
+ Instance,
+ LbaNumber,
+ (UINTN) (CurrWritePtr - LinearOffset),
+ &Size,
+ CurrBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CurrWritePtr = LinearOffset + PtrBlockMapEntry->BlockLength;
+ CurrBuffer = CurrBuffer + Size;
+ CurrWriteSize = CurrWriteSize - Size;
+ }
+ }
+
+ LinearOffset += PtrBlockMapEntry->BlockLength;
+ LbaNumber++;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+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;
+ }
+}
+
+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));
+}
+
+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));
+}
+
+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);
+}
+
+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;
+ }
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ ValidBufferSize,
+ (VOID **) &ValidBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ 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;
+ }
+ }
+
+ gBS->FreePool (ValidBuffer);
+
+ if (EFI_ERROR (Status)) {
+ *LastVariableOffset = 0;
+ }
+
+ return Status;
+}
+
+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;
+
+ //
+ // 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]), ArrayLength (VariableName))) {
+ 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)) {
+ return Status;
+ }
+ //
+ // Get data size
+ //
+ VarDataSize = Variable.CurrPtr->DataSize;
+ if (*DataSize >= VarDataSize) {
+ if (Data == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CopyMem (Data, GetVariableDataPtr (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
+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)) {
+ return Status;
+ }
+
+ 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 {
+ return EFI_NOT_FOUND;
+ }
+
+ 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;
+ return Status;
+ }
+ }
+
+ Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+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) {
+ return Status;
+ }
+ //
+ // 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.
+ //
+ else if (sizeof (VARIABLE_HEADER) + ArrayLength (VariableName) + DataSize > MAX_VARIABLE_SIZE) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Make sure if runtime bit is set, boot service bit is set also
+ //
+ else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Runtime but Attribute is not Runtime
+ //
+ else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Cannot set volatile variable in Runtime
+ //
+ else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Setting a data variable with no access, or zero DataSize attributes
+ // specified causes it to be deleted.
+ //
+ else if (DataSize == 0 || Attributes == 0) {
+ 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)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+ } 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)
+ ) {
+ return EFI_SUCCESS;
+ } 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)) {
+ return Status;
+ }
+ }
+ }
+ //
+ // 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 = ArrayLength (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 ()) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Perform garbage collection & reclaim operation
+ //
+ Status = Reclaim (Global->NonVolatileVariableBase, NonVolatileOffset, FALSE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // If still no enough space, return out of resources
+ //
+ if ((UINT32) (VarSize +*NonVolatileOffset) >
+ ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size
+ ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ 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)) {
+ return Status;
+ }
+ //
+ // 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)) {
+ return Status;
+ }
+ //
+ // Step 3:
+ //
+ NextVariable->State = VAR_ADDED;
+ Status = UpdateVariableStore (
+ Global,
+ FALSE,
+ TRUE,
+ Instance,
+ *NonVolatileOffset,
+ sizeof (VARIABLE_HEADER),
+ (UINT8 *) NextVariable
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *NonVolatileOffset = *NonVolatileOffset + VarSize;
+
+ } else {
+ if (EfiAtRuntime ()) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ 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)) {
+ return Status;
+ }
+ //
+ // If still no enough space, return out of resources
+ //
+ if ((UINT32) (VarSize +*VolatileOffset) >
+ ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size
+ ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Reclaimed = TRUE;
+ }
+
+ NextVariable->State = VAR_ADDED;
+ Status = UpdateVariableStore (
+ Global,
+ TRUE,
+ TRUE,
+ Instance,
+ *VolatileOffset,
+ (UINT32) VarSize,
+ (UINT8 *) NextVariable
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *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)) {
+ return Status;
+ }
+ }
+ }
+
+ 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;
+
+ EFI_FLASH_MAP_ENTRY_DATA *FlashMapEntryData;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
+ EFI_FLASH_SUBAREA_ENTRY VariableStoreEntry;
+ UINT64 BaseAddress;
+ UINT64 Length;
+ UINTN Index;
+ UINT8 Data;
+ EFI_PEI_HOB_POINTERS GuidHob;
+
+ Status = gBS->AllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (ESAL_VARIABLE_GLOBAL),
+ (VOID **) &mVariableModuleGlobal
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Allocate memory for volatile variable store
+ //
+ Status = gBS->AllocatePool (
+ EfiRuntimeServicesData,
+ VARIABLE_STORE_SIZE + SCRATCH_SIZE,
+ (VOID **) &VolatileVariableStore
+ );
+
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (mVariableModuleGlobal);
+ return Status;
+ }
+
+ SetMem (VolatileVariableStore, VARIABLE_STORE_SIZE + SCRATCH_SIZE, 0xff);
+
+ //
+ // Variable Specific Data
+ //
+ mVariableModuleGlobal->VariableBase[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
+ //
+
+ FlashMapEntryData = NULL;
+
+ GuidHob.Raw = GetHobList ();
+ while (NULL != (GuidHob.Raw = GetNextGuidHob (&gEfiFlashMapHobGuid, GuidHob.Raw))) {
+ FlashMapEntryData = (EFI_FLASH_MAP_ENTRY_DATA *) GET_GUID_HOB_DATA (GuidHob.Guid);
+
+ if (FlashMapEntryData->AreaType == EFI_FLASH_AREA_EFI_VARIABLES) {
+ break;
+ }
+ GuidHob.Raw = GET_NEXT_HOB (GuidHob);
+ }
+
+ if (NULL == GuidHob.Raw || FlashMapEntryData == NULL) {
+ gBS->FreePool (mVariableModuleGlobal);
+ gBS->FreePool (VolatileVariableStore);
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Currently only one non-volatile variable store is supported
+ //
+ if (FlashMapEntryData->NumEntries != 1) {
+ gBS->FreePool (mVariableModuleGlobal);
+ gBS->FreePool (VolatileVariableStore);
+ return EFI_UNSUPPORTED;
+ }
+
+ CopyMem (&VariableStoreEntry, &FlashMapEntryData->Entries[0], sizeof (VariableStoreEntry));
+
+ //
+ // 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)) {
+ gBS->FreePool (mVariableModuleGlobal);
+ gBS->FreePool (VolatileVariableStore);
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = gDS->SetMemorySpaceAttributes (
+ BaseAddress,
+ Length,
+ GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (mVariableModuleGlobal);
+ gBS->FreePool (VolatileVariableStore);
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Get address of non volatile variable store base
+ //
+ mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase = VariableStoreEntry.Base;
+
+ //
+ // Check Integrity
+ //
+ //
+ // Find the Correct Instance of the FV Block Service.
+ //
+ Instance = 0;
+ CurrPtr = (CHAR8 *) ((UINTN) mVariableModuleGlobal->VariableBase[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->VariableBase[Physical],
+ FALSE,
+ FALSE,
+ mVariableModuleGlobal->FvbInstance,
+ (UINTN) &VariableStoreHeader->Size,
+ sizeof (UINT32),
+ (UINT8 *) &VariableStoreEntry.Length
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ mVariableModuleGlobal->VariableBase[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 really free.
+ //
+ for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < VariableStoreHeader->Size; Index++) {
+ Data = ((UINT8 *) (UINTN) mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase)[Index];
+ if (Data != 0xff) {
+ //
+ // There must be something wrong in variable store, do reclaim operation.
+ //
+ Status = Reclaim (
+ mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase,
+ &mVariableModuleGlobal->NonVolatileLastVariableOffset,
+ FALSE
+ );
+ break;
+ }
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (mVariableModuleGlobal);
+ gBS->FreePool (VolatileVariableStore);
+ }
+
+ return Status;
+}
diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.h new file mode 100644 index 0000000000..d1fd5e271e --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.h @@ -0,0 +1,143 @@ +/*++
+
+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.h
+
+Abstract:
+
+--*/
+
+#ifndef _VARIABLE_H
+#define _VARIABLE_H
+
+//
+// Statements that include other header files
+//
+
+//
+// BugBug: We need relcate the head file.
+//
+#include <Common/Variable.h>
+
+#if defined (MDE_CPU_IPF)
+#define ALIGNMENT 8
+#else
+#define ALIGNMENT 1
+#endif
+
+
+#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;
+} VARIABLE_GLOBAL;
+
+typedef struct {
+ VARIABLE_GLOBAL VariableBase[2];
+ UINTN VolatileLastVariableOffset;
+ UINTN NonVolatileLastVariableOffset;
+ UINT32 FvbInstance;
+} ESAL_VARIABLE_GLOBAL;
+
+//
+// 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
+ )
+;
+
+#endif
diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.mbd b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.mbd new file mode 100644 index 0000000000..6a5be9d885 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.mbd @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MbdHeader>
+ <BaseName>Variable</BaseName>
+ <Guid>CBD2E4D5-7068-4FF5-B462-9822B4AD8D60</Guid>
+ <Version>0</Version>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ 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.
+ </License>
+ <Created>2006-03-12 17:09</Created>
+ <Modified>2006-03-19 15:19</Modified>
+ </MbdHeader>
+ <Libraries>
+ <Library>UefiBootServicesTableLib</Library>
+ <Library>BaseLib</Library>
+ <Library>BaseMemoryLib</Library>
+ <Library>UefiLib</Library>
+ <Library>UefiDriverEntryPoint</Library>
+ <Library>DxeReportStatusCodeLib</Library>
+ <Library>DxeServicesTableLib</Library>
+ <Library>BaseDebugLibNull</Library>
+ <Library>BasePrintLib</Library>
+ <Library>EdkDxeRuntimeDriverLib</Library>
+ <Library>DxeHobLib</Library>
+ <Library>DxeMemoryAllocationLib</Library>
+ <Library>EdkFvbServiceLib</Library>
+ <Arch ArchType="IPF">
+ <Library>EdkDxeSalLib</Library>
+ </Arch>
+ </Libraries>
+ <BuildOptions ToolChain="MSFT">
+ <ImageEntryPoint>_ModuleEntryPoint</ImageEntryPoint>
+ </BuildOptions>
+</ModuleBuildDescription>
diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.msa b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.msa new file mode 100644 index 0000000000..a4399bc0d2 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.msa @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
+ <MsaHeader>
+ <BaseName>Variable</BaseName>
+ <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>
+ <ComponentType>RT_DRIVER</ComponentType>
+ <Guid>CBD2E4D5-7068-4FF5-B462-9822B4AD8D60</Guid>
+ <Version>0</Version>
+ <Abstract>Component description file for DiskIo module.</Abstract>
+ <Description>FIX ME!</Description>
+ <Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
+ <License>
+ 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.
+ </License>
+ <Specification>0</Specification>
+ <Created>2006-03-12 17:09</Created>
+ <Updated>2006-03-19 15:19</Updated>
+ </MsaHeader>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DxeServicesTableLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DxeRuntimeDriverLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">HobLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">EdkFvbServiceLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">EdkDxeSalLib</LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>Variable.c</Filename>
+ <Filename>Reclaim.c</Filename>
+ <Arch ArchType="IA32">
+ <Filename>InitVariable.c</Filename>
+ <Filename>Ia32Variable.dxs</Filename>
+ </Arch>
+ <Arch ArchType="X64">
+ <Filename>InitVariable.c</Filename>
+ <Filename>x64Variable.dxs</Filename>
+ </Arch>
+ <Arch ArchType="EBC">
+ <Filename>InitVariable.c</Filename>
+ <Filename>x64Variable.dxs</Filename>
+ </Arch>
+ <Arch ArchType="IPF">
+ <Filename>Ipf\InitVariable.c</Filename>
+ <Filename>IpfVariable.dxs</Filename>
+ </Arch>
+ </SourceFiles>
+ <Includes>
+ <PackageName>MdePkg</PackageName>
+ <PackageName>EdkModulePkg</PackageName>
+ </Includes>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">VariableWrite</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">FaultTolerantWriteLite</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">CpuIo</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">FvbExtension</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolumeBlock</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">Variable</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">VariableWrite</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">FaultTolerantWriteLite</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">CpuIo</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">FvbExtension</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">FirmwareVolumeBlock</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalBootService</Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">ExtendedSalVariableServices</Protocol>
+ </Protocols>
+ <Guids>
+ <GuidEntry Usage="ALWAYS_CONSUMED">
+ <C_Name>FlashMapHob</C_Name>
+ </GuidEntry>
+ <GuidEntry Usage="ALWAYS_CONSUMED">
+ <C_Name>Hob</C_Name>
+ </GuidEntry>
+ <GuidEntry Usage="ALWAYS_CONSUMED">
+ <C_Name>SystemNvData</C_Name>
+ </GuidEntry>
+ <GuidEntry Usage="ALWAYS_CONSUMED">
+ <C_Name>AlternateFvBlock</C_Name>
+ </GuidEntry>
+ </Guids>
+ <Externs>
+ <Extern>
+ <ModuleEntryPoint>VariableServiceInitialize</ModuleEntryPoint>
+ </Extern>
+ <Extern>
+ <SetVirtualAddressMapCallBack>VariableClassAddressChangeEvent</SetVirtualAddressMapCallBack>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/build.xml b/EdkModulePkg/Universal/Variable/RuntimeDxe/build.xml new file mode 100644 index 0000000000..4eba6a6933 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/build.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?><!-- 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.-->
+<project basedir="." default="Variable"><!--Apply external ANT tasks-->
+ <taskdef resource="GenBuild.tasks"/>
+ <taskdef resource="net/sf/antcontrib/antlib.xml"/>
+ <property environment="env"/>
+ <property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
+ <import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
+ <property name="MODULE_RELATIVE_PATH" value="Universal\Variable\RuntimeDxe"/>
+ <property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
+ <property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
+ <target name="Variable">
+ <GenBuild baseName="Variable" mbdFilename="${MODULE_DIR}\Variable.mbd" msaFilename="${MODULE_DIR}\Variable.msa"/>
+ </target>
+ <target depends="Variable_clean" name="clean"/>
+ <target depends="Variable_cleanall" name="cleanall"/>
+ <target name="Variable_clean">
+ <OutputDirSetup baseName="Variable" mbdFilename="${MODULE_DIR}\Variable.mbd" msaFilename="${MODULE_DIR}\Variable.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\Variable_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\Variable_build.xml" target="clean"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
+ </target>
+ <target name="Variable_cleanall">
+ <OutputDirSetup baseName="Variable" mbdFilename="${MODULE_DIR}\Variable.mbd" msaFilename="${MODULE_DIR}\Variable.msa"/>
+ <if>
+ <available file="${DEST_DIR_OUTPUT}\Variable_build.xml"/>
+ <then>
+ <ant antfile="${DEST_DIR_OUTPUT}\Variable_build.xml" target="cleanall"/>
+ </then>
+ </if>
+ <delete dir="${DEST_DIR_OUTPUT}"/>
+ <delete dir="${DEST_DIR_DEBUG}"/>
+ <delete>
+ <fileset dir="${BIN_DIR}" includes="**Variable*"/>
+ </delete>
+ </target>
+</project>
\ No newline at end of file diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.c b/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.c new file mode 100644 index 0000000000..a4bcdd67ce --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.c @@ -0,0 +1,240 @@ +/*++
+
+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:
+
+ reclaim.c
+
+Abstract:
+
+ Handles non-volatile variable store garbage collection, using FTW
+ (Fault Tolerant Write) protocol.
+
+Revision History
+
+--*/
+
+#include "reclaim.h"
+#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;
+ }
+ }
+
+ gBS->FreePool (HandleBuffer);
+ return Status;
+}
+
+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->FvBlockMap[0];
+ for (LbaIndex = 1; LbaIndex <= FvbMapEntry->NumBlocks; LbaIndex += 1) {
+ if (Address < (FvbBaseAddress + FvbMapEntry->BlockLength * LbaIndex)) {
+ //
+ // Found the (Lba, Offset)
+ //
+ *Lba = LbaIndex - 1;
+ *Offset = (UINTN) (Address - (FvbBaseAddress + FvbMapEntry->BlockLength * (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;
+ Status = gBS->AllocatePool (EfiRuntimeServicesData, FtwBufferSize, (VOID **) &FtwBuffer);
+ if (EFI_ERROR (Status)) {
+ 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
+ );
+
+ gBS->FreePool (FtwBuffer);
+ return Status;
+}
diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.h b/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.h new file mode 100644 index 0000000000..7bc1020ba3 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/reclaim.h @@ -0,0 +1,45 @@ +/*++
+
+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:
+
+ reclaim.h
+
+Abstract:
+
+ Definitions for non-volatile variable store garbage collection
+
+Revision History
+
+--*/
+
+#ifndef _VAR_RECLAIM_H
+#define _VAR_RECLAIM_H
+
+//
+// Functions
+//
+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/EdkModulePkg/Universal/Variable/RuntimeDxe/x64Variable.dxs b/EdkModulePkg/Universal/Variable/RuntimeDxe/x64Variable.dxs new file mode 100644 index 0000000000..c9f2f694e7 --- /dev/null +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/x64Variable.dxs @@ -0,0 +1,26 @@ +/*++
+
+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:
+
+ x64Variable.dxs
+
+Abstract:
+
+ Dependency expression source file.
+
+--*/
+#include <AutoGen.h>
+#include "DxeDepex.h"
+
+DEPENDENCY_START
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID AND EFI_ALTERNATE_FV_BLOCK_GUID
+DEPENDENCY_END
\ No newline at end of file |