/*++

Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

Module Name:

  FSVariable.c

Abstract:

  Provide support functions for variable services.

--*/

#include "FSVariable.h"

VARIABLE_STORE_HEADER mStoreHeaderTemplate = {
  VARIABLE_STORE_SIGNATURE,
  VOLATILE_VARIABLE_STORE_SIZE,
  VARIABLE_STORE_FORMATTED,
  VARIABLE_STORE_HEALTHY,
  0,
  0
};

//
// Don't use module globals after the SetVirtualAddress map is signaled
//
VARIABLE_GLOBAL  *mGlobal;

/**
  Update the variable region with Variable information. These are the same 
  arguments as the EFI Variable services.

  @param[in] VariableName       Name of variable

  @param[in] VendorGuid         Guid of variable

  @param[in] Data               Variable data

  @param[in] DataSize           Size of data. 0 means delete

  @param[in] Attributes 	      Attribues of the variable

  @param[in] Variable           The variable information which is used to keep track of variable usage.

  @retval EFI_SUCCESS           The update operation is success.

  @retval EFI_OUT_OF_RESOURCES  Variable region is full, can not write other data into this region.

**/
EFI_STATUS
EFIAPI
UpdateVariable (
  IN      CHAR16                 *VariableName,
  IN      EFI_GUID               *VendorGuid,
  IN      VOID                   *Data,
  IN      UINTN                  DataSize,
  IN      UINT32                 Attributes OPTIONAL,
  IN      VARIABLE_POINTER_TRACK *Variable
  );

VOID
EFIAPI
OnVirtualAddressChangeFsv (
  IN EFI_EVENT        Event,
  IN VOID             *Context
  );

VOID
EFIAPI
OnSimpleFileSystemInstall (
  IN EFI_EVENT        Event,
  IN VOID             *Context
  );

BOOLEAN
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) {
    return FALSE;
  }

  return TRUE;
}

VARIABLE_STORE_STATUS
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 (CompareGuid (&VarStoreHeader->Signature, &mStoreHeaderTemplate.Signature) &&
      (VarStoreHeader->Format == mStoreHeaderTemplate.Format) &&
      (VarStoreHeader->State == mStoreHeaderTemplate.State)
     ) {
    return EfiValid;
  } else if (((UINT32 *)(&VarStoreHeader->Signature))[0] == VAR_DEFAULT_VALUE_32 &&
             ((UINT32 *)(&VarStoreHeader->Signature))[1] == VAR_DEFAULT_VALUE_32 &&
             ((UINT32 *)(&VarStoreHeader->Signature))[2] == VAR_DEFAULT_VALUE_32 &&
             ((UINT32 *)(&VarStoreHeader->Signature))[3] == VAR_DEFAULT_VALUE_32 &&
             VarStoreHeader->Size == VAR_DEFAULT_VALUE_32 &&
             VarStoreHeader->Format == VAR_DEFAULT_VALUE &&
             VarStoreHeader->State == VAR_DEFAULT_VALUE
          ) {

    return EfiRaw;
  } else {
    return EfiInvalid;
  }
}

UINT8 *
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 *
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 *
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);
}

BOOLEAN
ExistNewerVariable (
  IN  VARIABLE_HEADER         *Variable
  )
/*++

Routine Description:

  Check if exist newer variable when doing reclaim

Arguments:

  Variable                    Pointer to start position

Returns:

  TRUE - Exists another variable, which is newer than the current one
  FALSE  - Doesn't exist another vairable which is newer than the current one

--*/
{
  VARIABLE_HEADER       *NextVariable;
  CHAR16                *VariableName;
  EFI_GUID              *VendorGuid;
  
  VendorGuid   = &Variable->VendorGuid;
  VariableName = GET_VARIABLE_NAME_PTR(Variable);
  
  NextVariable = GetNextVariablePtr (Variable);
  while (IsValidVariableHeader (NextVariable)) {
    if ((NextVariable->State == VAR_ADDED) || (NextVariable->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION))) {
      //
      // If match Guid and Name
      //
      if (CompareGuid (VendorGuid, &NextVariable->VendorGuid)) {
         if (CompareMem (VariableName, GET_VARIABLE_NAME_PTR (NextVariable), StrSize (VariableName)) == 0) {
           return TRUE;
         }
       }
    }
    NextVariable = GetNextVariablePtr (NextVariable);
  }
  return FALSE;
}

EFI_STATUS
Reclaim (
  IN  VARIABLE_STORAGE_TYPE StorageType,
  IN  VARIABLE_HEADER       *CurrentVariable OPTIONAL
  )
