/** @file
    Help functions used by PCD DXE driver.

Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Service.h"
#include <Library/DxeServicesLib.h>

PCD_DATABASE   mPcdDatabase;

UINT32         mPcdTotalTokenCount; 
UINT32         mPeiLocalTokenCount; 
UINT32         mDxeLocalTokenCount; 
UINT32         mPeiNexTokenCount;   
UINT32         mDxeNexTokenCount;  
UINT32         mPeiExMapppingTableSize;
UINT32         mDxeExMapppingTableSize;
UINT32         mPeiGuidTableSize;
UINT32         mDxeGuidTableSize;

BOOLEAN        mPeiExMapTableEmpty; 
BOOLEAN        mDxeExMapTableEmpty; 
BOOLEAN        mPeiDatabaseEmpty;

LIST_ENTRY    *mCallbackFnTable;
EFI_GUID     **TmpTokenSpaceBuffer;
UINTN          TmpTokenSpaceBufferCount; 

UINTN                 mPeiPcdDbSize    = 0;
PEI_PCD_DATABASE      *mPeiPcdDbBinary = NULL;
UINTN                 mDxePcdDbSize    = 0;
DXE_PCD_DATABASE      *mDxePcdDbBinary = NULL;

/**
  Get Local Token Number by Token Number.

  @param[in]    IsPeiDb     If TRUE, the pcd entry is initialized in PEI phase,
                            If FALSE, the pcd entry is initialized in DXE phase.
  @param[in]    TokenNumber The PCD token number.

  @return       Local Token Number.
**/
UINT32
GetLocalTokenNumber (
  IN BOOLEAN            IsPeiDb,
  IN UINTN              TokenNumber
  )
{
  UINT32                *LocalTokenNumberTable;

  //
  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
  // We have to decrement TokenNumber by 1 to make it usable
  // as the array index.
  //
  TokenNumber--;

  LocalTokenNumberTable  = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) : 
                                     (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
  TokenNumber            = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount;

  return LocalTokenNumberTable[TokenNumber];
}

/**
  Get PCD type by Local Token Number.

  @param[in]    LocalTokenNumber The PCD local token number.

  @return       PCD type.
**/
EFI_PCD_TYPE
GetPcdType (
  IN UINT32             LocalTokenNumber
  )
{
  switch (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) {
    case PCD_DATUM_TYPE_POINTER:
      return EFI_PCD_TYPE_PTR;
    case PCD_DATUM_TYPE_UINT8:
      if ((LocalTokenNumber & PCD_DATUM_TYPE_UINT8_BOOLEAN) == PCD_DATUM_TYPE_UINT8_BOOLEAN) {
        return EFI_PCD_TYPE_BOOL;
      } else {
        return EFI_PCD_TYPE_8;
      }
    case PCD_DATUM_TYPE_UINT16:
      return EFI_PCD_TYPE_16;
    case PCD_DATUM_TYPE_UINT32:
      return EFI_PCD_TYPE_32;
    case PCD_DATUM_TYPE_UINT64:
      return EFI_PCD_TYPE_64;
    default:
      ASSERT (FALSE);
      return EFI_PCD_TYPE_8;
  }
}

/**
  Get PCD name.

  @param[in]    OnlyTokenSpaceName  If TRUE, only need to get the TokenSpaceCName.
                                    If FALSE, need to get the full PCD name.
  @param[in]    IsPeiDb             If TRUE, the pcd entry is initialized in PEI phase,
                                    If FALSE, the pcd entry is initialized in DXE phase.
  @param[in]    TokenNumber         The PCD token number.

  @return       The TokenSpaceCName or full PCD name.
**/
CHAR8 *
GetPcdName (
  IN BOOLEAN            OnlyTokenSpaceName,
  IN BOOLEAN            IsPeiDb,
  IN UINTN              TokenNumber
  )
{
  PCD_DATABASE_INIT *Database;
  UINT8             *StringTable;
  UINTN             NameSize;
  PCD_NAME_INDEX    *PcdNameIndex;
  CHAR8             *TokenSpaceName;
  CHAR8             *PcdName;
  CHAR8             *Name;

  //
  // Return NULL when PCD name table is absent. 
  //
  if (IsPeiDb) {
    if (mPcdDatabase.PeiDb->PcdNameTableOffset == 0) {
      return NULL;
    }
  } else {
    if (mPcdDatabase.DxeDb->PcdNameTableOffset == 0) {
      return NULL;
    }
  }

  //
  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
  // We have to decrement TokenNumber by 1 to make it usable
  // as the array index.
  //
  TokenNumber--;

  Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;
  TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount;

  StringTable = (UINT8 *) Database + Database->StringTableOffset;

  //
  // Get the PCD name index.
  //
  PcdNameIndex = (PCD_NAME_INDEX *)((UINT8 *) Database + Database->PcdNameTableOffset) + TokenNumber;
  TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex];
  PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex];

  if (OnlyTokenSpaceName) {
    //
    // Only need to get the TokenSpaceCName.
    //
    Name = AllocateCopyPool (AsciiStrSize (TokenSpaceName), TokenSpaceName);
  } else {
    //
    // Need to get the full PCD name.
    //
    NameSize = AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName);
    Name = AllocateZeroPool (NameSize);
    ASSERT (Name != NULL);
    //
    // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.
    //
    AsciiStrCatS (Name, NameSize, TokenSpaceName);
    Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.';
    AsciiStrCatS (Name, NameSize, PcdName);  
  }

  return Name;
}

/**
  Retrieve additional information associated with a PCD token.

  This includes information such as the type of value the TokenNumber is associated with as well as possible
  human readable name that is associated with the token.

  @param[in]    IsPeiDb     If TRUE, the pcd entry is initialized in PEI phase,
                            If FALSE, the pcd entry is initialized in DXE phase.
  @param[in]    Guid        The 128-bit unique value that designates the namespace from which to extract the value.
  @param[in]    TokenNumber The PCD token number.
  @param[out]   PcdInfo     The returned information associated with the requested TokenNumber.
                            The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName. 

  @retval  EFI_SUCCESS      The PCD information was returned successfully
  @retval  EFI_NOT_FOUND    The PCD service could not find the requested token number.
**/
EFI_STATUS
ExGetPcdInfo (
  IN        BOOLEAN             IsPeiDb,
  IN CONST  EFI_GUID            *Guid,
  IN        UINTN               TokenNumber,
  OUT       EFI_PCD_INFO        *PcdInfo
  )
{
  PCD_DATABASE_INIT     *Database;
  UINTN                 GuidTableIdx;
  EFI_GUID              *MatchGuid;
  EFI_GUID              *GuidTable;
  DYNAMICEX_MAPPING     *ExMapTable;
  UINTN                 Index;
  UINT32                LocalTokenNumber;

  Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;

  GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);
  MatchGuid = ScanGuid (GuidTable, Database->GuidTableCount * sizeof(EFI_GUID), Guid);

  if (MatchGuid == NULL) {
    return EFI_NOT_FOUND;
  }

  GuidTableIdx = MatchGuid - GuidTable;

  ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)Database + Database->ExMapTableOffset);

  //
  // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.
  //
  for (Index = 0; Index < Database->ExTokenCount; Index++) {
    if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
      if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
        //
        // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
        // PcdSize to 0 and PcdName to the null-terminated ASCII string
        // associated with the token's namespace Guid.
        //
        PcdInfo->PcdType = EFI_PCD_TYPE_8;
        PcdInfo->PcdSize = 0;
        //
        // Here use one representative in the token space to get the TokenSpaceCName.
        // 
        PcdInfo->PcdName = GetPcdName (TRUE, IsPeiDb, ExMapTable[Index].TokenNumber);
        return EFI_SUCCESS;
      } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {
        PcdInfo->PcdSize = DxePcdGetSize (ExMapTable[Index].TokenNumber);
        LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, ExMapTable[Index].TokenNumber);
        PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
        PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, ExMapTable[Index].TokenNumber);
        return EFI_SUCCESS;
      }
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Retrieve additional information associated with a PCD token.

  This includes information such as the type of value the TokenNumber is associated with as well as possible
  human readable name that is associated with the token.

  @param[in]    Guid        The 128-bit unique value that designates the namespace from which to extract the value.
  @param[in]    TokenNumber The PCD token number.
  @param[out]   PcdInfo     The returned information associated with the requested TokenNumber.
                            The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.

  @retval  EFI_SUCCESS      The PCD information was returned successfully.
  @retval  EFI_NOT_FOUND    The PCD service could not find the requested token number.
