/** @file
  CPU Register Table Library functions.

  Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "RegisterCpuFeatures.h"

/**
  Function that uses DEBUG() macros to display the contents of a a CPU feature bit mask.

  @param[in]  FeatureMask  A pointer to the CPU feature bit mask.
  @param[in]  BitMaskSize  CPU feature bits mask buffer size.

**/
VOID
DumpCpuFeatureMask (
  IN UINT8   *FeatureMask,
  IN UINT32  BitMaskSize
  )
{
  UINTN  Index;
  UINT8  *Data8;

  Data8 = (UINT8 *)FeatureMask;
  for (Index = 0; Index < BitMaskSize; Index++) {
    DEBUG ((DEBUG_INFO, " %02x ", *Data8++));
  }

  DEBUG ((DEBUG_INFO, "\n"));
}

/**
  Dump CPU feature name or CPU feature bit mask.

  @param[in]  CpuFeature   Pointer to CPU_FEATURES_ENTRY
  @param[in]  BitMaskSize  CPU feature bits mask buffer size.

**/
VOID
DumpCpuFeature (
  IN CPU_FEATURES_ENTRY  *CpuFeature,
  IN UINT32              BitMaskSize
  )
{
  if (CpuFeature->FeatureName != NULL) {
    DEBUG ((DEBUG_INFO, "FeatureName: %a\n", CpuFeature->FeatureName));
  } else {
    DEBUG ((DEBUG_INFO, "FeatureMask = "));
    DumpCpuFeatureMask (CpuFeature->FeatureMask, BitMaskSize);
  }
}

/**
  Determines if the feature bit mask is in dependent CPU feature bit mask buffer.

  @param[in]  FeatureMask        Pointer to CPU feature bit mask
  @param[in]  DependentBitMask   Pointer to dependent CPU feature bit mask buffer

  @retval TRUE  The feature bit mask is in dependent CPU feature bit mask buffer.
  @retval FALSE The feature bit mask is not in dependent CPU feature bit mask buffer.
**/
BOOLEAN
IsBitMaskMatchCheck (
  IN UINT8  *FeatureMask,
  IN UINT8  *DependentBitMask
  )
{
  UINTN              Index;
  UINT8              *Data1;
  UINT8              *Data2;
  CPU_FEATURES_DATA  *CpuFeaturesData;

  CpuFeaturesData = GetCpuFeaturesData ();

  Data1 = FeatureMask;
  Data2 = DependentBitMask;
  for (Index = 0; Index < CpuFeaturesData->BitMaskSize; Index++) {
    if (((*(Data1++)) & (*(Data2++))) != 0) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Try to find the specify cpu featuren in former/after feature list.

  @param[in]  FeatureList        Pointer to dependent CPU feature list
  @param[in]  CurrentEntry       Pointer to current CPU feature entry.
  @param[in]  SearchFormer       Find in former feature or after features.
  @param[in]  FeatureMask        Pointer to CPU feature bit mask

  @retval TRUE  The feature bit mask is in dependent CPU feature bit mask buffer.
  @retval FALSE The feature bit mask is not in dependent CPU feature bit mask buffer.
**/
BOOLEAN
FindSpecifyFeature (
  IN LIST_ENTRY  *FeatureList,
  IN LIST_ENTRY  *CurrentEntry,
  IN BOOLEAN     SearchFormer,
  IN UINT8       *FeatureMask
  )
{
  CPU_FEATURES_ENTRY  *CpuFeature;
  LIST_ENTRY          *NextEntry;

  //
  // Check whether exist the not neighborhood entry first.
  // If not exist, return FALSE means not found status.
  //
  if (SearchFormer) {
    NextEntry = CurrentEntry->BackLink;
    if (IsNull (FeatureList, NextEntry)) {
      return FALSE;
    }

    NextEntry = NextEntry->BackLink;
    if (IsNull (FeatureList, NextEntry)) {
      return FALSE;
    }

    NextEntry = CurrentEntry->BackLink->BackLink;
  } else {
    NextEntry = CurrentEntry->ForwardLink;
    if (IsNull (FeatureList, NextEntry)) {
      return FALSE;
    }

    NextEntry = NextEntry->ForwardLink;
    if (IsNull (FeatureList, NextEntry)) {
      return FALSE;
    }

    NextEntry = CurrentEntry->ForwardLink->ForwardLink;
  }

  while (!IsNull (FeatureList, NextEntry)) {
    CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry);

    if (IsBitMaskMatchCheck (FeatureMask, CpuFeature->FeatureMask)) {
      return TRUE;
    }

    if (SearchFormer) {
      NextEntry = NextEntry->BackLink;
    } else {
      NextEntry = NextEntry->ForwardLink;
    }
  }

  return FALSE;
}

/**
  Return feature dependence result.

  @param[in]  CpuFeature            Pointer to CPU feature.
  @param[in]  Before                Check before dependence or after.
  @param[in]  NextCpuFeatureMask    Pointer to next CPU feature Mask.

  @retval     return the dependence result.
**/
CPU_FEATURE_DEPENDENCE_TYPE
DetectFeatureScope (
  IN CPU_FEATURES_ENTRY  *CpuFeature,
  IN BOOLEAN             Before,
  IN UINT8               *NextCpuFeatureMask
  )
{
  //
  // if need to check before type dependence but the feature after current feature is not
  // exist, means this before type dependence not valid, just return NoneDepType.
  // Just like Feature A has a dependence of feature B, but Feature B not installed, so
  // Feature A maybe insert to the last entry of the list. In this case, for below code,
  // Featrure A has depend of feature B, but it is the last entry of the list, so the
  // NextCpuFeatureMask is NULL, so the dependence for feature A here is useless and code
  // just return NoneDepType.
  //
  if (NextCpuFeatureMask == NULL) {
    return NoneDepType;
  }

  if (Before) {
    if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) &&
        IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageBeforeFeatureBitMask))
    {
      return PackageDepType;
    }

    if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) &&
        IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreBeforeFeatureBitMask))
    {
      return CoreDepType;
    }

    if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) &&
        IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadBeforeFeatureBitMask))
    {
      return ThreadDepType;
    }

    return NoneDepType;
  }

  if ((CpuFeature->PackageAfterFeatureBitMask != NULL) &&
      IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageAfterFeatureBitMask))
  {
    return PackageDepType;
  }

  if ((CpuFeature->CoreAfterFeatureBitMask != NULL) &&
      IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreAfterFeatureBitMask))
  {
    return CoreDepType;
  }

  if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) &&
      IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadAfterFeatureBitMask))
  {
    return ThreadDepType;
  }

  return NoneDepType;
}

