/** @file
    Help functions used by PCD DXE driver.

Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016-2021 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#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);
      ASSERT (mVpdBaseAddress != 0);
      RetPtr = (VOID *)(mVpdBaseAddress + 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 == 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;

  if (Index == mDxePcdDbSize) {
    return EFI_SUCCESS;
  }

  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;
    }
  }

  DEBUG ((DEBUG_ERROR, "%a: Failed to find PCD with GUID: %g and token number: %d\n", __func__, Guid, ExTokenNumber));
  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);
  }
}