**/
EFI_STATUS
DxeGetPcdInfo (
  IN CONST  EFI_GUID        *Guid,
  IN        UINTN           TokenNumber,
  OUT       EFI_PCD_INFO    *PcdInfo
  )
{
  EFI_STATUS            Status;
  BOOLEAN               PeiExMapTableEmpty;
  BOOLEAN               DxeExMapTableEmpty;
  UINT32                LocalTokenNumber;
  BOOLEAN               IsPeiDb;

  ASSERT (PcdInfo != NULL);

  Status = EFI_NOT_FOUND;
  PeiExMapTableEmpty = mPeiExMapTableEmpty;
  DxeExMapTableEmpty = mDxeExMapTableEmpty;

  if (Guid == NULL) {
    if (((TokenNumber + 1 > mPeiNexTokenCount + 1) && (TokenNumber + 1 <= mPeiLocalTokenCount + 1)) ||
        ((TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) {
      return EFI_NOT_FOUND;
    } else if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
      //
      // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
      // PcdSize to 0 and PcdName to NULL for default Token Space.
      //
      PcdInfo->PcdType = EFI_PCD_TYPE_8;
      PcdInfo->PcdSize = 0;
      PcdInfo->PcdName = NULL;
    } else {
      PcdInfo->PcdSize = DxePcdGetSize (TokenNumber);
      IsPeiDb = FALSE;
      if ((TokenNumber + 1 <= mPeiNexTokenCount + 1)) {
        IsPeiDb = TRUE;
      }
      LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber);
      PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
      PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, TokenNumber);
    }
    return EFI_SUCCESS;
  }

  if (PeiExMapTableEmpty && DxeExMapTableEmpty) {
    return EFI_NOT_FOUND;
  }

  if (!PeiExMapTableEmpty) {
    Status = ExGetPcdInfo (
               TRUE,
               Guid,
               TokenNumber,
               PcdInfo
               );
  }

  if (Status == EFI_SUCCESS) {
    return Status;
  }

  if (!DxeExMapTableEmpty) {
    Status = ExGetPcdInfo (
               FALSE,
               Guid,
               TokenNumber,
               PcdInfo
               );
  }

  return Status;
}

/**
  Get the PCD entry pointer in PCD database.
  
  This routine will visit PCD database to find the PCD entry according to given
  token number. The given token number is autogened by build tools and it will be 
  translated to local token number. Local token number contains PCD's type and 
  offset of PCD entry in PCD database.

  @param TokenNumber     Token's number, it is autogened by build tools
  @param GetSize         The size of token's value

  @return PCD entry pointer in PCD database

**/
VOID *
GetWorker (
  IN UINTN             TokenNumber,
  IN UINTN             GetSize
  )
{
  EFI_GUID            *GuidTable;
  UINT8               *StringTable;
  EFI_GUID            *Guid;
  UINT16              *Name;
  VARIABLE_HEAD       *VariableHead;
  UINT8               *VaraiableDefaultBuffer;
  UINT8               *Data;
  VPD_HEAD            *VpdHead;
  UINT8               *PcdDb;
  VOID                *RetPtr;
  UINTN               TmpTokenNumber;
  UINTN               DataSize;
  EFI_STATUS          Status;
  UINT32              LocalTokenNumber;
  UINT32              Offset;
  STRING_HEAD         StringTableIdx;      
  BOOLEAN             IsPeiDb;

  //
  // Aquire lock to prevent reentrance from TPL_CALLBACK level
  //
  EfiAcquireLock (&mPcdDatabaseLock);

  RetPtr = NULL;

  ASSERT (TokenNumber > 0);
  //
  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
  // We have to decrement TokenNumber by 1 to make it usable
  // as the array index.
  //
  TokenNumber--;

  TmpTokenNumber = TokenNumber;

  //
  // EBC compiler is very choosy. It may report warning about comparison
  // between UINTN and 0 . So we add 1 in each size of the 
  // comparison.
  //
  ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);

  ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0));

  // EBC compiler is very choosy. It may report warning about comparison
  // between UINTN and 0 . So we add 1 in each size of the 
  // comparison.
  IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);

  LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1);

  PcdDb = IsPeiDb ? ((UINT8 *) mPcdDatabase.PeiDb) : ((UINT8 *) mPcdDatabase.DxeDb);
                                    
  if (IsPeiDb) {
    StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);
  } else {
    StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);
  }


  Offset     = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;

  switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
    case PCD_TYPE_VPD:
      VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset);
      RetPtr = (VOID *) ((UINTN) PcdGet32 (PcdVpdBaseAddress) + VpdHead->Offset);

      break;

    case PCD_TYPE_HII|PCD_TYPE_STRING:
    case PCD_TYPE_HII:
      if (IsPeiDb) {
        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);
      } else {
        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);
      }

      VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
      Guid = GuidTable + VariableHead->GuidTableIndex;
      Name = (UINT16*)(StringTable + VariableHead->StringIndex);

      if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {
        //
        // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of 
        // string array in string table.
        //
        StringTableIdx = *(STRING_HEAD*)((UINT8 *) PcdDb + VariableHead->DefaultValueOffset);   
        VaraiableDefaultBuffer = (UINT8 *) (StringTable + StringTableIdx);     
      } else {
        VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset;
      }
      Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
      if (Status == EFI_SUCCESS) {
        if (DataSize >= (VariableHead->Offset + GetSize)) {
          if (GetSize == 0) {
            //
            // It is a pointer type. So get the MaxSize reserved for
            // this PCD entry.
            //
            GetPtrTypeSize (TmpTokenNumber, &GetSize);
            if (GetSize > (DataSize - VariableHead->Offset)) {
              //
              // Use actual valid size.
              //
              GetSize = DataSize - VariableHead->Offset;
            }
          }
          //
          // If the operation is successful, we copy the data
          // to the default value buffer in the PCD Database.
          // So that we can free the Data allocated in GetHiiVariable.
          //
          CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);
        }
        FreePool (Data);
      }
      RetPtr = (VOID *) VaraiableDefaultBuffer;
      break;

    case PCD_TYPE_STRING:
      StringTableIdx = *(STRING_HEAD*)((UINT8 *) PcdDb + Offset);
      RetPtr = (VOID *) (StringTable + StringTableIdx);
      break;

    case PCD_TYPE_DATA:
      RetPtr = (VOID *) ((UINT8 *) PcdDb + Offset);
      break;

    default:
      ASSERT (FALSE);
      break;
      
  }

  EfiReleaseLock (&mPcdDatabaseLock);

  return RetPtr;

}