/**
  Return feature dependence result.

  @param[in]  CpuFeature            Pointer to CPU feature.
  @param[in]  Before                Check before dependence or after.
  @param[in]  FeatureList           Pointer to CPU feature list.

  @retval     return the dependence result.
**/
CPU_FEATURE_DEPENDENCE_TYPE
DetectNoneNeighborhoodFeatureScope (
  IN CPU_FEATURES_ENTRY  *CpuFeature,
  IN BOOLEAN             Before,
  IN LIST_ENTRY          *FeatureList
  )
{
  if (Before) {
    if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) &&
        FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->PackageBeforeFeatureBitMask))
    {
      return PackageDepType;
    }

    if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) &&
        FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->CoreBeforeFeatureBitMask))
    {
      return CoreDepType;
    }

    if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) &&
        FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->ThreadBeforeFeatureBitMask))
    {
      return ThreadDepType;
    }

    return NoneDepType;
  }

  if ((CpuFeature->PackageAfterFeatureBitMask != NULL) &&
      FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->PackageAfterFeatureBitMask))
  {
    return PackageDepType;
  }

  if ((CpuFeature->CoreAfterFeatureBitMask != NULL) &&
      FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->CoreAfterFeatureBitMask))
  {
    return CoreDepType;
  }

  if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) &&
      FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->ThreadAfterFeatureBitMask))
  {
    return ThreadDepType;
  }

  return NoneDepType;
}

/**
  Base on dependence relationship to asjust feature dependence.

  ONLY when the feature before(or after) the find feature also has
  dependence with the find feature. In this case, driver need to base
  on dependce relationship to decide how to insert current feature and
  adjust the feature dependence.

  @param[in, out]  PreviousFeature    CPU feature current before the find one.
  @param[in, out]  CurrentFeature     Cpu feature need to adjust.
  @param[in]       FindFeature        Cpu feature which current feature depends.
  @param[in]       Before             Before or after dependence relationship.

  @retval   TRUE   means the current feature dependence has been adjusted.

  @retval   FALSE  means the previous feature dependence has been adjusted.
                   or previous feature has no dependence with the find one.

**/
BOOLEAN
AdjustFeaturesDependence (
  IN OUT CPU_FEATURES_ENTRY  *PreviousFeature,
  IN OUT CPU_FEATURES_ENTRY  *CurrentFeature,
  IN     CPU_FEATURES_ENTRY  *FindFeature,
  IN     BOOLEAN             Before
  )
{
  CPU_FEATURE_DEPENDENCE_TYPE  PreDependType;
  CPU_FEATURE_DEPENDENCE_TYPE  CurrentDependType;

  PreDependType     = DetectFeatureScope (PreviousFeature, Before, FindFeature->FeatureMask);
  CurrentDependType = DetectFeatureScope (CurrentFeature, Before, FindFeature->FeatureMask);

  //
  // If previous feature has no dependence with the find featue.
  // return FALSE.
  //
  if (PreDependType == NoneDepType) {
    return FALSE;
  }

  //
  // If both feature have dependence, keep the one which needs use more
  // processors and clear the dependence for the other one.
  //
  if (PreDependType >= CurrentDependType) {
    return TRUE;
  } else {
    return FALSE;
  }
}

/**
  Base on dependence relationship to asjust feature order.

  @param[in]       FeatureList        Pointer to CPU feature list
  @param[in, out]  FindEntry          The entry this feature depend on.
  @param[in, out]  CurrentEntry       The entry for this feature.
  @param[in]       Before             Before or after dependence relationship.

**/
VOID
AdjustEntry (
  IN      LIST_ENTRY  *FeatureList,
  IN OUT  LIST_ENTRY  *FindEntry,
  IN OUT  LIST_ENTRY  *CurrentEntry,
  IN      BOOLEAN     Before
  )
{
  LIST_ENTRY          *PreviousEntry;
  CPU_FEATURES_ENTRY  *PreviousFeature;
  CPU_FEATURES_ENTRY  *CurrentFeature;
  CPU_FEATURES_ENTRY  *FindFeature;

  //
  // For CPU feature which has core or package type dependence, later code need to insert
  // AcquireSpinLock/ReleaseSpinLock logic to sequency the execute order.
  // So if driver finds both feature A and B need to execute before feature C, driver will
  // base on dependence type of feature A and B to update the logic here.
  // For example, feature A has package type dependence and feature B has core type dependence,
  // because package type dependence need to wait for more processors which has strong dependence
  // than core type dependence. So driver will adjust the feature order to B -> A -> C. and driver
  // will remove the feature dependence in feature B.
  // Driver just needs to make sure before feature C been executed, feature A has finished its task
  // in all all thread. Feature A finished in all threads also means feature B have finshed in all
  // threads.
  //
  if (Before) {
    PreviousEntry = GetPreviousNode (FeatureList, FindEntry);
  } else {
    PreviousEntry = GetNextNode (FeatureList, FindEntry);
  }

  CurrentFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);
  RemoveEntryList (CurrentEntry);

  if (IsNull (FeatureList, PreviousEntry)) {
    //
    // If not exist the previous or next entry, just insert the current entry.
    //
    if (Before) {
      InsertTailList (FindEntry, CurrentEntry);
    } else {
      InsertHeadList (FindEntry, CurrentEntry);
    }
  } else {
    //
    // If exist the previous or next entry, need to check it before insert curent entry.
    //
    PreviousFeature = CPU_FEATURE_ENTRY_FROM_LINK (PreviousEntry);
    FindFeature     = CPU_FEATURE_ENTRY_FROM_LINK (FindEntry);

    if (AdjustFeaturesDependence (PreviousFeature, CurrentFeature, FindFeature, Before)) {
      //
      // Return TRUE means current feature dependence has been cleared and the previous
      // feature dependence has been kept and used. So insert current feature before (or after)
      // the previous feature.
      //
      if (Before) {
        InsertTailList (PreviousEntry, CurrentEntry);
      } else {
        InsertHeadList (PreviousEntry, CurrentEntry);
      }
    } else {
      if (Before) {
        InsertTailList (FindEntry, CurrentEntry);
      } else {
        InsertHeadList (FindEntry, CurrentEntry);
      }
    }
  }
}