/*++

Routine Description:

  Variable store garbage collection and reclaim operation

Arguments:

  IsVolatile                  The variable store is volatile or not,
                              if it is non-volatile, need FTW
  CurrentVairable             If it is not NULL, it means not to process
                              current variable for Reclaim.

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 *) mGlobal->VariableBase[StorageType];

  //
  // Start Pointers for the variable.
  //
  Variable        = (VARIABLE_HEADER *) (VariableStoreHeader + 1);

  //
  // recaluate the total size of Common/HwErr type variables in non-volatile area.
  //
  if (!StorageType) {
    mGlobal->CommonVariableTotalSize = 0;
    mGlobal->HwErrVariableTotalSize  = 0;
  }
  //
  // To make the reclaim, here we just allocate a memory that equal to the original memory
  //
  ValidBufferSize = sizeof (VARIABLE_STORE_HEADER) + VariableStoreHeader->Size;

  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  ValidBufferSize,
                  (VOID**) &ValidBuffer
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  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);

  
  ValidBufferSize = sizeof (VARIABLE_STORE_HEADER);
  while (IsValidVariableHeader (Variable)) {
    NextVariable = GetNextVariablePtr (Variable);
    //
    // State VAR_ADDED or VAR_IN_DELETED_TRANSITION are to kept,
    // The CurrentVariable, is also saved, as SetVariable may fail due to lack of space
    //
    if (Variable->State == VAR_ADDED) {
      VariableSize = (UINTN) NextVariable - (UINTN) Variable;
      CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
      ValidBufferSize += VariableSize;
      CurrPtr += VariableSize;
      if ((!StorageType) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
        mGlobal->HwErrVariableTotalSize += VariableSize;
      } else if ((!StorageType) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
        mGlobal->CommonVariableTotalSize += VariableSize;
      }
    } else if (Variable->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION)) {
      //
      // As variables that with the same guid and name may exist in NV due to power failure during SetVariable,
      // we will only save the latest valid one
      //
      if (!ExistNewerVariable(Variable)) {
        VariableSize = (UINTN) NextVariable - (UINTN) Variable;
        CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
        //
        // If CurrentVariable == Variable, mark as VAR_IN_DELETED_TRANSITION
        //
        if (Variable != CurrentVariable){
          ((VARIABLE_HEADER *)CurrPtr)->State = VAR_ADDED;
        }
        CurrPtr += VariableSize;
        ValidBufferSize += VariableSize;
        if ((!StorageType) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
          mGlobal->HwErrVariableTotalSize += VariableSize;
        } else if ((!StorageType) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
          mGlobal->CommonVariableTotalSize += VariableSize;
        }
      }
    }
    Variable = NextVariable;
  }

  mGlobal->LastVariableOffset[StorageType] = ValidBufferSize;

  //
  // TODO: cannot restore to original state, basic FTW needed
  //
  Status = mGlobal->VariableStore[StorageType]->Erase (
                                                  mGlobal->VariableStore[StorageType]
                                                  );
  Status = mGlobal->VariableStore[StorageType]->Write (
                                                    mGlobal->VariableStore[StorageType],
                                                    0,
                                                    ValidBufferSize,
                                                    ValidBuffer
                                                    );

  if (EFI_ERROR (Status)) {
    //
    // If error, then reset the last variable offset to zero.
    //
    mGlobal->LastVariableOffset[StorageType] = 0;
  };

  gBS->FreePool (ValidBuffer);

  return Status;
}

EFI_STATUS
FindVariable (
  IN  CHAR16                  *VariableName,
  IN  EFI_GUID                *VendorGuid,
  OUT VARIABLE_POINTER_TRACK  *PtrTrack
  )
/*++

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.

Returns:

  EFI_INVALID_PARAMETER       - Invalid parameter
  EFI_SUCCESS                 - Find the specified variable
  EFI_NOT_FOUND               - Not found

--*/
{
  VARIABLE_HEADER         *Variable;
  VARIABLE_STORE_HEADER   *VariableStoreHeader;
  UINTN                   Index;
  VARIABLE_HEADER         *InDeleteVariable;
  UINTN                   InDeleteIndex;
  VARIABLE_HEADER         *InDeleteStartPtr;
  VARIABLE_HEADER         *InDeleteEndPtr;

  if (VariableName[0] != 0 && VendorGuid == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  InDeleteVariable = NULL;
  InDeleteIndex    = (UINTN)-1;
  InDeleteStartPtr = NULL;
  InDeleteEndPtr   = NULL;

  for (Index = 0; Index < MaxType; Index ++) {
    //
    // 0: Non-Volatile, 1: Volatile
    //
    VariableStoreHeader = (VARIABLE_STORE_HEADER *) mGlobal->VariableBase[Index];

    //
    // Start Pointers for the variable.
    // Actual Data Pointer where data can be written.
    //
    Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);

    //
    // Find the variable by walk through non-volatile and volatile variable store
    //
    PtrTrack->StartPtr = Variable;
    PtrTrack->EndPtr   = GetEndPointer (VariableStoreHeader);

    while ((Variable < PtrTrack->EndPtr) && IsValidVariableHeader (Variable)) {
      if (Variable->State == VAR_ADDED) {
        if (!EfiAtRuntime () || (Variable->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
          if (VariableName[0] == 0) {
            PtrTrack->CurrPtr = Variable;
            PtrTrack->Type    = (VARIABLE_STORAGE_TYPE) Index;
            return EFI_SUCCESS;
          } else {
            if (CompareGuid (VendorGuid, &Variable->VendorGuid)) {
              if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable), StrSize (VariableName))) {
                PtrTrack->CurrPtr = Variable;
                PtrTrack->Type    = (VARIABLE_STORAGE_TYPE) Index;
                return EFI_SUCCESS;
              }
            }
          }
        }
      } else if (Variable->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION)) {
        //
        // VAR_IN_DELETED_TRANSITION should also be checked.
        //
        if (!EfiAtRuntime () || (Variable->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
          if (VariableName[0] == 0) {
            InDeleteVariable = Variable;
            InDeleteIndex    = Index;
            InDeleteStartPtr = PtrTrack->StartPtr;
            InDeleteEndPtr   = PtrTrack->EndPtr;
          } else {
            if (CompareGuid (VendorGuid, &Variable->VendorGuid)) {
              if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable), StrSize (VariableName))) {
                InDeleteVariable = Variable;
                InDeleteIndex    = Index;
                InDeleteStartPtr = PtrTrack->StartPtr;
                InDeleteEndPtr   = PtrTrack->EndPtr;
              }
            }
          }
        }
      }

      Variable = GetNextVariablePtr (Variable);
    }
    //
    // While (...)
    //
  }
  //
  // for (...)
  //

  //
  // if VAR_IN_DELETED_TRANSITION found, and VAR_ADDED not found,
  // we return it.
  //
  if (InDeleteVariable != NULL) {
    PtrTrack->CurrPtr  = InDeleteVariable;
    PtrTrack->Type     = (VARIABLE_STORAGE_TYPE) InDeleteIndex;
    PtrTrack->StartPtr = InDeleteStartPtr;
    PtrTrack->EndPtr   = InDeleteEndPtr;
    return EFI_SUCCESS;
  }

  PtrTrack->CurrPtr = NULL;
  return EFI_NOT_FOUND;
}