/**
  Register the callback function for a PCD entry.

  This routine will register a callback function to a PCD entry by given token number
  and token space guid.
  
  @param TokenNumber        PCD token's number, it is autogened by build tools.
  @param Guid               PCD token space's guid, 
                            if not NULL, this PCD is dynamicEx type PCD.
  @param CallBackFunction   Callback function pointer

  @return EFI_SUCCESS Always success for registering callback function.

**/
EFI_STATUS
DxeRegisterCallBackWorker (
  IN  UINTN                   TokenNumber,
  IN  CONST EFI_GUID          *Guid, OPTIONAL
  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction
)
{
  CALLBACK_FN_ENTRY       *FnTableEntry;
  LIST_ENTRY              *ListHead;
  LIST_ENTRY              *ListNode;

  if (Guid != NULL) {
    TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);
  }

  //
  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
  // We have to decrement TokenNumber by 1 to make it usable
  // as the array index of mCallbackFnTable[].
  //
  ListHead = &mCallbackFnTable[TokenNumber - 1];
  ListNode = GetFirstNode (ListHead);

  while (ListNode != ListHead) {
    FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);

    if (FnTableEntry->CallbackFn == CallBackFunction) {
      //
      // We only allow a Callback function to be register once
      // for a TokenNumber. So just return EFI_SUCCESS
      //
      return EFI_SUCCESS;
    }
    ListNode = GetNextNode (ListHead, ListNode);
  }

  FnTableEntry = AllocatePool (sizeof(CALLBACK_FN_ENTRY));
  ASSERT (FnTableEntry != NULL);

  FnTableEntry->CallbackFn = CallBackFunction;
  InsertTailList (ListHead, &FnTableEntry->Node);
  
  return EFI_SUCCESS;
}

/**
  UnRegister the callback function for a PCD entry.

  This routine will unregister a callback function to a PCD entry by given token number
  and token space guid.

  @param TokenNumber        PCD token's number, it is autogened by build tools.
  @param Guid               PCD token space's guid.
                            if not NULL, this PCD is dynamicEx type PCD.
  @param CallBackFunction   Callback function pointer

  @retval EFI_SUCCESS               Callback function is success to be unregister.
  @retval EFI_INVALID_PARAMETER     Can not find the PCD entry by given token number.
**/
EFI_STATUS
DxeUnRegisterCallBackWorker (
  IN  UINTN                   TokenNumber,
  IN  CONST EFI_GUID          *Guid, OPTIONAL
  IN  PCD_PROTOCOL_CALLBACK   CallBackFunction
)
{
  CALLBACK_FN_ENTRY       *FnTableEntry;
  LIST_ENTRY              *ListHead;
  LIST_ENTRY              *ListNode;

  if (Guid != NULL) {
    TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);
  }

  //
  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
  // We have to decrement TokenNumber by 1 to make it usable
  // as the array index of mCallbackFnTable[].
  //
  ListHead = &mCallbackFnTable[TokenNumber - 1];
  ListNode = GetFirstNode (ListHead);

  while (ListNode != ListHead) {
    FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);

    if (FnTableEntry->CallbackFn == CallBackFunction) {
      //
      // We only allow a Callback function to be register once
      // for a TokenNumber. So we can safely remove the Node from
      // the Link List and return EFI_SUCCESS.
      //
      RemoveEntryList (ListNode);
      FreePool (FnTableEntry);
      
      return EFI_SUCCESS;
    }
    ListNode = GetNextNode (ListHead, ListNode);
  }

  return EFI_INVALID_PARAMETER;
}

/**
  Get next token number in given token space.
  
  This routine is used for dynamicEx type PCD. It will firstly scan token space
  table to get token space according to given token space guid. Then scan given 
  token number in found token space, if found, then return next token number in 
  this token space.

  @param Guid            Token space guid. Next token number will be scaned in 
                         this token space.
  @param TokenNumber     Token number. 
                         If PCD_INVALID_TOKEN_NUMBER, return first token number in 
                         token space table.
                         If not PCD_INVALID_TOKEN_NUMBER, return next token number
                         in token space table.
  @param GuidTable       Token space guid table. It will be used for scan token space
                         by given token space guid.
  @param SizeOfGuidTable The size of guid table.
  @param ExMapTable      DynamicEx token number mapping table.
  @param SizeOfExMapTable The size of dynamicEx token number mapping table.

  @retval EFI_NOT_FOUND  Can not given token space or token number.
  @retval EFI_SUCCESS    Success to get next token number.

**/
EFI_STATUS
ExGetNextTokeNumber (
  IN      CONST EFI_GUID         *Guid,
  IN OUT  UINTN                  *TokenNumber,
  IN      EFI_GUID               *GuidTable,
  IN      UINTN                  SizeOfGuidTable,
  IN      DYNAMICEX_MAPPING      *ExMapTable,
  IN      UINTN                  SizeOfExMapTable
  )
{
  EFI_GUID         *MatchGuid;
  UINTN            Index;
  UINTN            GuidTableIdx;
  BOOLEAN          Found;
  UINTN            ExMapTableCount;

  //
  // Scan token space guid 
  // 
  MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid);
  if (MatchGuid == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // Find the token space table in dynamicEx mapping table.
  //
  Found = FALSE;
  GuidTableIdx = MatchGuid - GuidTable;
  ExMapTableCount = SizeOfExMapTable / sizeof(ExMapTable[0]);
  for (Index = 0; Index < ExMapTableCount; Index++) {
    if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
      Found = TRUE;
      break;
    }
  }

  if (Found) {
    //
    // If given token number is PCD_INVALID_TOKEN_NUMBER, then return the first
    // token number in found token space.
    //
    if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
      *TokenNumber = ExMapTable[Index].ExTokenNumber;
      return EFI_SUCCESS;
    }

    for ( ; Index < ExMapTableCount; Index++) {
      if ((ExMapTable[Index].ExTokenNumber == *TokenNumber) && (ExMapTable[Index].ExGuidIndex == GuidTableIdx)) {
        break;
      }
    }

    while (Index < ExMapTableCount) {
      Index++;
      if (Index == ExMapTableCount) {
        //
        // Exceed the length of ExMap Table
        //
        *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
        return EFI_NOT_FOUND;
      } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
        //
        // Found the next match
        //
        *TokenNumber = ExMapTable[Index].ExTokenNumber;
        return EFI_SUCCESS;
      }
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Find the PCD database.

  @retval The base address of external PCD database binary.
  @retval NULL         Return NULL if not find.