/**
  Checks and adjusts current CPU features per dependency relationship.

  @param[in]  FeatureList        Pointer to CPU feature list
  @param[in]  CurrentEntry       Pointer to current checked CPU feature
  @param[in]  FeatureMask        The feature bit mask.

  @retval     return Swapped info.
**/
BOOLEAN
InsertToBeforeEntry (
  IN LIST_ENTRY  *FeatureList,
  IN LIST_ENTRY  *CurrentEntry,
  IN UINT8       *FeatureMask
  )
{
  LIST_ENTRY          *CheckEntry;
  CPU_FEATURES_ENTRY  *CheckFeature;
  BOOLEAN             Swapped;

  Swapped = FALSE;

  //
  // Check all features dispatched before this entry
  //
  CheckEntry = GetFirstNode (FeatureList);
  while (CheckEntry != CurrentEntry) {
    CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);
    if (IsBitMaskMatchCheck (CheckFeature->FeatureMask, FeatureMask)) {
      AdjustEntry (FeatureList, CheckEntry, CurrentEntry, TRUE);
      Swapped = TRUE;
      break;
    }

    CheckEntry = CheckEntry->ForwardLink;
  }

  return Swapped;
}

/**
  Checks and adjusts current CPU features per dependency relationship.

  @param[in]  FeatureList        Pointer to CPU feature list
  @param[in]  CurrentEntry       Pointer to current checked CPU feature
  @param[in]  FeatureMask        The feature bit mask.

  @retval     return Swapped info.
**/
BOOLEAN
InsertToAfterEntry (
  IN LIST_ENTRY  *FeatureList,
  IN LIST_ENTRY  *CurrentEntry,
  IN UINT8       *FeatureMask
  )
{
  LIST_ENTRY          *CheckEntry;
  CPU_FEATURES_ENTRY  *CheckFeature;
  BOOLEAN             Swapped;

  Swapped = FALSE;

  //
  // Check all features dispatched after this entry
  //
  CheckEntry = GetNextNode (FeatureList, CurrentEntry);
  while (!IsNull (FeatureList, CheckEntry)) {
    CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);
    if (IsBitMaskMatchCheck (CheckFeature->FeatureMask, FeatureMask)) {
      AdjustEntry (FeatureList, CheckEntry, CurrentEntry, FALSE);
      Swapped = TRUE;
      break;
    }

    CheckEntry = CheckEntry->ForwardLink;
  }

  return Swapped;
}

/**
  Checks and adjusts CPU features order per dependency relationship.

  @param[in]  FeatureList        Pointer to CPU feature list
**/
VOID
CheckCpuFeaturesDependency (
  IN LIST_ENTRY  *FeatureList
  )
{
  LIST_ENTRY          *CurrentEntry;
  CPU_FEATURES_ENTRY  *CpuFeature;
  LIST_ENTRY          *CheckEntry;
  CPU_FEATURES_ENTRY  *CheckFeature;
  BOOLEAN             Swapped;
  LIST_ENTRY          *TempEntry;
  LIST_ENTRY          *NextEntry;

  CurrentEntry = GetFirstNode (FeatureList);
  while (!IsNull (FeatureList, CurrentEntry)) {
    Swapped    = FALSE;
    CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);
    NextEntry  = CurrentEntry->ForwardLink;
    if (CpuFeature->BeforeAll) {
      //
      // Check all features dispatched before this entry
      //
      CheckEntry = GetFirstNode (FeatureList);
      while (CheckEntry != CurrentEntry) {
        CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);
        if (!CheckFeature->BeforeAll) {
          //
          // If this feature has no BeforeAll flag and is dispatched before CpuFeature,
          // insert currentEntry before Checked feature
          //
          RemoveEntryList (CurrentEntry);
          InsertTailList (CheckEntry, CurrentEntry);
          Swapped = TRUE;
          break;
        }

        CheckEntry = CheckEntry->ForwardLink;
      }

      if (Swapped) {
        CurrentEntry = NextEntry;
        continue;
      }
    }

    if (CpuFeature->AfterAll) {
      //
      // Check all features dispatched after this entry
      //
      CheckEntry = GetNextNode (FeatureList, CurrentEntry);
      while (!IsNull (FeatureList, CheckEntry)) {
        CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);
        if (!CheckFeature->AfterAll) {
          //
          // If this feature has no AfterAll flag and is dispatched after CpuFeature,
          // insert currentEntry after Checked feature
          //
          TempEntry = GetNextNode (FeatureList, CurrentEntry);
          RemoveEntryList (CurrentEntry);
          InsertHeadList (CheckEntry, CurrentEntry);
          CurrentEntry = TempEntry;
          Swapped      = TRUE;
          break;
        }

        CheckEntry = CheckEntry->ForwardLink;
      }

      if (Swapped) {
        CurrentEntry = NextEntry;
        continue;
      }
    }

    if (CpuFeature->ThreadBeforeFeatureBitMask != NULL) {
      Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->ThreadBeforeFeatureBitMask);
      if (Swapped) {
        continue;
      }
    }

    if (CpuFeature->ThreadAfterFeatureBitMask != NULL) {
      Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->ThreadAfterFeatureBitMask);
      if (Swapped) {
        continue;
      }
    }

    if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {
      Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->CoreBeforeFeatureBitMask);
      if (Swapped) {
        continue;
      }
    }

    if (CpuFeature->CoreAfterFeatureBitMask != NULL) {
      Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->CoreAfterFeatureBitMask);
      if (Swapped) {
        continue;
      }
    }

    if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {
      Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->PackageBeforeFeatureBitMask);
      if (Swapped) {
        continue;
      }
    }

    if (CpuFeature->PackageAfterFeatureBitMask != NULL) {
      Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->PackageAfterFeatureBitMask);
      if (Swapped) {
        continue;
      }
    }

    CurrentEntry = CurrentEntry->ForwardLink;
  }
}