/**
  Get index from supported language codes according to language string.

  This code is used to get corresponding index in supported language codes. It can handle
  RFC4646 and ISO639 language tags.
  In ISO639 language tags, take 3-characters as a delimitation to find matched string and calculate the index.
  In RFC4646 language tags, take semicolon as a delimitation to find matched string and calculate the index.

  For example:
    SupportedLang  = "engfraengfra"
    Lang           = "eng"
    Iso639Language = TRUE
  The return value is "0".
  Another example:
    SupportedLang  = "en;fr;en-US;fr-FR"
    Lang           = "fr-FR"
    Iso639Language = FALSE
  The return value is "3".

  @param  SupportedLang               Platform supported language codes.
  @param  Lang                        Configured language.
  @param  Iso639Language              A bool value to signify if the handler is operated on ISO639 or RFC4646.

  @retval the index of language in the language codes.

**/
UINTN
EFIAPI
GetIndexFromSupportedLangCodes(
  IN  CHAR8            *SupportedLang,
  IN  CHAR8            *Lang,
  IN  BOOLEAN          Iso639Language
  ) 
{
  UINTN    Index;
  UINT32   CompareLength;
  CHAR8    *Supported;

  Index = 0;
  Supported = SupportedLang;
  if (Iso639Language) {
    CompareLength = 3;
    for (Index = 0; Index < AsciiStrLen (SupportedLang); Index += CompareLength) {
      if (AsciiStrnCmp (Lang, SupportedLang + Index, CompareLength) == 0) {
        //
        // Successfully find the index of Lang string in SupportedLang string.
        //
        Index = Index / CompareLength;
        return Index;
      }
    }
    ASSERT (FALSE);
    return 0;
  } else {
    //
    // Compare RFC4646 language code
    //
    while (*Supported != '\0') {
      //
      // take semicolon as delimitation, sequentially traverse supported language codes.
      //
      for (CompareLength = 0; *Supported != ';' && *Supported != '\0'; CompareLength++) {
        Supported++;
      }
      if (AsciiStrnCmp (Lang, Supported - CompareLength, CompareLength) == 0) {
        //
        // Successfully find the index of Lang string in SupportedLang string.
        //
        return Index;
      }
      Index++;
    }
    ASSERT (FALSE);
    return 0;
  }
}

/**
  Get language string from supported language codes according to index.

  This code is used to get corresponding language string in supported language codes. It can handle
  RFC4646 and ISO639 language tags.
  In ISO639 language tags, take 3-characters as a delimitation. Find language string according to the index.
  In RFC4646 language tags, take semicolon as a delimitation. Find language string according to the index.

  For example:
    SupportedLang  = "engfraengfra"
    Index          = "1"
    Iso639Language = TRUE
  The return value is "fra".
  Another example:
    SupportedLang  = "en;fr;en-US;fr-FR"
    Index          = "1"
    Iso639Language = FALSE
  The return value is "fr".

  @param  SupportedLang               Platform supported language codes.
  @param  Index                       the index in supported language codes.
  @param  Iso639Language              A bool value to signify if the handler is operated on ISO639 or RFC4646.

  @retval the language string in the language codes.

**/
CHAR8 *
EFIAPI
GetLangFromSupportedLangCodes (
  IN  CHAR8            *SupportedLang,
  IN  UINTN            Index,
  IN  BOOLEAN          Iso639Language
)
{
  UINTN    SubIndex;
  UINT32   CompareLength;
  CHAR8    *Supported;

  SubIndex  = 0;
  Supported = SupportedLang;
  if (Iso639Language) {
    //
    // according to the index of Lang string in SupportedLang string to get the language.
    // As this code will be invoked in RUNTIME, therefore there is not memory allocate/free operation.
    // In driver entry, it pre-allocates a runtime attribute memory to accommodate this string.
    //
    CompareLength = 3;
    SetMem (mGlobal->Lang, sizeof(mGlobal->Lang), 0);
    return CopyMem (mGlobal->Lang, SupportedLang + Index * CompareLength, CompareLength);
      
  } else {
    while (TRUE) {
      //
      // take semicolon as delimitation, sequentially traverse supported language codes.
      //
      for (CompareLength = 0; *Supported != ';' && *Supported != '\0'; CompareLength++) {
        Supported++;
      }
      if ((*Supported == '\0') && (SubIndex != Index)) {
        //
        // Have completed the traverse, but not find corrsponding string.
        // This case is not allowed to happen.
        //
        ASSERT(FALSE);
        return NULL;
      }
      if (SubIndex == Index) {
        //
        // according to the index of Lang string in SupportedLang string to get the language.
        // As this code will be invoked in RUNTIME, therefore there is not memory allocate/free operation.
        // In driver entry, it pre-allocates a runtime attribute memory to accommodate this string.
        //
        SetMem (mGlobal->PlatformLang, sizeof (mGlobal->PlatformLang), 0);
        return CopyMem (mGlobal->PlatformLang, Supported - CompareLength, CompareLength);
      }
      SubIndex++;
    }
  }
}