**/
DXE_PCD_DATABASE *
LocateExPcdBinary (
  VOID
) 
{
  EFI_STATUS            Status;
 
  //
  // Search the External Pcd database from one section of current FFS, 
  // and read it to memory
  //
  Status = GetSectionFromFfs (
             EFI_SECTION_RAW,
             0,
             (VOID **) &mDxePcdDbBinary,
             &mDxePcdDbSize
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Check the first bytes (Header Signature Guid) and build version.
  //
  if (!CompareGuid ((VOID *)mDxePcdDbBinary, &gPcdDataBaseSignatureGuid) ||
      (mDxePcdDbBinary->BuildVersion != PCD_SERVICE_DXE_VERSION)) {
    ASSERT (FALSE);
  }

  return mDxePcdDbBinary;
}

/**
  Update PCD database base on current SkuId

  @param   SkuId     Current SkuId
  @param   IsPeiDb   Whether to update PEI PCD database.

  @retval EFI_SUCCESS    Update PCD database successfully.
  @retval EFI_NOT_FOUND  Not found PCD database for current SkuId.
**/
EFI_STATUS
UpdatePcdDatabase (
  IN SKU_ID        SkuId,
  IN BOOLEAN       IsPeiDb
  )
{
  UINTN                       Index;
  PCD_DATABASE_SKU_DELTA      *SkuDelta;
  PCD_DATA_DELTA              *SkuDeltaData;

  if (IsPeiDb && mPeiPcdDbBinary != NULL) {
    //
    // Find the delta data for PEI DB
    //
    Index    = (mPcdDatabase.PeiDb->Length + 7) & (~7);
    SkuDelta = NULL;
    while (Index < mPeiPcdDbSize) {
      SkuDelta = (PCD_DATABASE_SKU_DELTA *) ((UINT8 *) mPeiPcdDbBinary + Index);
      if (SkuDelta->SkuId == (UINT16) SkuId && SkuDelta->SkuIdCompared == 0) {
        break;
      }
      Index = (Index + SkuDelta->Length + 7) & (~7);
    }

    //
    // Patch the delta data into current PCD database
    //
    if (Index < mPeiPcdDbSize && SkuDelta != NULL) {
      SkuDeltaData = (PCD_DATA_DELTA *) (SkuDelta + 1);
      while ((UINT8 *) SkuDeltaData < (UINT8 *) SkuDelta + SkuDelta->Length) {
        *((UINT8 *) mPcdDatabase.PeiDb + SkuDeltaData->Offset) = (UINT8) SkuDeltaData->Value;
        SkuDeltaData ++;
      }
    } else {
      return EFI_NOT_FOUND;
    }
  }

  //
  // Find the delta data for DXE DB
  //
  Index    = (mPcdDatabase.DxeDb->Length + 7) & (~7);
  SkuDelta = NULL;
  while (Index < mDxePcdDbSize) {
    SkuDelta = (PCD_DATABASE_SKU_DELTA *) ((UINT8 *) mDxePcdDbBinary + Index);
    if (SkuDelta->SkuId == SkuId && SkuDelta->SkuIdCompared == 0) {
      break;
    }
    Index = (Index + SkuDelta->Length + 7) & (~7);
  }

  //
  // Patch the delta data into current PCD database
  //
  if (Index < mDxePcdDbSize && SkuDelta != NULL) {
    SkuDeltaData = (PCD_DATA_DELTA *) (SkuDelta + 1);
    while ((UINT8 *) SkuDeltaData < (UINT8 *) SkuDelta + SkuDelta->Length) {
      *((UINT8 *) mPcdDatabase.DxeDb + SkuDeltaData->Offset) = (UINT8) SkuDeltaData->Value;
      SkuDeltaData ++;
    }
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  Initialize the PCD database in DXE phase.
  
  PCD database in DXE phase also contains PCD database in PEI phase which is copied
  from GUID Hob.

**/
VOID
BuildPcdDxeDataBase (
  VOID
  )
{
  PEI_PCD_DATABASE    *PeiDatabase;
  EFI_HOB_GUID_TYPE   *GuidHob;
  UINTN               Index;
  UINT32              PcdDxeDbLen;
  VOID                *PcdDxeDb;
  EFI_STATUS          Status;

  //
  // Assign PCD Entries with default value to PCD DATABASE
  //
  mPcdDatabase.DxeDb = LocateExPcdBinary ();
  ASSERT(mPcdDatabase.DxeDb != NULL);
  PcdDxeDbLen = mPcdDatabase.DxeDb->Length + mPcdDatabase.DxeDb->UninitDataBaseSize;
  PcdDxeDb = AllocateZeroPool (PcdDxeDbLen);
  ASSERT (PcdDxeDb != NULL);
  CopyMem (PcdDxeDb, mPcdDatabase.DxeDb, mPcdDatabase.DxeDb->Length);
  mPcdDatabase.DxeDb = PcdDxeDb;

  GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
  if (GuidHob != NULL) {

    // 
    // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM
    // should not be included at all. So the GuidHob could
    // be NULL. If it is NULL, we just copy over the DXE Default
    // Value to PCD Database.
    //
    PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);

    //
    // Get next one that stores full PEI data
    //
    GuidHob = GetNextGuidHob (&gPcdDataBaseHobGuid, GET_NEXT_HOB (GuidHob));
    if (GuidHob != NULL) {
      mPeiPcdDbBinary = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);
      mPeiPcdDbSize   = (UINTN) GET_GUID_HOB_DATA_SIZE (GuidHob);
    }

    //
    // Assign PCD Entries refereneced in PEI phase to PCD DATABASE
    //
    mPcdDatabase.PeiDb = PeiDatabase;
    //
    // Inherit the SystemSkuId from PEI phase.
    //
    if (mPcdDatabase.PeiDb->SystemSkuId != 0) {
      Status = UpdatePcdDatabase (mPcdDatabase.PeiDb->SystemSkuId, FALSE);
      ASSERT_EFI_ERROR (Status);
    }
    mPcdDatabase.DxeDb->SystemSkuId = mPcdDatabase.PeiDb->SystemSkuId;
  } else {
    mPcdDatabase.PeiDb = AllocateZeroPool (sizeof (PEI_PCD_DATABASE));
    ASSERT(mPcdDatabase.PeiDb != NULL);
  }

  //
  // Initialized the external PCD database local variables
  //
  mPeiLocalTokenCount     = mPcdDatabase.PeiDb->LocalTokenCount;
  mDxeLocalTokenCount     = mPcdDatabase.DxeDb->LocalTokenCount;

  mPeiExMapppingTableSize = mPcdDatabase.PeiDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING);
  mDxeExMapppingTableSize = mPcdDatabase.DxeDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING);
  mPeiGuidTableSize       = mPcdDatabase.PeiDb->GuidTableCount * sizeof(GUID);
  mDxeGuidTableSize       = mPcdDatabase.DxeDb->GuidTableCount * sizeof (GUID);

  mPcdTotalTokenCount     = mPeiLocalTokenCount + mDxeLocalTokenCount;
  mPeiNexTokenCount       = mPeiLocalTokenCount - mPcdDatabase.PeiDb->ExTokenCount;
  mDxeNexTokenCount       = mDxeLocalTokenCount - mPcdDatabase.DxeDb->ExTokenCount;  

  mPeiExMapTableEmpty     = (mPcdDatabase.PeiDb->ExTokenCount == 0) ? TRUE : FALSE;
  mDxeExMapTableEmpty     = (mPcdDatabase.DxeDb->ExTokenCount == 0) ? TRUE : FALSE;
  mPeiDatabaseEmpty       = (mPeiLocalTokenCount == 0) ? TRUE : FALSE;

  TmpTokenSpaceBufferCount = mPcdDatabase.PeiDb->ExTokenCount + mPcdDatabase.DxeDb->ExTokenCount;
  TmpTokenSpaceBuffer     = (EFI_GUID **)AllocateZeroPool(TmpTokenSpaceBufferCount * sizeof (EFI_GUID *));

  //
  // Initialized the Callback Function Table
  //
  mCallbackFnTable = AllocateZeroPool (mPcdTotalTokenCount * sizeof (LIST_ENTRY));
  ASSERT(mCallbackFnTable != NULL);

  //
  // EBC compiler is very choosy. It may report warning about comparison
  // between UINTN and 0 . So we add 1 in each size of the 
  // comparison.
  //
  for (Index = 0; Index + 1 < mPcdTotalTokenCount + 1; Index++) {
    InitializeListHead (&mCallbackFnTable[Index]);
  }
}