/**
  Worker function to register CPU Feature.

  @param[in]  CpuFeaturesData       Pointer to CPU feature data structure.
  @param[in]  CpuFeature            Pointer to CPU feature entry

  @retval  RETURN_SUCCESS           The CPU feature was successfully registered.
  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources to register
                                    the CPU feature.
  @retval  RETURN_UNSUPPORTED       Registration of the CPU feature is not
                                    supported due to a circular dependency between
                                    BEFORE and AFTER features.
**/
RETURN_STATUS
RegisterCpuFeatureWorker (
  IN CPU_FEATURES_DATA   *CpuFeaturesData,
  IN CPU_FEATURES_ENTRY  *CpuFeature
  )
{
  EFI_STATUS          Status;
  CPU_FEATURES_ENTRY  *CpuFeatureEntry;
  LIST_ENTRY          *Entry;
  BOOLEAN             FeatureExist;

  FeatureExist    = FALSE;
  CpuFeatureEntry = NULL;
  Entry           = GetFirstNode (&CpuFeaturesData->FeatureList);
  while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {
    CpuFeatureEntry = CPU_FEATURE_ENTRY_FROM_LINK (Entry);
    if (CompareMem (CpuFeature->FeatureMask, CpuFeatureEntry->FeatureMask, CpuFeaturesData->BitMaskSize) == 0) {
      //
      // If this feature already registered
      //
      FeatureExist = TRUE;
      break;
    }

    Entry = Entry->ForwardLink;
  }

  if (!FeatureExist) {
    DEBUG ((DEBUG_INFO, "[NEW] "));
    DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize);
    InsertTailList (&CpuFeaturesData->FeatureList, &CpuFeature->Link);
    CpuFeaturesData->FeaturesCount++;
  } else {
    DEBUG ((DEBUG_INFO, "[OVERRIDE] "));
    DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize);
    ASSERT (CpuFeatureEntry != NULL);
    //
    // Overwrite original parameters of CPU feature
    //
    if (CpuFeature->GetConfigDataFunc != NULL) {
      CpuFeatureEntry->GetConfigDataFunc = CpuFeature->GetConfigDataFunc;
    }

    if (CpuFeature->SupportFunc != NULL) {
      CpuFeatureEntry->SupportFunc = CpuFeature->SupportFunc;
    }

    if (CpuFeature->InitializeFunc != NULL) {
      CpuFeatureEntry->InitializeFunc = CpuFeature->InitializeFunc;
    }

    if (CpuFeature->FeatureName != NULL) {
      if (CpuFeatureEntry->FeatureName == NULL) {
        CpuFeatureEntry->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE);
        ASSERT (CpuFeatureEntry->FeatureName != NULL);
      }

      Status = AsciiStrCpyS (CpuFeatureEntry->FeatureName, CPU_FEATURE_NAME_SIZE, CpuFeature->FeatureName);
      ASSERT_EFI_ERROR (Status);
      FreePool (CpuFeature->FeatureName);
    }

    if (CpuFeature->ThreadBeforeFeatureBitMask != NULL) {
      if (CpuFeatureEntry->ThreadBeforeFeatureBitMask != NULL) {
        FreePool (CpuFeatureEntry->ThreadBeforeFeatureBitMask);
      }

      CpuFeatureEntry->ThreadBeforeFeatureBitMask = CpuFeature->ThreadBeforeFeatureBitMask;
    }

    if (CpuFeature->ThreadAfterFeatureBitMask != NULL) {
      if (CpuFeatureEntry->ThreadAfterFeatureBitMask != NULL) {
        FreePool (CpuFeatureEntry->ThreadAfterFeatureBitMask);
      }

      CpuFeatureEntry->ThreadAfterFeatureBitMask = CpuFeature->ThreadAfterFeatureBitMask;
    }

    if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {
      if (CpuFeatureEntry->CoreBeforeFeatureBitMask != NULL) {
        FreePool (CpuFeatureEntry->CoreBeforeFeatureBitMask);
      }

      CpuFeatureEntry->CoreBeforeFeatureBitMask = CpuFeature->CoreBeforeFeatureBitMask;
    }

    if (CpuFeature->CoreAfterFeatureBitMask != NULL) {
      if (CpuFeatureEntry->CoreAfterFeatureBitMask != NULL) {
        FreePool (CpuFeatureEntry->CoreAfterFeatureBitMask);
      }

      CpuFeatureEntry->CoreAfterFeatureBitMask = CpuFeature->CoreAfterFeatureBitMask;
    }

    if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {
      if (CpuFeatureEntry->PackageBeforeFeatureBitMask != NULL) {
        FreePool (CpuFeatureEntry->PackageBeforeFeatureBitMask);
      }

      CpuFeatureEntry->PackageBeforeFeatureBitMask = CpuFeature->PackageBeforeFeatureBitMask;
    }

    if (CpuFeature->PackageAfterFeatureBitMask != NULL) {
      if (CpuFeatureEntry->PackageAfterFeatureBitMask != NULL) {
        FreePool (CpuFeatureEntry->PackageAfterFeatureBitMask);
      }

      CpuFeatureEntry->PackageAfterFeatureBitMask = CpuFeature->PackageAfterFeatureBitMask;
    }

    CpuFeatureEntry->BeforeAll = CpuFeature->BeforeAll;
    CpuFeatureEntry->AfterAll  = CpuFeature->AfterAll;

    FreePool (CpuFeature->FeatureMask);
    FreePool (CpuFeature);
  }

  //
  // Verify CPU features dependency can change CPU feature order
  //
  CheckCpuFeaturesDependency (&CpuFeaturesData->FeatureList);
  return RETURN_SUCCESS;
}