/**
  Hook the operations in PlatformLangCodes, LangCodes, PlatformLang and Lang.

  When setting Lang/LangCodes, simultaneously update PlatformLang/PlatformLangCodes.

  According to UEFI spec, PlatformLangCodes/LangCodes are only set once in firmware initialization,
  and are read-only. Therefore, in variable driver, only store the original value for other use.

  @param[in] VariableName       Name of variable

  @param[in] Data               Variable data

  @param[in] DataSize           Size of data. 0 means delete

  @retval EFI_SUCCESS  auto update operation is successful.

**/
EFI_STATUS
EFIAPI
AutoUpdateLangVariable(
  IN  CHAR16             *VariableName,
  IN  VOID               *Data,
  IN  UINTN              DataSize
  )
{
  EFI_STATUS     Status;
  CHAR8          *BestPlatformLang;
  CHAR8          *BestLang;
  UINTN          Index;
  UINT32         Attributes;
  VARIABLE_POINTER_TRACK Variable;

  //
  // According to UEFI spec, "Lang" and "PlatformLang" is NV|BS|RT attributions.
  //
  Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;

  if (StrCmp (VariableName, L"PlatformLangCodes") == 0) {
    //
    // According to UEFI spec, PlatformLangCodes is only set once in firmware initialization, and is read-only
    // Therefore, in variable driver, only store the original value for other use.
    //
    AsciiStrnCpy (mGlobal->PlatformLangCodes, Data, DataSize);
  } else if (StrCmp (VariableName, L"LangCodes") == 0) {
    //
    // According to UEFI spec, LangCodes is only set once in firmware initialization, and is read-only
    // Therefore, in variable driver, only store the original value for other use.
    //
    AsciiStrnCpy (mGlobal->LangCodes, Data, DataSize);
  } else if (StrCmp (VariableName, L"PlatformLang") == 0) {
    ASSERT (AsciiStrLen (mGlobal->PlatformLangCodes) != 0);

    //
    // When setting PlatformLang, firstly get most matched language string from supported language codes.
    //
    BestPlatformLang = GetBestLanguage(mGlobal->PlatformLangCodes, FALSE, Data, NULL);

    //
    // Get the corresponding index in language codes.
    //
    Index = GetIndexFromSupportedLangCodes(mGlobal->PlatformLangCodes, BestPlatformLang, FALSE);

    //
    // Get the corresponding ISO639 language tag according to RFC4646 language tag.
    //
    BestLang = GetLangFromSupportedLangCodes(mGlobal->LangCodes, Index, TRUE);

    //
    // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
    //
    FindVariable(L"Lang", &gEfiGlobalVariableGuid, &Variable);

    Status = UpdateVariable(L"Lang", &gEfiGlobalVariableGuid, 
                    BestLang, ISO_639_2_ENTRY_SIZE + 1, Attributes, &Variable);

    DEBUG((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a\n", BestPlatformLang, BestLang));

    ASSERT_EFI_ERROR(Status);
    
  } else if (StrCmp (VariableName, L"Lang") == 0) {
    ASSERT (AsciiStrLen (mGlobal->LangCodes) != 0);

    //
    // When setting Lang, firstly get most matched language string from supported language codes.
    //
    BestLang = GetBestLanguage(mGlobal->LangCodes, TRUE, Data, NULL);

    //
    // Get the corresponding index in language codes.
    //
    Index = GetIndexFromSupportedLangCodes(mGlobal->LangCodes, BestLang, TRUE);

    //
    // Get the corresponding RFC4646 language tag according to ISO639 language tag.
    //
    BestPlatformLang = GetLangFromSupportedLangCodes(mGlobal->PlatformLangCodes, Index, FALSE);

    //
    // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
    //
    FindVariable(L"PlatformLang", &gEfiGlobalVariableGuid, &Variable);

    Status = UpdateVariable(L"PlatformLang", &gEfiGlobalVariableGuid, 
                    BestPlatformLang, AsciiStrSize (BestPlatformLang), Attributes, &Variable);

    DEBUG((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a\n", BestLang, BestPlatformLang));
    ASSERT_EFI_ERROR(Status);
  }
  return EFI_SUCCESS;
}

/**
  Update the variable region with Variable information. These are the same 
  arguments as the EFI Variable services.

  @param[in] VariableName       Name of variable

  @param[in] VendorGuid         Guid of variable

  @param[in] Data               Variable data

  @param[in] DataSize           Size of data. 0 means delete

  @param[in] Attributes 	      Attribues of the variable

  @param[in] Variable           The variable information which is used to keep track of variable usage.

  @retval EFI_SUCCESS           The update operation is success.

  @retval EFI_OUT_OF_RESOURCES  Variable region is full, can not write other data into this region.

**/
EFI_STATUS
EFIAPI
UpdateVariable (
  IN      CHAR16                 *VariableName,
  IN      EFI_GUID               *VendorGuid,
  IN      VOID                   *Data,
  IN      UINTN                  DataSize,
  IN      UINT32                 Attributes OPTIONAL,
  IN      VARIABLE_POINTER_TRACK *Variable
  )
{
  EFI_STATUS                          Status;
  VARIABLE_HEADER                     *NextVariable;
  UINTN                               VarNameOffset;
  UINTN                               VarDataOffset;
  UINTN                               VarNameSize;
  UINTN                               VarSize;
  UINT8                               State;
  BOOLEAN                             Reclaimed;
  VARIABLE_STORAGE_TYPE               StorageType;

  Reclaimed         = FALSE;

  if (Variable->CurrPtr != NULL) {  
    //
    // Update/Delete existing variable
    //
    
    if (EfiAtRuntime ()) {              
      //
      // If EfiAtRuntime and the variable is Volatile and Runtime Access,  
      // the volatile is ReadOnly, and SetVariable should be aborted and 
      // return EFI_WRITE_PROTECTED.
      //
      if (Variable->Type == Volatile) {
        return EFI_WRITE_PROTECTED;
      }
      //
      // Only variable have NV attribute can be updated/deleted in Runtime
      //
      if (!(Variable->CurrPtr->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.
    //
    if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {
      //
      // Found this variable in storage
      //
      State = Variable->CurrPtr->State;
      State &= VAR_DELETED;

      Status = mGlobal->VariableStore[Variable->Type]->Write (
                                                        mGlobal->VariableStore[Variable->Type],
                                                        VARIABLE_MEMBER_OFFSET (State, (UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr),
                                                        sizeof (Variable->CurrPtr->State),
                                                        &State
                                                        );
      //
      // NOTE: Write operation at least can write data to memory cache
      //       Discard file writing failure here.
      //
      return EFI_SUCCESS;
    }
    
    //
    // Found this variable in storage
    // 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) == 0)
          ) {
      return EFI_SUCCESS;
    } else if ((Variable->CurrPtr->State == VAR_ADDED) ||
               (Variable->CurrPtr->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION))) {
      //
      // Mark the old variable as in delete transition
      //
      State = Variable->CurrPtr->State;
      State &= VAR_IN_DELETED_TRANSITION;

      Status = mGlobal->VariableStore[Variable->Type]->Write (
                                                        mGlobal->VariableStore[Variable->Type],
                                                        VARIABLE_MEMBER_OFFSET (State, (UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr),
                                                        sizeof (Variable->CurrPtr->State),
                                                        &State
                                                        );
      //
      // NOTE: Write operation at least can write data to memory cache
      //       Discard file writing failure here.
      //
    }
  } else {
    //
    // Create a new variable
    //  
    
    //
    // Make sure we are trying to create a new variable.
    // Setting a data variable with no access, or zero DataSize attributes means to delete it.    
    //
    if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {
      return EFI_NOT_FOUND;
    }    
    //
    // Only variable have NV|RT attribute can be created in Runtime
    //
    if (EfiAtRuntime () &&
        (!(Attributes & EFI_VARIABLE_RUNTIME_ACCESS) || !(Attributes & EFI_VARIABLE_NON_VOLATILE))) {
      return EFI_INVALID_PARAMETER;
    }        
    
  } 

  //
  // Function part - create a new variable and copy the data.
  // Both update a variable and create a variable will come here.  
  // We can firstly write all the data in memory, then write them to file
  // This can reduce the times of write operation
  //
  
  NextVariable = (VARIABLE_HEADER *) mGlobal->Scratch;

  NextVariable->StartId     = VARIABLE_DATA;
  NextVariable->Attributes  = Attributes;
  NextVariable->State       = VAR_ADDED;
  NextVariable->Reserved    = 0;
  VarNameOffset             = sizeof (VARIABLE_HEADER);
  VarNameSize               = StrSize (VariableName);
  CopyMem (
    (UINT8 *) ((UINTN) NextVariable + VarNameOffset),
    VariableName,
    VarNameSize
    );
  VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize);
  CopyMem (
    (UINT8 *) ((UINTN) NextVariable + VarDataOffset),
    Data,
    DataSize
    );
  CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));
  //
  // There will be pad bytes after Data, the NextVariable->NameSize and
  // NextVariable->DataSize should not include pad size so that variable
  // service can get actual size in GetVariable
  //
  NextVariable->NameSize  = (UINT32)VarNameSize;
  NextVariable->DataSize  = (UINT32)DataSize;

  //
  // The actual size of the variable that stores in storage should
  // include pad size.
  // VarDataOffset: offset from begin of current variable header
  //
  VarSize = VarDataOffset + DataSize + GET_PAD_SIZE (DataSize);

  StorageType = (Attributes & EFI_VARIABLE_NON_VOLATILE) ? NonVolatile : Volatile;

  if ((UINT32) (VarSize + mGlobal->LastVariableOffset[StorageType]) >
      ((VARIABLE_STORE_HEADER *) mGlobal->VariableBase[StorageType])->Size
      ) {
    if ((StorageType == NonVolatile) && EfiAtRuntime ()) {
      return EFI_OUT_OF_RESOURCES;
    }
    //
    // Perform garbage collection & reclaim operation
    //
    Status = Reclaim (StorageType, Variable->CurrPtr);
    if (EFI_ERROR (Status)) {
      //
      // Reclaim error
      // we cannot restore to original state, fetal error, report to user
      //
      DEBUG ((EFI_D_ERROR, "FSVariable: Recalim error (fetal error) - %r\n", Status));
      return Status;
    }
    //
    // If still no enough space, return out of resources
    //
    if ((UINT32) (VarSize + mGlobal->LastVariableOffset[StorageType]) >
        ((VARIABLE_STORE_HEADER *) mGlobal->VariableBase[StorageType])->Size
       ) {
      return EFI_OUT_OF_RESOURCES;
    }

    Reclaimed = TRUE;
  }
  Status = mGlobal->VariableStore[StorageType]->Write (
                                                  mGlobal->VariableStore[StorageType],
                                                  mGlobal->LastVariableOffset[StorageType],
                                                  VarSize,
                                                  NextVariable
                                                  );
  //
  // NOTE: Write operation at least can write data to memory cache
  //       Discard file writing failure here.
  //
  mGlobal->LastVariableOffset[StorageType] += VarSize;

  if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) {
    mGlobal->HwErrVariableTotalSize += VarSize;
  } else {
    mGlobal->CommonVariableTotalSize += VarSize;
  }

  //
  // Mark the old variable as deleted
  //
  if (!Reclaimed && !EFI_ERROR (Status) && Variable->CurrPtr != NULL) {
    State = Variable->CurrPtr->State;
    State &= VAR_DELETED;

    Status = mGlobal->VariableStore[StorageType]->Write (
                                                    mGlobal->VariableStore[StorageType],
                                                    VARIABLE_MEMBER_OFFSET (State, (UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr),
                                                    sizeof (Variable->CurrPtr->State),
                                                    &State
                                                    );
    //
    // NOTE: Write operation at least can write data to memory cache
    //       Discard file writing failure here.
    //
  }
  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
DuetGetVariable (
  IN      CHAR16            *VariableName,
  IN      EFI_GUID          *VendorGuid,
  OUT     UINT32            *Attributes OPTIONAL,
  IN OUT  UINTN             *DataSize,
  OUT     VOID              *Data
  )
/*++

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

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);

  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
  )
/*++

Routine Description:

  This code Finds the Next available variable

Arguments:

  VariableNameSize            Size of the variable
  VariableName                Pointer to variable name
  VendorGuid                  Variable Vendor Guid

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);

  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) {
    //
    // The order we find variable is: 1). NonVolatile; 2). Volatile
    // If both volatile and non-volatile variable store are parsed,
    // return not found
    //
    if (Variable.CurrPtr >= Variable.EndPtr || Variable.CurrPtr == NULL) {
      if (Variable.Type == Volatile) {
        //
        // Since we met the end of Volatile storage, we have parsed all the stores.
        //
        return EFI_NOT_FOUND;
      }

      //
      // End of NonVolatile, continue to parse Volatile
      //
      Variable.Type = Volatile;
      Variable.StartPtr = (VARIABLE_HEADER *) ((VARIABLE_STORE_HEADER *) mGlobal->VariableBase[Volatile] + 1);
      Variable.EndPtr   = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) mGlobal->VariableBase[Volatile]);

      Variable.CurrPtr = Variable.StartPtr;
      if (!IsValidVariableHeader (Variable.CurrPtr)) {
        continue;
      }
    }
    //
    // Variable is found
    //
    if (IsValidVariableHeader (Variable.CurrPtr) &&
        ((Variable.CurrPtr->State == VAR_ADDED) ||
         (Variable.CurrPtr->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION)))) {
      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);
  }
}

EFI_STATUS
EFIAPI
SetVariable (
  IN CHAR16                  *VariableName,
  IN EFI_GUID                *VendorGuid,
  IN UINT32                  Attributes,
  IN UINTN                   DataSize,
  IN VOID                    *Data
  )
/*++

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

Returns:
  
  EFI_INVALID_PARAMETER           - Invalid parameter
  EFI_SUCCESS                     - Set successfully
  EFI_OUT_OF_RESOURCES            - Resource not enough to set variable
  EFI_NOT_FOUND                   - Not found
  EFI_DEVICE_ERROR                - Variable can not be saved due to hardware failure
  EFI_WRITE_PROTECTED             - Variable is read-only

--*/
{
  VARIABLE_POINTER_TRACK  Variable;
  EFI_STATUS              Status;

  //
  // Check input parameters
  // 
  if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  
  //
  //  Make sure if runtime bit is set, boot service bit is set also
  //
  if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
    return EFI_INVALID_PARAMETER;
  }
  
  //
  //  The size of the VariableName, including the Unicode Null in bytes plus
  //  the DataSize is limited to maximum size of FixedPcdGet32(PcdMaxHardwareErrorVariableSize)
  //  bytes for HwErrRec, and FixedPcdGet32(PcdMaxVariableSize) bytes for the others.
  //
  if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
    if ((DataSize > FixedPcdGet32(PcdMaxHardwareErrorVariableSize)) ||                                                       
        (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > FixedPcdGet32(PcdMaxHardwareErrorVariableSize))) {
      return EFI_INVALID_PARAMETER;
    }
    //
    // According to UEFI spec, HARDWARE_ERROR_RECORD variable name convention should be L"HwErrRecXXXX"
    //
    if (StrnCmp(VariableName, L"HwErrRec", StrLen(L"HwErrRec")) != 0) {
      return EFI_INVALID_PARAMETER;
    }
  } else {
    if ((DataSize > FixedPcdGet32(PcdMaxVariableSize)) ||
        (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > FixedPcdGet32(PcdMaxVariableSize))) {
      return EFI_INVALID_PARAMETER;
    }  
  }  

  //
  // Check whether the input variable is already existed
  //
  Status = FindVariable (VariableName, VendorGuid, &Variable);

  //
  // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang
  //
  AutoUpdateLangVariable (VariableName, Data, DataSize);

  Status = UpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes, &Variable);

  return Status;
}

EFI_STATUS
EFIAPI
QueryVariableInfo (
  IN  UINT32                 Attributes,
  OUT UINT64                 *MaximumVariableStorageSize,
  OUT UINT64                 *RemainingVariableStorageSize,
  OUT UINT64                 *MaximumVariableSize
  )
/*++

Routine Description:

  This code returns information about the EFI variables.

Arguments:

  Attributes                      Attributes bitmask to specify the type of variables
                                  on which to return information.
  MaximumVariableStorageSize      Pointer to the maximum size of the storage space available
                                  for the EFI variables associated with the attributes specified.
  RemainingVariableStorageSize    Pointer to the remaining size of the storage space available
                                  for the EFI variables associated with the attributes specified.
  MaximumVariableSize             Pointer to the maximum size of the individual EFI variables
                                  associated with the attributes specified.

Returns:

  EFI STATUS
  EFI_INVALID_PARAMETER           - An invalid combination of attribute bits was supplied.
  EFI_SUCCESS                     - Query successfully.
  EFI_UNSUPPORTED                 - The attribute is not supported on this platform.

--*/
{
  VARIABLE_HEADER        *Variable;
  VARIABLE_HEADER        *NextVariable;
  UINT64                 VariableSize;
  VARIABLE_STORE_HEADER  *VariableStoreHeader;
  UINT64                 CommonVariableTotalSize;
  UINT64                 HwErrVariableTotalSize;

  CommonVariableTotalSize = 0;
  HwErrVariableTotalSize = 0;

  if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
    return EFI_INVALID_PARAMETER;
  }
  
  if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
    //
    // Make sure the Attributes combination is supported by the platform.
    //
    return EFI_UNSUPPORTED;  
  }  
  else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
    //
    // Make sure if runtime bit is set, boot service bit is set also.
    //
    return EFI_INVALID_PARAMETER;
  } else if (EfiAtRuntime () && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
    //
    // Make sure RT Attribute is set if we are in Runtime phase.
    //
    return EFI_INVALID_PARAMETER;
  } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
    //
    // Make sure Hw Attribute is set with NV.
    //
    return EFI_INVALID_PARAMETER;
  }
  
  VariableStoreHeader = (VARIABLE_STORE_HEADER *) mGlobal->VariableBase[
                                (Attributes & EFI_VARIABLE_NON_VOLATILE) ? NonVolatile : Volatile
                                ];
  //
  // Now let's fill *MaximumVariableStorageSize *RemainingVariableStorageSize
  // with the storage size (excluding the storage header size).
  //
  *MaximumVariableStorageSize   = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER);

  //
  // Harware error record variable needs larger size.
  //
  if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
    *MaximumVariableStorageSize = FixedPcdGet32(PcdHwErrStorageSize);
    *MaximumVariableSize = FixedPcdGet32(PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER);
  } else {
    if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
      ASSERT (FixedPcdGet32(PcdHwErrStorageSize) < VariableStoreHeader->Size);
      *MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - FixedPcdGet32(PcdHwErrStorageSize);
    }

    //
    // Let *MaximumVariableSize be FixedPcdGet32(PcdMaxVariableSize) with the exception of the variable header size.
    //
    *MaximumVariableSize = FixedPcdGet32(PcdMaxVariableSize) - sizeof (VARIABLE_HEADER);
  }
  
  //
  // Point to the starting address of the variables.
  //
  Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);

  //
  // Now walk through the related variable store.
  //
  while ((Variable < GetEndPointer (VariableStoreHeader)) && IsValidVariableHeader (Variable)) {
    NextVariable = GetNextVariablePtr (Variable);
    VariableSize = (UINT64) (UINTN) NextVariable - (UINT64) (UINTN) Variable;

    if (EfiAtRuntime ()) {
      //
      // we don't take the state of the variables in mind
      // when calculating RemainingVariableStorageSize,
      // since the space occupied by variables not marked with
      // VAR_ADDED is not allowed to be reclaimed in Runtime.
      //
      if ((NextVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
        HwErrVariableTotalSize += VariableSize;
      } else {
        CommonVariableTotalSize += VariableSize;
      }
    } else {
      //
      // Only care about Variables with State VAR_ADDED,because
      // the space not marked as VAR_ADDED is reclaimable now.
      //
      if ((Variable->State == VAR_ADDED) || (Variable->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION))) {
        if ((NextVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
          HwErrVariableTotalSize += VariableSize;
        } else {
          CommonVariableTotalSize += VariableSize;
        }
      }
    }

    //
    // Go to the next one
    //
    Variable = NextVariable;
  }
  
  if ((Attributes  & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD){
    *RemainingVariableStorageSize = *MaximumVariableStorageSize - HwErrVariableTotalSize;
  } else {
    *RemainingVariableStorageSize = *MaximumVariableStorageSize - CommonVariableTotalSize;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
VariableServiceInitialize (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
/*++

Routine Description:
  This function does 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_SUCCESS       - Variable services successfully initialized.

--*/
{
  EFI_STATUS                      Status;
  EFI_HANDLE                      NewHandle;
  VS_DEV                          *Dev;
  EFI_PEI_HOB_POINTERS            GuidHob;
  VARIABLE_HEADER                 *Variable;
  VARIABLE_HEADER                 *NextVariable;
  VARIABLE_STORE_HEADER           *VariableStoreHeader;
  EFI_FLASH_MAP_FS_ENTRY_DATA     *FlashMapEntryData;
  EFI_FLASH_SUBAREA_ENTRY         VariableStoreEntry;
  UINT64                          BaseAddress;
  UINT64                          Length;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;

  Status = gBS->AllocatePool (
                  EfiRuntimeServicesData,
                  (UINTN) sizeof (VARIABLE_GLOBAL),
                  (VOID**) &mGlobal
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ZeroMem (mGlobal, (UINTN) sizeof (VARIABLE_GLOBAL));

  GuidHob.Raw = GetHobList ();
  FlashMapEntryData = NULL;
  while ((GuidHob.Raw = GetNextGuidHob (&gEfiFlashMapHobGuid, GuidHob.Raw)) != NULL) {
    FlashMapEntryData = (EFI_FLASH_MAP_FS_ENTRY_DATA *) GET_GUID_HOB_DATA (GuidHob.Guid);
    if (FlashMapEntryData->AreaType == EFI_FLASH_AREA_EFI_VARIABLES) {
      break;
    }
    GuidHob.Raw = GET_NEXT_HOB (GuidHob); 
  }

  if (FlashMapEntryData == NULL) {
    DEBUG ((EFI_D_ERROR, "FSVariable: Could not find flash area for variable!\n"));
    Status = EFI_NOT_FOUND;
    return Status;
  }
  
  CopyMem(
    (VOID*)&VariableStoreEntry,
    (VOID*)&FlashMapEntryData->Entries[0],
    sizeof(EFI_FLASH_SUBAREA_ENTRY)
    );

  //
  // 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)) {
    Status = EFI_UNSUPPORTED;
    return Status;
  }
  Status = gDS->SetMemorySpaceAttributes (
                  BaseAddress,
                  Length,
                  GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME
                  );
  if (EFI_ERROR (Status)) {
    Status = EFI_UNSUPPORTED;
    return Status;
  }

  Status = FileStorageConstructor (
             &mGlobal->VariableStore[NonVolatile], 
             &mGlobal->GoVirtualChildEvent[NonVolatile],
             VariableStoreEntry.Base,
             (UINT32) VariableStoreEntry.Length,
             FlashMapEntryData->VolumeId,
             FlashMapEntryData->FilePath
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Volatile Storage
  //
  Status = MemStorageConstructor (
             &mGlobal->VariableStore[Volatile],
             &mGlobal->GoVirtualChildEvent[Volatile],
             VOLATILE_VARIABLE_STORE_SIZE
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Scratch
  //
  Status = gBS->AllocatePool (
                  EfiRuntimeServicesData,
                  VARIABLE_SCRATCH_SIZE,
                  &mGlobal->Scratch
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // 1. NV Storage
  //
  Dev = DEV_FROM_THIS (mGlobal->VariableStore[NonVolatile]);
  VariableStoreHeader = (VARIABLE_STORE_HEADER *) VAR_DATA_PTR (Dev);
  if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {
    if (~VariableStoreHeader->Size == 0) {
      VariableStoreHeader->Size = (UINT32) VariableStoreEntry.Length;
    }
  }
  //
  // Calculate LastVariableOffset
  //
  Variable = (VARIABLE_HEADER *) (VariableStoreHeader + 1);
  while (IsValidVariableHeader (Variable)) {
    UINTN VariableSize = 0;
    NextVariable = GetNextVariablePtr (Variable);
    VariableSize = NextVariable - Variable;
    if ((NextVariable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
      mGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);
    } else {
      mGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);
    }
    Variable = NextVariable;
  }

  mGlobal->LastVariableOffset[NonVolatile] = (UINTN) Variable - (UINTN) VariableStoreHeader;
  mGlobal->VariableBase[NonVolatile]       = VariableStoreHeader;

  //
  // Reclaim if remaining space is too small
  //
  if ((VariableStoreHeader->Size - mGlobal->LastVariableOffset[NonVolatile]) < VARIABLE_RECLAIM_THRESHOLD) {
    Status = Reclaim (NonVolatile, NULL);
    if (EFI_ERROR (Status)) {
      //
      // Reclaim error
      // we cannot restore to original state
      //
      DEBUG ((EFI_D_ERROR, "FSVariable: Reclaim error (fatal error) - %r\n", Status));
      ASSERT_EFI_ERROR (Status);
    }
  }
  
  //
  // 2. Volatile Storage
  //
  Dev = DEV_FROM_THIS (mGlobal->VariableStore[Volatile]);
  VariableStoreHeader = (VARIABLE_STORE_HEADER *) VAR_DATA_PTR (Dev);
  mGlobal->VariableBase[Volatile] = VAR_DATA_PTR (Dev);  
  mGlobal->LastVariableOffset[Volatile] = sizeof (VARIABLE_STORE_HEADER);
  //
  // init store_header & body in memory.
  //
  mGlobal->VariableStore[Volatile]->Erase (mGlobal->VariableStore[Volatile]);
  mGlobal->VariableStore[Volatile]->Write (
                                   mGlobal->VariableStore[Volatile],
                                   0,
                                   sizeof (VARIABLE_STORE_HEADER),
                                   &mStoreHeaderTemplate
                                   );


  SystemTable->RuntimeServices->GetVariable         = DuetGetVariable;
  SystemTable->RuntimeServices->GetNextVariableName = GetNextVariableName;
  SystemTable->RuntimeServices->SetVariable         = SetVariable;

  SystemTable->RuntimeServices->QueryVariableInfo   = QueryVariableInfo;

  //
  // 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 Status;
}



VOID
EFIAPI
OnVirtualAddressChangeFsv (
  IN EFI_EVENT        Event,
  IN VOID             *Context
  )
{
  UINTN Index;

  for (Index = 0; Index < MaxType; Index++) {
    mGlobal->GoVirtualChildEvent[Index] (Event, mGlobal->VariableStore[Index]);
    EfiConvertPointer (0, (VOID**) &mGlobal->VariableStore[Index]);
    EfiConvertPointer (0, &mGlobal->VariableBase[Index]);
  }
  EfiConvertPointer (0, &mGlobal->Scratch);
  EfiConvertPointer (0, (VOID**) &mGlobal);
}