/**
  Get Variable which contains HII type PCD entry.

  @param VariableGuid    Variable's guid
  @param VariableName    Variable's unicode name string
  @param VariableData    Variable's data pointer, 
  @param VariableSize    Variable's size.

  @return the status of gRT->GetVariable
**/
EFI_STATUS
GetHiiVariable (
  IN  EFI_GUID      *VariableGuid,
  IN  UINT16        *VariableName,
  OUT UINT8         **VariableData,
  OUT UINTN         *VariableSize
  )
{
  UINTN      Size;
  EFI_STATUS Status;
  UINT8      *Buffer;

  Size = 0;
  Buffer = NULL;
  
  //
  // Firstly get the real size of HII variable
  //
  Status = gRT->GetVariable (
    (UINT16 *)VariableName,
    VariableGuid,
    NULL,
    &Size,
    Buffer
    );
  
  //
  // Allocate buffer to hold whole variable data according to variable size.
  //
  if (Status == EFI_BUFFER_TOO_SMALL) {
    Buffer = (UINT8 *) AllocatePool (Size);

    ASSERT (Buffer != NULL);

    Status = gRT->GetVariable (
      VariableName,
      VariableGuid,
      NULL,
      &Size,
      Buffer
      );

    ASSERT (Status == EFI_SUCCESS);
    *VariableData = Buffer;
    *VariableSize = Size;
  } else {
    //
    // Use Default Data only when variable is not found. 
    // For other error status, correct data can't be got, and trig ASSERT().
    //
    ASSERT (Status == EFI_NOT_FOUND);
  }

  return Status;
}

/**
  Invoke the callback function when dynamic PCD entry was set, if this PCD entry 
  has registered callback function.

  @param ExTokenNumber   DynamicEx PCD's token number, if this PCD entry is dyanmicEx
                         type PCD.
  @param Guid            DynamicEx PCD's guid, if this PCD entry is dynamicEx type
                         PCD.
  @param TokenNumber     PCD token number generated by build tools.
  @param Data            Value want to be set for this PCD entry
  @param Size            The size of value

**/
VOID
InvokeCallbackOnSet (
  UINT32            ExTokenNumber,
  CONST EFI_GUID    *Guid, OPTIONAL
  UINTN             TokenNumber,
  VOID              *Data,
  UINTN             Size
  )
{
  CALLBACK_FN_ENTRY       *FnTableEntry;
  LIST_ENTRY              *ListHead;
  LIST_ENTRY              *ListNode;

  //
  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
  // We have to decrement TokenNumber by 1 to make it usable
  // as the array index of mCallbackFnTable[].
  //
  ListHead = &mCallbackFnTable[TokenNumber - 1];
  ListNode = GetFirstNode (ListHead);

  while (ListNode != ListHead) {
    FnTableEntry = CR_FNENTRY_FROM_LISTNODE (ListNode, CALLBACK_FN_ENTRY, Node);

    FnTableEntry->CallbackFn(Guid, 
                    (Guid == NULL) ? TokenNumber : ExTokenNumber,
                    Data,
                    Size);
    
    ListNode = GetNextNode (ListHead, ListNode);
  }
  
  return;
}


/**
  Wrapper function for setting non-pointer type value for a PCD entry.

  @param TokenNumber     Pcd token number autogenerated by build tools.
  @param Data            Value want to be set for PCD entry
  @param Size            Size of value.

  @return status of SetWorker.

**/
EFI_STATUS
SetValueWorker (
  IN UINTN                   TokenNumber,
  IN VOID                    *Data,
  IN UINTN                   Size
  )
{
  return SetWorker (TokenNumber, Data, &Size, FALSE);
}