/**
  Sets CPU feature bit mask in CPU feature bit mask buffer.

  @param[in]  FeaturesBitMask       Pointer to CPU feature bit mask buffer
  @param[in]  Feature               The bit number of the CPU feature
  @param[in]  BitMaskSize           CPU feature bit mask buffer size
**/
VOID
SetCpuFeaturesBitMask (
  IN UINT8   **FeaturesBitMask,
  IN UINT32  Feature,
  IN UINTN   BitMaskSize
  )
{
  UINT8  *CpuFeaturesBitMask;

  ASSERT (FeaturesBitMask != NULL);
  CpuFeaturesBitMask = *FeaturesBitMask;
  if (CpuFeaturesBitMask == NULL) {
    CpuFeaturesBitMask = AllocateZeroPool (BitMaskSize);
    ASSERT (CpuFeaturesBitMask != NULL);
    *FeaturesBitMask = CpuFeaturesBitMask;
  }

  CpuFeaturesBitMask  += (Feature / 8);
  *CpuFeaturesBitMask |= (UINT8)(1 << (Feature % 8));
}

/**
  Registers a CPU Feature.

  @param[in]  FeatureName        A Null-terminated Ascii string indicates CPU feature
                                 name.
  @param[in]  GetConfigDataFunc  CPU feature get configuration data function.  This
                                 is an optional parameter that may be NULL.  If NULL,
                                 then the most recently registered function for the
                                 CPU feature is used.  If no functions are registered
                                 for a CPU feature, then the CPU configuration data
                                 for the registered feature is NULL.
  @param[in]  SupportFunc        CPU feature support function.  This is an optional
                                 parameter that may be NULL.  If NULL, then the most
                                 recently registered function for the CPU feature is
                                 used. If no functions are registered for a CPU
                                 feature, then the CPU feature is assumed to be
                                 supported by all CPUs.
  @param[in]  InitializeFunc     CPU feature initialize function.  This is an optional
                                 parameter that may be NULL.  If NULL, then the most
                                 recently registered function for the CPU feature is
                                 used. If no functions are registered for a CPU
                                 feature, then the CPU feature initialization is
                                 skipped.
  @param[in]  ...                Variable argument list of UINT32 CPU feature value.
                                 Values with no modifiers are the features provided
                                 by the registered functions.
                                 Values with CPU_FEATURE_BEFORE modifier are features
                                 that must be initialized after the features provided
                                 by the registered functions are used.
                                 Values with CPU_FEATURE_AFTER modifier are features
                                 that must be initialized before the features provided
                                 by the registered functions are used.
                                 The last argument in this variable argument list must
                                 always be CPU_FEATURE_END.

  @retval  RETURN_SUCCESS           The CPU feature was successfully registered.
  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources to register
                                    the CPU feature.
  @retval  RETURN_UNSUPPORTED       Registration of the CPU feature is not
                                    supported due to a circular dependency between
                                    BEFORE and AFTER features.
  @retval  RETURN_NOT_READY         CPU feature PCD PcdCpuFeaturesUserConfiguration
                                    not updated by Platform driver yet.

  @note This service could be called by BSP only.
**/
RETURN_STATUS
EFIAPI
RegisterCpuFeature (
  IN CHAR8                        *FeatureName        OPTIONAL,
  IN CPU_FEATURE_GET_CONFIG_DATA  GetConfigDataFunc   OPTIONAL,
  IN CPU_FEATURE_SUPPORT          SupportFunc         OPTIONAL,
  IN CPU_FEATURE_INITIALIZE       InitializeFunc      OPTIONAL,
  ...
  )
{
  EFI_STATUS          Status;
  VA_LIST             Marker;
  UINT32              Feature;
  CPU_FEATURES_ENTRY  *CpuFeature;
  UINT8               *FeatureMask;
  UINT8               *ThreadBeforeFeatureBitMask;
  UINT8               *ThreadAfterFeatureBitMask;
  UINT8               *CoreBeforeFeatureBitMask;
  UINT8               *CoreAfterFeatureBitMask;
  UINT8               *PackageBeforeFeatureBitMask;
  UINT8               *PackageAfterFeatureBitMask;
  BOOLEAN             BeforeAll;
  BOOLEAN             AfterAll;
  CPU_FEATURES_DATA   *CpuFeaturesData;

  FeatureMask                 = NULL;
  ThreadBeforeFeatureBitMask  = NULL;
  ThreadAfterFeatureBitMask   = NULL;
  CoreBeforeFeatureBitMask    = NULL;
  CoreAfterFeatureBitMask     = NULL;
  PackageBeforeFeatureBitMask = NULL;
  PackageAfterFeatureBitMask  = NULL;
  BeforeAll                   = FALSE;
  AfterAll                    = FALSE;

  CpuFeaturesData = GetCpuFeaturesData ();
  if (CpuFeaturesData->FeaturesCount == 0) {
    InitializeListHead (&CpuFeaturesData->FeatureList);
    InitializeSpinLock (&CpuFeaturesData->CpuFlags.MemoryMappedLock);
    //
    // Code assumes below three PCDs have PCD same buffer size.
    //
    ASSERT (PcdGetSize (PcdCpuFeaturesSetting) == PcdGetSize (PcdCpuFeaturesCapability));
    ASSERT (PcdGetSize (PcdCpuFeaturesSetting) == PcdGetSize (PcdCpuFeaturesSupport));
    CpuFeaturesData->BitMaskSize = (UINT32)PcdGetSize (PcdCpuFeaturesSetting);
  }

  VA_START (Marker, InitializeFunc);
  Feature = VA_ARG (Marker, UINT32);
  while (Feature != CPU_FEATURE_END) {
    //
    // It's invalid to require a feature is before AND after all other features.
    //
    ASSERT (
      (Feature & (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL))
      != (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL)
      );

    //
    // It's invalid to require feature A is before AND after before feature B,
    // either in thread level, core level or package level.
    //
    ASSERT (
      (Feature & (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER))
      != (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER)
      );
    ASSERT (
      (Feature & (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER))
      != (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER)
      );
    ASSERT (
      (Feature & (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER))
      != (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER)
      );
    if (Feature < CPU_FEATURE_THREAD_BEFORE) {
      BeforeAll = ((Feature & CPU_FEATURE_BEFORE_ALL) != 0) ? TRUE : FALSE;
      AfterAll  = ((Feature & CPU_FEATURE_AFTER_ALL) != 0) ? TRUE : FALSE;
      Feature  &= ~(CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL);
      ASSERT (FeatureMask == NULL);
      SetCpuFeaturesBitMask (&FeatureMask, Feature, CpuFeaturesData->BitMaskSize);
    } else if ((Feature & CPU_FEATURE_THREAD_BEFORE) != 0) {
      SetCpuFeaturesBitMask (&ThreadBeforeFeatureBitMask, Feature & ~CPU_FEATURE_THREAD_BEFORE, CpuFeaturesData->BitMaskSize);
    } else if ((Feature & CPU_FEATURE_THREAD_AFTER) != 0) {
      SetCpuFeaturesBitMask (&ThreadAfterFeatureBitMask, Feature & ~CPU_FEATURE_THREAD_AFTER, CpuFeaturesData->BitMaskSize);
    } else if ((Feature & CPU_FEATURE_CORE_BEFORE) != 0) {
      SetCpuFeaturesBitMask (&CoreBeforeFeatureBitMask, Feature & ~CPU_FEATURE_CORE_BEFORE, CpuFeaturesData->BitMaskSize);
    } else if ((Feature & CPU_FEATURE_CORE_AFTER) != 0) {
      SetCpuFeaturesBitMask (&CoreAfterFeatureBitMask, Feature & ~CPU_FEATURE_CORE_AFTER, CpuFeaturesData->BitMaskSize);
    } else if ((Feature & CPU_FEATURE_PACKAGE_BEFORE) != 0) {
      SetCpuFeaturesBitMask (&PackageBeforeFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_BEFORE, CpuFeaturesData->BitMaskSize);
    } else if ((Feature & CPU_FEATURE_PACKAGE_AFTER) != 0) {
      SetCpuFeaturesBitMask (&PackageAfterFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_AFTER, CpuFeaturesData->BitMaskSize);
    }

    Feature = VA_ARG (Marker, UINT32);
  }

  VA_END (Marker);

  CpuFeature = AllocateZeroPool (sizeof (CPU_FEATURES_ENTRY));
  ASSERT (CpuFeature != NULL);
  CpuFeature->Signature                   = CPU_FEATURE_ENTRY_SIGNATURE;
  CpuFeature->FeatureMask                 = FeatureMask;
  CpuFeature->ThreadBeforeFeatureBitMask  = ThreadBeforeFeatureBitMask;
  CpuFeature->ThreadAfterFeatureBitMask   = ThreadAfterFeatureBitMask;
  CpuFeature->CoreBeforeFeatureBitMask    = CoreBeforeFeatureBitMask;
  CpuFeature->CoreAfterFeatureBitMask     = CoreAfterFeatureBitMask;
  CpuFeature->PackageBeforeFeatureBitMask = PackageBeforeFeatureBitMask;
  CpuFeature->PackageAfterFeatureBitMask  = PackageAfterFeatureBitMask;
  CpuFeature->BeforeAll                   = BeforeAll;
  CpuFeature->AfterAll                    = AfterAll;
  CpuFeature->GetConfigDataFunc           = GetConfigDataFunc;
  CpuFeature->SupportFunc                 = SupportFunc;
  CpuFeature->InitializeFunc              = InitializeFunc;
  if (FeatureName != NULL) {
    CpuFeature->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE);
    ASSERT (CpuFeature->FeatureName != NULL);
    Status = AsciiStrCpyS (CpuFeature->FeatureName, CPU_FEATURE_NAME_SIZE, FeatureName);
    ASSERT_EFI_ERROR (Status);
  }

  Status = RegisterCpuFeatureWorker (CpuFeaturesData, CpuFeature);
  ASSERT_EFI_ERROR (Status);

  return RETURN_SUCCESS;
}