/**
  Set value for an PCD entry

  @param TokenNumber     Pcd token number autogenerated by build tools.
  @param Data            Value want to be set for PCD entry
  @param Size            Size of value.
  @param PtrType         If TRUE, the type of PCD entry's value is Pointer.
                         If False, the type of PCD entry's value is not Pointer.

  @retval EFI_INVALID_PARAMETER  If this PCD type is VPD, VPD PCD can not be set.
  @retval EFI_INVALID_PARAMETER  If Size can not be set to size table.
  @retval EFI_INVALID_PARAMETER  If Size of non-Ptr type PCD does not match the size information in PCD database.  
  @retval EFI_NOT_FOUND          If value type of PCD entry is intergrate, but not in
                                 range of UINT8, UINT16, UINT32, UINT64
  @retval EFI_NOT_FOUND          Can not find the PCD type according to token number.                                
**/
EFI_STATUS
SetWorker (
  IN          UINTN                   TokenNumber,
  IN          VOID                    *Data,
  IN OUT      UINTN                   *Size,
  IN          BOOLEAN                 PtrType
  )
{
  BOOLEAN             IsPeiDb;
  UINT32              LocalTokenNumber;
  EFI_GUID            *GuidTable;
  UINT8               *StringTable;
  EFI_GUID            *Guid;
  UINT16              *Name;
  UINTN               VariableOffset;
  UINT32              Attributes;
  VOID                *InternalData;
  VARIABLE_HEAD       *VariableHead;
  UINTN               Offset;
  UINT8               *PcdDb;
  EFI_STATUS          Status;
  UINTN               MaxSize;
  UINTN               TmpTokenNumber;

  //
  // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
  // We have to decrement TokenNumber by 1 to make it usable
  // as the array index.
  //
  TokenNumber--;

  TmpTokenNumber = TokenNumber;
  
  //
  // EBC compiler is very choosy. It may report warning about comparison
  // between UINTN and 0 . So we add 1 in each size of the 
  // comparison.
  //
  ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);

  if (PtrType) {
    //
    // Get MaxSize first, then check new size with max buffer size.
    //
    GetPtrTypeSize (TokenNumber, &MaxSize);
    if (*Size > MaxSize) {
      *Size = MaxSize;
      return EFI_INVALID_PARAMETER;
    }
  } else {
    if (*Size != DxePcdGetSize (TokenNumber + 1)) {
      return EFI_INVALID_PARAMETER;
    }
  }

  //
  // EBC compiler is very choosy. It may report warning about comparison
  // between UINTN and 0 . So we add 1 in each size of the 
  // comparison.
  //
  if ((TokenNumber + 1 < mPeiNexTokenCount + 1) ||
      (TokenNumber + 1 >= mPeiLocalTokenCount + 1 && TokenNumber + 1 < (mPeiLocalTokenCount + mDxeNexTokenCount + 1))) {
    InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);
  }

  //
  // Aquire lock to prevent reentrance from TPL_CALLBACK level
  //
  EfiAcquireLock (&mPcdDatabaseLock);

  //
  // EBC compiler is very choosy. It may report warning about comparison
  // between UINTN and 0 . So we add 1 in each size of the 
  // comparison.
  //
  IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);

  LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1);

  Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;

  PcdDb = IsPeiDb ? ((UINT8 *) mPcdDatabase.PeiDb) : ((UINT8 *) mPcdDatabase.DxeDb);

  if (IsPeiDb) {
    StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);
  } else {
    StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);
  }

  
  InternalData = PcdDb + Offset;

  switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
    case PCD_TYPE_VPD:
      ASSERT (FALSE);
      Status = EFI_INVALID_PARAMETER;
      break;
    
    case PCD_TYPE_STRING:
      if (SetPtrTypeSize (TmpTokenNumber, Size)) {
        CopyMem (StringTable + *((STRING_HEAD *)InternalData), Data, *Size);
        Status = EFI_SUCCESS;
      } else {
        Status = EFI_INVALID_PARAMETER;
      }
      break;

    case PCD_TYPE_HII|PCD_TYPE_STRING:
    case PCD_TYPE_HII:
      if (PtrType) {
        if (!SetPtrTypeSize (TmpTokenNumber, Size)) {
          Status = EFI_INVALID_PARAMETER;
          break;
        }
      }

      if (IsPeiDb) {
        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);
      } else {
        GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);
      }

      VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);

      Guid = GuidTable + VariableHead->GuidTableIndex;
      Name = (UINT16*) (StringTable + VariableHead->StringIndex);
      VariableOffset = VariableHead->Offset;
      Attributes = VariableHead->Attributes;
      Status = SetHiiVariable (Guid, Name, Attributes, Data, *Size, VariableOffset);
      break;
      
    case PCD_TYPE_DATA:
      if (PtrType) {
        if (SetPtrTypeSize (TmpTokenNumber, Size)) {
          CopyMem (InternalData, Data, *Size);
          Status = EFI_SUCCESS;
        } else {
          Status = EFI_INVALID_PARAMETER;
        }
        break;
      }

      Status = EFI_SUCCESS;
      switch (*Size) {
        case sizeof(UINT8):
          *((UINT8 *) InternalData) = *((UINT8 *) Data);
          break;

        case sizeof(UINT16):
          *((UINT16 *) InternalData) = *((UINT16 *) Data);
          break;

        case sizeof(UINT32):
          *((UINT32 *) InternalData) = *((UINT32 *) Data);
          break;

        case sizeof(UINT64):
          *((UINT64 *) InternalData) = *((UINT64 *) Data);
          break;

        default:
          ASSERT (FALSE);
          Status = EFI_NOT_FOUND;
          break;
      }
      break;

    default:
      ASSERT (FALSE);
      Status = EFI_NOT_FOUND;
      break;
    }

  EfiReleaseLock (&mPcdDatabaseLock);
  
  return Status;
}

/**
  Wrapper function for get PCD value for dynamic-ex PCD.

  @param Guid            Token space guid for dynamic-ex PCD.
  @param ExTokenNumber   Token number for dynamic-ex PCD.
  @param GetSize         The size of dynamic-ex PCD value.

  @return PCD entry in PCD database.

**/
VOID *
ExGetWorker (
  IN CONST EFI_GUID         *Guid,
  IN UINTN                  ExTokenNumber,
  IN UINTN                  GetSize
  ) 
{
  return GetWorker(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber), GetSize);
}

/**
  Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD.

  @param ExTokenNumber   Token number for dynamic-ex PCD.
  @param Guid            Token space guid for dynamic-ex PCD.
  @param Data            Value want to be set.
  @param SetSize         The size of value.

  @return status of ExSetWorker().

**/
EFI_STATUS
ExSetValueWorker (
  IN          UINTN                ExTokenNumber,
  IN          CONST EFI_GUID       *Guid,
  IN          VOID                 *Data,
  IN          UINTN                SetSize
  )
{
  return ExSetWorker (ExTokenNumber, Guid, Data, &SetSize, FALSE);
}

/**
  Set value for a dynamic-ex PCD entry.
  
  This routine find the local token number according to dynamic-ex PCD's token 
  space guid and token number firstly, and invoke callback function if this PCD
  entry registered callback function. Finally, invoken general SetWorker to set
  PCD value.
  
  @param ExTokenNumber   Dynamic-ex PCD token number.
  @param Guid            Token space guid for dynamic-ex PCD.
  @param Data            PCD value want to be set
  @param SetSize         Size of value.
  @param PtrType         If TRUE, this PCD entry is pointer type.
                         If FALSE, this PCD entry is not pointer type.

  @return status of SetWorker().

**/
EFI_STATUS
ExSetWorker (
  IN          UINTN                ExTokenNumber,
  IN          CONST EFI_GUID       *Guid,
  IN          VOID                 *Data,
  IN OUT      UINTN                *SetSize,
  IN          BOOLEAN              PtrType
  )
{
  UINTN                   TokenNumber;
  
  TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber);

  InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, *SetSize);

  return SetWorker (TokenNumber, Data, SetSize, PtrType);

}