/**
  Return ACPI_CPU_DATA data.

  @return  Pointer to ACPI_CPU_DATA data.
           NULL if the ACPI CPU data structure cannot be allocated.

**/
ACPI_CPU_DATA *
GetAcpiCpuData (
  VOID
  )
{
  EFI_STATUS                 Status;
  UINTN                      NumberOfCpus;
  UINTN                      NumberOfEnabledProcessors;
  ACPI_CPU_DATA              *AcpiCpuData;
  UINTN                      TableSize;
  CPU_REGISTER_TABLE         *RegisterTable;
  UINTN                      Index;
  EFI_PROCESSOR_INFORMATION  ProcessorInfoBuffer;

  AcpiCpuData = (ACPI_CPU_DATA *)(UINTN)PcdGet64 (PcdCpuS3DataAddress);
  if (AcpiCpuData == NULL) {
    AcpiCpuData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)));
    if (AcpiCpuData == NULL) {
      ASSERT (AcpiCpuData != NULL);
      return NULL;
    }

    ZeroMem (AcpiCpuData, sizeof (ACPI_CPU_DATA));

    //
    // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure
    //
    Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData);
    ASSERT_EFI_ERROR (Status);

    GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors);
    AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;
  }

  if ((AcpiCpuData->CpuFeatureInitData.RegisterTable == 0) ||
      (AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable == 0))
  {
    //
    // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs
    //
    NumberOfCpus  = AcpiCpuData->NumberOfCpus;
    TableSize     = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);
    RegisterTable = AllocatePages (EFI_SIZE_TO_PAGES (TableSize));
    if (RegisterTable == NULL) {
      // Leave the AcpiCpuData data buffer allocated since it was assigned to a dynamic PCD
      // which could have invoked PCD set callbacks that may have cached the buffer.
      ASSERT (RegisterTable != NULL);
      return NULL;
    }

    for (Index = 0; Index < NumberOfCpus; Index++) {
      Status = GetProcessorInformation (Index, &ProcessorInfoBuffer);
      ASSERT_EFI_ERROR (Status);

      RegisterTable[Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;
      RegisterTable[Index].TableLength        = 0;
      RegisterTable[Index].AllocatedSize      = 0;
      RegisterTable[Index].RegisterTableEntry = 0;

      RegisterTable[NumberOfCpus + Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;
      RegisterTable[NumberOfCpus + Index].TableLength        = 0;
      RegisterTable[NumberOfCpus + Index].AllocatedSize      = 0;
      RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;
    }

    if (AcpiCpuData->CpuFeatureInitData.RegisterTable == 0) {
      AcpiCpuData->CpuFeatureInitData.RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;
    }

    if (AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable == 0) {
      AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);
    }
  }

  return AcpiCpuData;
}