/**
  Get variable size and data from HII-type PCDs.

  @param[in]  VariableGuid   Guid of variable which stored value of a HII-type PCD.
  @param[in]  VariableName   Unicode name of variable which stored value of a HII-type PCD.
  @param[out] VariableSize   Pointer to variable size got from HII-type PCDs.
  @param[out] VariableData   Pointer to variable data got from HII-type PCDs.

**/
VOID
GetVariableSizeAndDataFromHiiPcd (
  IN EFI_GUID               *VariableGuid,
  IN UINT16                 *VariableName,
  OUT UINTN                 *VariableSize,
  OUT VOID                  *VariableData OPTIONAL
  )
{
  BOOLEAN                   IsPeiDb;
  PCD_DATABASE_INIT         *Database;
  UINTN                     TokenNumber;
  UINT32                    LocalTokenNumber;
  UINTN                     Offset;
  EFI_GUID                  *GuidTable;
  UINT8                     *StringTable;
  VARIABLE_HEAD             *VariableHead;
  EFI_GUID                  *Guid;
  UINT16                    *Name;
  UINTN                     PcdDataSize;
  UINTN                     Size;
  UINT8                     *VaraiableDefaultBuffer;
  STRING_HEAD               StringTableIdx;

  *VariableSize = 0;

  //
  // Go through PCD database to find out DynamicHii PCDs.
  //
  for (TokenNumber = 1; TokenNumber <= mPcdTotalTokenCount; TokenNumber++) {
    IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);
    Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;
    LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber);
    if ((LocalTokenNumber & PCD_TYPE_HII) != 0) {
      //
      // Get the Variable Guid and Name pointer.
      //
      Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
      VariableHead = (VARIABLE_HEAD *) ((UINT8 *) Database + Offset);
      StringTable = (UINT8 *) ((UINT8 *) Database + Database->StringTableOffset);
      GuidTable = (EFI_GUID *) ((UINT8 *) Database + Database->GuidTableOffset);
      Guid = GuidTable + VariableHead->GuidTableIndex;
      Name = (UINT16*) (StringTable + VariableHead->StringIndex);
      if (CompareGuid (VariableGuid, Guid) && (StrCmp (VariableName, Name) == 0)) {
        //
        // It is the matched DynamicHii PCD.
        //
        PcdDataSize = DxePcdGetSize (TokenNumber);
        Size = VariableHead->Offset + PcdDataSize;
        if (Size > *VariableSize) {
          *VariableSize = Size;
        }
        if (VariableData != NULL) {
          if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {
            //
            // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
            // string array in string table.
            //
            StringTableIdx = *(STRING_HEAD *) ((UINT8 *) Database + VariableHead->DefaultValueOffset);
            VaraiableDefaultBuffer = (UINT8 *) (StringTable + StringTableIdx);
          } else {
            VaraiableDefaultBuffer = (UINT8 *) Database + VariableHead->DefaultValueOffset;
          }
          CopyMem ((UINT8 *) VariableData + VariableHead->Offset, VaraiableDefaultBuffer, PcdDataSize);
        }
      }
    }
  }
}

/**
  Set value for HII-type PCD.

  A HII-type PCD's value is stored in a variable. Setting/Getting the value of 
  HII-type PCD is to visit this variable.
  
  @param VariableGuid    Guid of variable which stored value of a HII-type PCD.
  @param VariableName    Unicode name of variable which stored value of a HII-type PCD.
  @param SetAttributes   Attributes bitmask to set for the variable.
  @param Data            Value want to be set.
  @param DataSize        Size of value
  @param Offset          Value offset of HII-type PCD in variable.

  @return status of GetVariable()/SetVariable().

**/
EFI_STATUS
SetHiiVariable (
  IN  EFI_GUID     *VariableGuid,
  IN  UINT16       *VariableName,
  IN  UINT32       SetAttributes,
  IN  CONST VOID   *Data,
  IN  UINTN        DataSize,
  IN  UINTN        Offset
  )
{
  UINTN       Size;
  VOID        *Buffer;
  EFI_STATUS  Status;
  UINT32      Attribute;
  UINTN       SetSize;

  Size = 0;
  SetSize = 0;

  //
  // Try to get original variable size information.
  //
  Status = gRT->GetVariable (
    (UINT16 *)VariableName,
    VariableGuid,
    NULL,
    &Size,
    NULL
    );
  
  if (Status == EFI_BUFFER_TOO_SMALL) {
    //
    // Patch new PCD's value to offset in given HII variable.
    //
    if (Size >= (DataSize + Offset)) {
      SetSize = Size;
    } else {
      SetSize = DataSize + Offset;
    }
    Buffer = AllocatePool (SetSize);
    ASSERT (Buffer != NULL);

    Status = gRT->GetVariable (
      VariableName,
      VariableGuid,
      &Attribute,
      &Size,
      Buffer
      );
    
    ASSERT_EFI_ERROR (Status);

    CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);

    if (SetAttributes == 0) {
      SetAttributes = Attribute;
    }

    Status = gRT->SetVariable (
              VariableName,
              VariableGuid,
              SetAttributes,
              SetSize,
              Buffer
              );

    FreePool (Buffer);
    return Status;
  } else if (Status == EFI_NOT_FOUND) {
    //
    // If variable does not exist, a new variable need to be created.
    //

    //
    // Get size, allocate buffer and get data.
    //
    GetVariableSizeAndDataFromHiiPcd (VariableGuid, VariableName, &Size, NULL);
    Buffer = AllocateZeroPool (Size);
    ASSERT (Buffer != NULL);
    GetVariableSizeAndDataFromHiiPcd (VariableGuid, VariableName, &Size, Buffer);

    //
    // Update buffer.
    //
    CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);

    if (SetAttributes == 0) {
      SetAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
    }

    Status = gRT->SetVariable (
              VariableName,
              VariableGuid,
              SetAttributes,
              Size,
              Buffer
              );

    FreePool (Buffer);
    return Status;    
  }
  
  //
  // If we drop to here, the value is failed to be written in to variable area.
  //
  return Status;
}

/**
  Get Token Number according to dynamic-ex PCD's {token space guid:token number}

  A dynamic-ex type PCD, developer must provide pair of token space guid: token number
  in DEC file. PCD database maintain a mapping table that translate pair of {token
  space guid: token number} to Token Number.
  
  @param Guid            Token space guid for dynamic-ex PCD entry.
  @param ExTokenNumber   Dynamic-ex PCD token number.

  @return Token Number for dynamic-ex PCD.

**/
UINTN           
GetExPcdTokenNumber (
  IN CONST EFI_GUID             *Guid,
  IN UINT32                     ExTokenNumber
  )
{
  UINT32              Index;
  DYNAMICEX_MAPPING   *ExMap;
  EFI_GUID            *GuidTable;
  EFI_GUID            *MatchGuid;
  UINTN               MatchGuidIdx;

  if (!mPeiDatabaseEmpty) {
    ExMap       = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset);
    GuidTable   = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);

    MatchGuid   = ScanGuid (GuidTable, mPeiGuidTableSize, Guid);

    if (MatchGuid != NULL) {

      MatchGuidIdx = MatchGuid - GuidTable;

      for (Index = 0; Index < mPcdDatabase.PeiDb->ExTokenCount; Index++) {
        if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
            (MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
            return ExMap[Index].TokenNumber;
        }
      }
    }
  }

  ExMap       = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset);
  GuidTable   = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);

  MatchGuid   = ScanGuid (GuidTable, mDxeGuidTableSize, Guid);
  //
  // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
  // error in the BUILD system.
  //
  ASSERT (MatchGuid != NULL);

  MatchGuidIdx = MatchGuid - GuidTable;

  for (Index = 0; Index < mPcdDatabase.DxeDb->ExTokenCount; Index++) {
    if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
         (MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
        return ExMap[Index].TokenNumber;
    }
  }

  ASSERT (FALSE);

  return 0;
}