/**
  Enlarges CPU register table for each processor.

  @param[in, out]  RegisterTable   Pointer processor's CPU register table
**/
STATIC
VOID
EnlargeRegisterTable (
  IN OUT CPU_REGISTER_TABLE  *RegisterTable
  )
{
  EFI_PHYSICAL_ADDRESS  Address;
  UINTN                 UsedPages;

  UsedPages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;
  Address   = (UINTN)AllocatePages (UsedPages + 1);
  ASSERT (Address != 0);

  //
  // If there are records existing in the register table, then copy its contents
  // to new region and free the old one.
  //
  if (RegisterTable->AllocatedSize > 0) {
    CopyMem (
      (VOID *)(UINTN)Address,
      (VOID *)(UINTN)RegisterTable->RegisterTableEntry,
      RegisterTable->AllocatedSize
      );

    FreePages ((VOID *)(UINTN)RegisterTable->RegisterTableEntry, UsedPages);
  }

  //
  // Adjust the allocated size and register table base address.
  //
  RegisterTable->AllocatedSize     += EFI_PAGE_SIZE;
  RegisterTable->RegisterTableEntry = Address;
}

/**
  Add an entry in specified register table.

  This function adds an entry in specified register table, with given register type,
  register index, bit section and value.

  @param[in]  PreSmmFlag       If TRUE, entry will be added into PreSmm register table
                               If FALSE, entry will be added into register table
  @param[in]  ProcessorNumber  The index of the CPU to add a register table entry
  @param[in]  RegisterType     Type of the register to program
  @param[in]  Index            Index of the register to program
  @param[in]  ValidBitStart    Start of the bit section
  @param[in]  ValidBitLength   Length of the bit section
  @param[in]  Value            Value to write
  @param[in]  TestThenWrite    Whether need to test current Value before writing.

**/
VOID
CpuRegisterTableWriteWorker (
  IN BOOLEAN        PreSmmFlag,
  IN UINTN          ProcessorNumber,
  IN REGISTER_TYPE  RegisterType,
  IN UINT64         Index,
  IN UINT8          ValidBitStart,
  IN UINT8          ValidBitLength,
  IN UINT64         Value,
  IN BOOLEAN        TestThenWrite
  )
{
  CPU_FEATURES_DATA         *CpuFeaturesData;
  ACPI_CPU_DATA             *AcpiCpuData;
  CPU_REGISTER_TABLE        *RegisterTable;
  CPU_REGISTER_TABLE_ENTRY  *RegisterTableEntry;

  CpuFeaturesData = GetCpuFeaturesData ();
  if (CpuFeaturesData->RegisterTable == NULL) {
    AcpiCpuData = GetAcpiCpuData ();
    if (AcpiCpuData == NULL) {
      ASSERT (AcpiCpuData != NULL);
      return;
    }

    ASSERT (AcpiCpuData->CpuFeatureInitData.RegisterTable != 0);
    CpuFeaturesData->RegisterTable       = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->CpuFeatureInitData.RegisterTable;
    CpuFeaturesData->PreSmmRegisterTable = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable;
  }

  if (PreSmmFlag) {
    RegisterTable = &CpuFeaturesData->PreSmmRegisterTable[ProcessorNumber];
  } else {
    RegisterTable = &CpuFeaturesData->RegisterTable[ProcessorNumber];
  }

  if (RegisterTable->TableLength == RegisterTable->AllocatedSize / sizeof (CPU_REGISTER_TABLE_ENTRY)) {
    EnlargeRegisterTable (RegisterTable);
  }

  //
  // Append entry in the register table.
  //
  RegisterTableEntry                                            = (CPU_REGISTER_TABLE_ENTRY *)(UINTN)RegisterTable->RegisterTableEntry;
  RegisterTableEntry[RegisterTable->TableLength].RegisterType   = RegisterType;
  RegisterTableEntry[RegisterTable->TableLength].Index          = (UINT32)Index;
  RegisterTableEntry[RegisterTable->TableLength].HighIndex      = (UINT32)RShiftU64 (Index, 32);
  RegisterTableEntry[RegisterTable->TableLength].ValidBitStart  = ValidBitStart;
  RegisterTableEntry[RegisterTable->TableLength].ValidBitLength = ValidBitLength;
  RegisterTableEntry[RegisterTable->TableLength].Value          = Value;
  RegisterTableEntry[RegisterTable->TableLength].TestThenWrite  = TestThenWrite;

  RegisterTable->TableLength++;
}

/**
  Adds an entry in specified register table.

  This function adds an entry in specified register table, with given register type,
  register index, bit section and value.

  @param[in]  ProcessorNumber  The index of the CPU to add a register table entry
  @param[in]  RegisterType     Type of the register to program
  @param[in]  Index            Index of the register to program
  @param[in]  ValueMask        Mask of bits in register to write
  @param[in]  Value            Value to write

  @note This service could be called by BSP only.
**/
VOID
EFIAPI
CpuRegisterTableWrite (
  IN UINTN          ProcessorNumber,
  IN REGISTER_TYPE  RegisterType,
  IN UINT64         Index,
  IN UINT64         ValueMask,
  IN UINT64         Value
  )
{
  UINT8  Start;
  UINT8  End;
  UINT8  Length;

  Start  = (UINT8)LowBitSet64 (ValueMask);
  End    = (UINT8)HighBitSet64 (ValueMask);
  Length = End - Start + 1;
  CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE);
}

/**
  Adds an entry in specified register table.

  This function adds an entry in specified register table, with given register type,
  register index, bit section and value.

  @param[in]  ProcessorNumber  The index of the CPU to add a register table entry
  @param[in]  RegisterType     Type of the register to program
  @param[in]  Index            Index of the register to program
  @param[in]  ValueMask        Mask of bits in register to write
  @param[in]  Value            Value to write

  @note This service could be called by BSP only.
**/
VOID
EFIAPI
CpuRegisterTableTestThenWrite (
  IN UINTN          ProcessorNumber,
  IN REGISTER_TYPE  RegisterType,
  IN UINT64         Index,
  IN UINT64         ValueMask,
  IN UINT64         Value
  )
{
  UINT8  Start;
  UINT8  End;
  UINT8  Length;

  Start  = (UINT8)LowBitSet64 (ValueMask);
  End    = (UINT8)HighBitSet64 (ValueMask);
  Length = End - Start + 1;
  CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, TRUE);
}

/**
  Adds an entry in specified Pre-SMM register table.

  This function adds an entry in specified register table, with given register type,
  register index, bit section and value.

  @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
  @param[in]  RegisterType     Type of the register to program
  @param[in]  Index            Index of the register to program
  @param[in]  ValueMask        Mask of bits in register to write
  @param[in]  Value            Value to write

  @note This service could be called by BSP only.
**/
VOID
EFIAPI
PreSmmCpuRegisterTableWrite (
  IN UINTN          ProcessorNumber,
  IN REGISTER_TYPE  RegisterType,
  IN UINT64         Index,
  IN UINT64         ValueMask,
  IN UINT64         Value
  )
{
  UINT8  Start;
  UINT8  End;
  UINT8  Length;

  Start  = (UINT8)LowBitSet64 (ValueMask);
  End    = (UINT8)HighBitSet64 (ValueMask);
  Length = End - Start + 1;
  CpuRegisterTableWriteWorker (TRUE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE);
}

/**
  Worker function to determine if a CPU feature is set in input CPU feature bit mask buffer.

  @param[in]  CpuBitMask      CPU feature bit mask buffer
  @param[in]  CpuBitMaskSize  The size of CPU feature bit mask buffer
  @param[in]  Feature         The bit number of the CPU feature

  @retval  TRUE   The CPU feature is set in CpuBitMask.
  @retval  FALSE  The CPU feature is not set in CpuBitMask.

**/
BOOLEAN
IsCpuFeatureSetInCpuPcd (
  IN UINT8   *CpuBitMask,
  IN UINTN   CpuBitMaskSize,
  IN UINT32  Feature
  )
{
  if ((Feature >> 3) >= CpuBitMaskSize) {
    return FALSE;
  }

  return ((*(CpuBitMask + (Feature >> 3)) & (1 << (Feature & 0x07))) != 0);
}

/**
  Determines if a CPU feature is enabled in PcdCpuFeaturesSupport bit mask.
  If a CPU feature is disabled in PcdCpuFeaturesSupport then all the code/data
  associated with that feature should be optimized away if compiler
  optimizations are enabled.

  @param[in]  Feature  The bit number of the CPU feature to check in the PCD
                       PcdCpuFeaturesSupport

  @retval  TRUE   The CPU feature is set in PcdCpuFeaturesSupport.
  @retval  FALSE  The CPU feature is not set in PcdCpuFeaturesSupport.

  @note This service could be called by BSP only.
**/
BOOLEAN
EFIAPI
IsCpuFeatureSupported (
  IN UINT32  Feature
  )
{
  return IsCpuFeatureSetInCpuPcd (
           (UINT8 *)PcdGetPtr (PcdCpuFeaturesSupport),
           PcdGetSize (PcdCpuFeaturesSupport),
           Feature
           );
}

/**
  Determines if a CPU feature is set in PcdCpuFeaturesSetting bit mask.

  @param[in]  Feature  The bit number of the CPU feature to check in the PCD
                       PcdCpuFeaturesSetting

  @retval  TRUE   The CPU feature is set in PcdCpuFeaturesSetting.
  @retval  FALSE  The CPU feature is not set in PcdCpuFeaturesSetting.

  @note This service could be called by BSP only.
**/
BOOLEAN
EFIAPI
IsCpuFeatureInSetting (
  IN UINT32  Feature
  )
{
  return IsCpuFeatureSetInCpuPcd (
           (UINT8 *)PcdGetPtr (PcdCpuFeaturesSetting),
           PcdGetSize (PcdCpuFeaturesSetting),
           Feature
           );
}

/**
  Switches to assigned BSP after CPU features initialization.

  @param[in]  ProcessorNumber  The index of the CPU executing this function.

  @note This service could be called by BSP only.
**/
VOID
EFIAPI
SwitchBspAfterFeaturesInitialize (
  IN UINTN  ProcessorNumber
  )
{
  CPU_FEATURES_DATA  *CpuFeaturesData;

  CpuFeaturesData            = GetCpuFeaturesData ();
  CpuFeaturesData->BspNumber = ProcessorNumber;
}