/**
  Wrapper function of getting index of PCD entry in size table.
  
  @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
  @param IsPeiDb                  If TRUE, the pcd entry is initialized in PEI phase,
                                  If FALSE, the pcd entry is initialized in DXE phase.

  @return index of PCD entry in size table.
**/
UINTN
GetSizeTableIndex (
  IN    UINTN             LocalTokenNumberTableIdx,
  IN    BOOLEAN           IsPeiDb
  )
{
  UINT32 *LocalTokenNumberTable;
  UINTN  LocalTokenNumber;
  UINTN  Index;
  UINTN  SizeTableIdx;
  
  if (IsPeiDb) {
    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
  } else {
    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
  }

  SizeTableIdx = 0;

  for (Index = 0; Index < LocalTokenNumberTableIdx; Index ++) {
    LocalTokenNumber = LocalTokenNumberTable[Index];

    if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {
      //
      // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type 
      // PCD entry.
      //
      if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
          //
          // We have only two entry for VPD enabled PCD entry:
          // 1) MAX Size.
          // 2) Current Size
          // Current size is equal to MAX size.
          //
          SizeTableIdx += 2;
      } else {
          //
          // We have only two entry for Non-Sku enabled PCD entry:
          // 1) MAX SIZE
          // 2) Current Size
          //
          SizeTableIdx += 2;
      }
    }

  }

  return SizeTableIdx;  
}

/**
  Get size of POINTER type PCD value.

  @param LocalTokenNumberTableIdx Index of local token number in local token number table.
  @param MaxSize                  Maxmium size of POINTER type PCD value.

  @return size of POINTER type PCD value.

**/
UINTN
GetPtrTypeSize (
  IN    UINTN             LocalTokenNumberTableIdx,
  OUT   UINTN             *MaxSize
  )
{
  INTN        SizeTableIdx;
  UINTN       LocalTokenNumber;
  SIZE_INFO   *SizeTable;
  BOOLEAN     IsPeiDb;
  UINT32      *LocalTokenNumberTable;

  // EBC compiler is very choosy. It may report warning about comparison
  // between UINTN and 0 . So we add 1 in each size of the 
  // comparison.
  IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);


  if (IsPeiDb) {
    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);
  } else {
    LocalTokenNumberTableIdx -= mPeiLocalTokenCount;
    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);
  }

  LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];

  ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
  
  SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);

  *MaxSize = SizeTable[SizeTableIdx];
  //
  // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type 
  // PCD entry.
  //
  if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
      //
      // We have only two entry for VPD enabled PCD entry:
      // 1) MAX Size.
      // 2) Current Size
      // We consider current size is equal to MAX size.
      //
      return *MaxSize;
  } else {
      //
      // We have only two entry for Non-Sku enabled PCD entry:
      // 1) MAX SIZE
      // 2) Current Size
      //
      return SizeTable[SizeTableIdx + 1];
  }
}

/**
  Set size of POINTER type PCD value. The size should not exceed the maximum size
  of this PCD value.

  @param LocalTokenNumberTableIdx Index of local token number in local token number table.
  @param CurrentSize              Size of POINTER type PCD value.

  @retval TRUE  Success to set size of PCD value.
  @retval FALSE Fail to set size of PCD value.
**/
BOOLEAN
SetPtrTypeSize (
  IN          UINTN             LocalTokenNumberTableIdx,
  IN    OUT   UINTN             *CurrentSize
  )
{
  INTN        SizeTableIdx;
  UINTN       LocalTokenNumber;
  SIZE_INFO   *SizeTable;
  UINTN       MaxSize;
  BOOLEAN     IsPeiDb;
  UINT32      *LocalTokenNumberTable;

  //
  // EBC compiler is very choosy. It may report warning about comparison
  // between UINTN and 0 . So we add 1 in each size of the 
  // comparison.
  //
  IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);

  if (IsPeiDb) {
    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);
  } else {
    LocalTokenNumberTableIdx -= mPeiLocalTokenCount;
    LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
    SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);
  }

  LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];

  ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
  
  SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);

  MaxSize = SizeTable[SizeTableIdx];
  //
  // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type 
  // PCD entry.
  //
  if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
      //
      // We shouldn't come here as we don't support SET for VPD
      //
      ASSERT (FALSE);
      return FALSE;
  } else {
    if ((*CurrentSize > MaxSize) ||
      (*CurrentSize == MAX_ADDRESS)) {
       *CurrentSize = MaxSize;
       return FALSE;
    } 
    
    //
    // We have only two entry for Non-Sku enabled PCD entry:
    // 1) MAX SIZE
    // 2) Current Size
    //
    SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;
    return TRUE;
  }
}

/**
  VariableLock DynamicHiiPcd.

  @param[in] IsPeiDb        If TRUE, the pcd entry is initialized in PEI phase,
                            If FALSE, the pcd entry is initialized in DXE phase.
  @param[in] VariableLock   Pointer to VariableLockProtocol.

**/
VOID
VariableLockDynamicHiiPcd (
  IN BOOLEAN                        IsPeiDb,
  IN EDKII_VARIABLE_LOCK_PROTOCOL   *VariableLock
  )
{
  EFI_STATUS                Status;
  PCD_DATABASE_INIT         *Database;
  UINT32                    LocalTokenCount; 
  UINTN                     TokenNumber;
  UINT32                    LocalTokenNumber;
  UINTN                     Offset;
  EFI_GUID                  *GuidTable;
  UINT8                     *StringTable;
  VARIABLE_HEAD             *VariableHead;
  EFI_GUID                  *Guid;
  UINT16                    *Name;

  Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;
  LocalTokenCount = IsPeiDb ? mPeiLocalTokenCount: mDxeLocalTokenCount;

  //
  // Go through PCD database to find out DynamicHii PCDs.
  //
  for (TokenNumber = 1; TokenNumber <= LocalTokenCount; TokenNumber++) {
    if (IsPeiDb) {
      LocalTokenNumber = GetLocalTokenNumber (TRUE, TokenNumber);
    } else {
      LocalTokenNumber = GetLocalTokenNumber (FALSE, TokenNumber + mPeiLocalTokenCount);
    }
    if ((LocalTokenNumber & PCD_TYPE_HII) != 0) {
      Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
      VariableHead = (VARIABLE_HEAD *) ((UINT8 *) Database + Offset);
      //
      // Why not to set property by VarCheckProtocol with Attributes and Property directly here?
      // It is because that set property by VarCheckProtocol will indicate the variable to
      // be a system variable, but the unknown max size of the variable is dangerous to
      // the system variable region.
      //
      if ((VariableHead->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0) {
        //
        // DynamicHii PCD with RO property set in *.dsc.
        //
        StringTable = (UINT8 *) ((UINT8 *) Database + Database->StringTableOffset);
        GuidTable = (EFI_GUID *) ((UINT8 *) Database + Database->GuidTableOffset);
        Guid = GuidTable + VariableHead->GuidTableIndex;
        Name = (UINT16*) (StringTable + VariableHead->StringIndex);
        Status = VariableLock->RequestToLock (VariableLock, Name, Guid);
        ASSERT_EFI_ERROR (Status);
      }
    }
  }
}

/**
  VariableLockProtocol callback
  to lock the variables referenced by DynamicHii PCDs with RO property set in *.dsc.

  @param[in] Event      Event whose notification function is being invoked.
  @param[in] Context    Pointer to the notification function's context.

**/
VOID
EFIAPI
VariableLockCallBack (
  IN EFI_EVENT          Event,
  IN VOID               *Context
  )
{
  EFI_STATUS                    Status;
  EDKII_VARIABLE_LOCK_PROTOCOL  *VariableLock;

  Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);
  if (!EFI_ERROR (Status)) {
    VariableLockDynamicHiiPcd (TRUE, VariableLock);
    VariableLockDynamicHiiPcd (FALSE, VariableLock);
  }
}

