]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c
UefiCpuPkg: Apply uncrustify changes
[mirror_edk2.git] / UefiCpuPkg / Library / RegisterCpuFeaturesLib / RegisterCpuFeaturesLib.c
index b6e108b8ad143ecaaaee3b2d9bd7537b3edb4904..0285aaf5c91a2cd1dbc65bc5dc5860f0c767ee36 100644 (file)
@@ -1,63 +1,34 @@
 /** @file\r
   CPU Register Table Library functions.\r
 \r
-  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "RegisterCpuFeatures.h"\r
 \r
-/**\r
-  Checks if two CPU feature bit masks are equal.\r
-\r
-  @param[in]  FirstFeatureMask  The first input CPU feature bit mask\r
-  @param[in]  SecondFeatureMask The second input CPU feature bit mask\r
-\r
-  @retval TRUE  Two CPU feature bit masks are equal.\r
-  @retval FALSE Two CPU feature bit masks are not equal.\r
-**/\r
-BOOLEAN\r
-IsCpuFeatureMatch (\r
-  IN UINT8               *FirstFeatureMask,\r
-  IN UINT8               *SecondFeatureMask\r
-  )\r
-{\r
-  UINTN                 BitMaskSize;\r
-\r
-  BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
-  if (CompareMem (FirstFeatureMask, SecondFeatureMask, BitMaskSize) == 0) {\r
-    return TRUE;\r
-  } else {\r
-    return FALSE;\r
-  }\r
-}\r
-\r
 /**\r
   Function that uses DEBUG() macros to display the contents of a a CPU feature bit mask.\r
 \r
   @param[in]  FeatureMask  A pointer to the CPU feature bit mask.\r
+  @param[in]  BitMaskSize  CPU feature bits mask buffer size.\r
+\r
 **/\r
 VOID\r
 DumpCpuFeatureMask (\r
-  IN UINT8               *FeatureMask\r
+  IN UINT8   *FeatureMask,\r
+  IN UINT32  BitMaskSize\r
   )\r
 {\r
-  UINTN                  Index;\r
-  UINT8                  *Data8;\r
-  UINTN                  BitMaskSize;\r
+  UINTN  Index;\r
+  UINT8  *Data8;\r
 \r
-  BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
-  Data8       = (UINT8 *) FeatureMask;\r
+  Data8 = (UINT8 *)FeatureMask;\r
   for (Index = 0; Index < BitMaskSize; Index++) {\r
     DEBUG ((DEBUG_INFO, " %02x ", *Data8++));\r
   }\r
+\r
   DEBUG ((DEBUG_INFO, "\n"));\r
 }\r
 \r
@@ -65,18 +36,20 @@ DumpCpuFeatureMask (
   Dump CPU feature name or CPU feature bit mask.\r
 \r
   @param[in]  CpuFeature   Pointer to CPU_FEATURES_ENTRY\r
+  @param[in]  BitMaskSize  CPU feature bits mask buffer size.\r
+\r
 **/\r
 VOID\r
 DumpCpuFeature (\r
-  IN CPU_FEATURES_ENTRY  *CpuFeature\r
+  IN CPU_FEATURES_ENTRY  *CpuFeature,\r
+  IN UINT32              BitMaskSize\r
   )\r
 {\r
-\r
   if (CpuFeature->FeatureName != NULL) {\r
     DEBUG ((DEBUG_INFO, "FeatureName: %a\n", CpuFeature->FeatureName));\r
   } else {\r
     DEBUG ((DEBUG_INFO, "FeatureMask = "));\r
-    DumpCpuFeatureMask (CpuFeature->FeatureMask);\r
+    DumpCpuFeatureMask (CpuFeature->FeatureMask, BitMaskSize);\r
   }\r
 }\r
 \r
@@ -91,66 +64,163 @@ DumpCpuFeature (
 **/\r
 BOOLEAN\r
 IsBitMaskMatchCheck (\r
-  IN UINT8        *FeatureMask,\r
-  IN UINT8        *DependentBitMask\r
+  IN UINT8  *FeatureMask,\r
+  IN UINT8  *DependentBitMask\r
   )\r
 {\r
-  UINTN      Index;\r
-  UINTN      BitMaskSize;\r
-  UINT8      *Data1;\r
-  UINT8      *Data2;\r
+  UINTN              Index;\r
+  UINT8              *Data1;\r
+  UINT8              *Data2;\r
+  CPU_FEATURES_DATA  *CpuFeaturesData;\r
 \r
-  BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
+  CpuFeaturesData = GetCpuFeaturesData ();\r
 \r
   Data1 = FeatureMask;\r
   Data2 = DependentBitMask;\r
-  for (Index = 0; Index < BitMaskSize; Index++) {\r
+  for (Index = 0; Index < CpuFeaturesData->BitMaskSize; Index++) {\r
     if (((*(Data1++)) & (*(Data2++))) != 0) {\r
       return TRUE;\r
     }\r
   }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Try to find the specify cpu featuren in former/after feature list.\r
+\r
+  @param[in]  FeatureList        Pointer to dependent CPU feature list\r
+  @param[in]  CurrentEntry       Pointer to current CPU feature entry.\r
+  @param[in]  SearchFormer       Find in former feature or after features.\r
+  @param[in]  FeatureMask        Pointer to CPU feature bit mask\r
+\r
+  @retval TRUE  The feature bit mask is in dependent CPU feature bit mask buffer.\r
+  @retval FALSE The feature bit mask is not in dependent CPU feature bit mask buffer.\r
+**/\r
+BOOLEAN\r
+FindSpecifyFeature (\r
+  IN LIST_ENTRY  *FeatureList,\r
+  IN LIST_ENTRY  *CurrentEntry,\r
+  IN BOOLEAN     SearchFormer,\r
+  IN UINT8       *FeatureMask\r
+  )\r
+{\r
+  CPU_FEATURES_ENTRY  *CpuFeature;\r
+  LIST_ENTRY          *NextEntry;\r
+\r
+  //\r
+  // Check whether exist the not neighborhood entry first.\r
+  // If not exist, return FALSE means not found status.\r
+  //\r
+  if (SearchFormer) {\r
+    NextEntry = CurrentEntry->BackLink;\r
+    if (IsNull (FeatureList, NextEntry)) {\r
+      return FALSE;\r
+    }\r
+\r
+    NextEntry = NextEntry->BackLink;\r
+    if (IsNull (FeatureList, NextEntry)) {\r
+      return FALSE;\r
+    }\r
+\r
+    NextEntry = CurrentEntry->BackLink->BackLink;\r
+  } else {\r
+    NextEntry = CurrentEntry->ForwardLink;\r
+    if (IsNull (FeatureList, NextEntry)) {\r
+      return FALSE;\r
+    }\r
+\r
+    NextEntry = NextEntry->ForwardLink;\r
+    if (IsNull (FeatureList, NextEntry)) {\r
+      return FALSE;\r
+    }\r
+\r
+    NextEntry = CurrentEntry->ForwardLink->ForwardLink;\r
+  }\r
+\r
+  while (!IsNull (FeatureList, NextEntry)) {\r
+    CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry);\r
+\r
+    if (IsBitMaskMatchCheck (FeatureMask, CpuFeature->FeatureMask)) {\r
+      return TRUE;\r
+    }\r
+\r
+    if (SearchFormer) {\r
+      NextEntry = NextEntry->BackLink;\r
+    } else {\r
+      NextEntry = NextEntry->ForwardLink;\r
+    }\r
+  }\r
+\r
   return FALSE;\r
 }\r
 \r
 /**\r
   Return feature dependence result.\r
 \r
-  @param[in]  CpuFeature        Pointer to CPU feature.\r
-  @param[in]  Before            Check before dependence or after.\r
+  @param[in]  CpuFeature            Pointer to CPU feature.\r
+  @param[in]  Before                Check before dependence or after.\r
+  @param[in]  NextCpuFeatureMask    Pointer to next CPU feature Mask.\r
 \r
   @retval     return the dependence result.\r
 **/\r
 CPU_FEATURE_DEPENDENCE_TYPE\r
 DetectFeatureScope (\r
-  IN CPU_FEATURES_ENTRY         *CpuFeature,\r
-  IN BOOLEAN                    Before\r
+  IN CPU_FEATURES_ENTRY  *CpuFeature,\r
+  IN BOOLEAN             Before,\r
+  IN UINT8               *NextCpuFeatureMask\r
   )\r
 {\r
+  //\r
+  // if need to check before type dependence but the feature after current feature is not\r
+  // exist, means this before type dependence not valid, just return NoneDepType.\r
+  // Just like Feature A has a dependence of feature B, but Feature B not installed, so\r
+  // Feature A maybe insert to the last entry of the list. In this case, for below code,\r
+  // Featrure A has depend of feature B, but it is the last entry of the list, so the\r
+  // NextCpuFeatureMask is NULL, so the dependence for feature A here is useless and code\r
+  // just return NoneDepType.\r
+  //\r
+  if (NextCpuFeatureMask == NULL) {\r
+    return NoneDepType;\r
+  }\r
+\r
   if (Before) {\r
-    if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {\r
+    if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) &&\r
+        IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageBeforeFeatureBitMask))\r
+    {\r
       return PackageDepType;\r
     }\r
 \r
-    if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {\r
+    if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) &&\r
+        IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreBeforeFeatureBitMask))\r
+    {\r
       return CoreDepType;\r
     }\r
 \r
-    if (CpuFeature->BeforeFeatureBitMask != NULL) {\r
+    if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) &&\r
+        IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadBeforeFeatureBitMask))\r
+    {\r
       return ThreadDepType;\r
     }\r
 \r
     return NoneDepType;\r
   }\r
 \r
-  if (CpuFeature->PackageAfterFeatureBitMask != NULL) {\r
+  if ((CpuFeature->PackageAfterFeatureBitMask != NULL) &&\r
+      IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageAfterFeatureBitMask))\r
+  {\r
     return PackageDepType;\r
   }\r
 \r
-  if (CpuFeature->CoreAfterFeatureBitMask != NULL) {\r
+  if ((CpuFeature->CoreAfterFeatureBitMask != NULL) &&\r
+      IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreAfterFeatureBitMask))\r
+  {\r
     return CoreDepType;\r
   }\r
 \r
-  if (CpuFeature->AfterFeatureBitMask != NULL) {\r
+  if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) &&\r
+      IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadAfterFeatureBitMask))\r
+  {\r
     return ThreadDepType;\r
   }\r
 \r
@@ -158,45 +228,62 @@ DetectFeatureScope (
 }\r
 \r
 /**\r
-  Clear dependence for the specified type.\r
+  Return feature dependence result.\r
 \r
-  @param[in]  CpuFeature         Cpu feature need to clear.\r
-  @param[in]  Before             Before or after dependence relationship.\r
+  @param[in]  CpuFeature            Pointer to CPU feature.\r
+  @param[in]  Before                Check before dependence or after.\r
+  @param[in]  FeatureList           Pointer to CPU feature list.\r
 \r
+  @retval     return the dependence result.\r
 **/\r
-VOID\r
-ClearFeatureScope (\r
-  IN CPU_FEATURES_ENTRY           *CpuFeature,\r
-  IN BOOLEAN                      Before\r
+CPU_FEATURE_DEPENDENCE_TYPE\r
+DetectNoneNeighborhoodFeatureScope (\r
+  IN CPU_FEATURES_ENTRY  *CpuFeature,\r
+  IN BOOLEAN             Before,\r
+  IN LIST_ENTRY          *FeatureList\r
   )\r
 {\r
   if (Before) {\r
-    if (CpuFeature->BeforeFeatureBitMask != NULL) {\r
-      FreePool (CpuFeature->BeforeFeatureBitMask);\r
-      CpuFeature->BeforeFeatureBitMask = NULL;\r
-    }\r
-    if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {\r
-      FreePool (CpuFeature->CoreBeforeFeatureBitMask);\r
-      CpuFeature->CoreBeforeFeatureBitMask = NULL;\r
-    }\r
-    if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {\r
-      FreePool (CpuFeature->PackageBeforeFeatureBitMask);\r
-      CpuFeature->PackageBeforeFeatureBitMask = NULL;\r
-    }\r
-  } else {\r
-    if (CpuFeature->PackageAfterFeatureBitMask != NULL) {\r
-      FreePool (CpuFeature->PackageAfterFeatureBitMask);\r
-      CpuFeature->PackageAfterFeatureBitMask = NULL;\r
+    if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) &&\r
+        FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->PackageBeforeFeatureBitMask))\r
+    {\r
+      return PackageDepType;\r
     }\r
-    if (CpuFeature->CoreAfterFeatureBitMask != NULL) {\r
-      FreePool (CpuFeature->CoreAfterFeatureBitMask);\r
-      CpuFeature->CoreAfterFeatureBitMask = NULL;\r
+\r
+    if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) &&\r
+        FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->CoreBeforeFeatureBitMask))\r
+    {\r
+      return CoreDepType;\r
     }\r
-    if (CpuFeature->AfterFeatureBitMask != NULL) {\r
-      FreePool (CpuFeature->AfterFeatureBitMask);\r
-      CpuFeature->AfterFeatureBitMask = NULL;\r
+\r
+    if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) &&\r
+        FindSpecifyFeature (FeatureList, &CpuFeature->Link, FALSE, CpuFeature->ThreadBeforeFeatureBitMask))\r
+    {\r
+      return ThreadDepType;\r
     }\r
+\r
+    return NoneDepType;\r
   }\r
+\r
+  if ((CpuFeature->PackageAfterFeatureBitMask != NULL) &&\r
+      FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->PackageAfterFeatureBitMask))\r
+  {\r
+    return PackageDepType;\r
+  }\r
+\r
+  if ((CpuFeature->CoreAfterFeatureBitMask != NULL) &&\r
+      FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->CoreAfterFeatureBitMask))\r
+  {\r
+    return CoreDepType;\r
+  }\r
+\r
+  if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) &&\r
+      FindSpecifyFeature (FeatureList, &CpuFeature->Link, TRUE, CpuFeature->ThreadAfterFeatureBitMask))\r
+  {\r
+    return ThreadDepType;\r
+  }\r
+\r
+  return NoneDepType;\r
 }\r
 \r
 /**\r
@@ -209,6 +296,7 @@ ClearFeatureScope (
 \r
   @param[in, out]  PreviousFeature    CPU feature current before the find one.\r
   @param[in, out]  CurrentFeature     Cpu feature need to adjust.\r
+  @param[in]       FindFeature        Cpu feature which current feature depends.\r
   @param[in]       Before             Before or after dependence relationship.\r
 \r
   @retval   TRUE   means the current feature dependence has been adjusted.\r
@@ -219,16 +307,17 @@ ClearFeatureScope (
 **/\r
 BOOLEAN\r
 AdjustFeaturesDependence (\r
-  IN OUT CPU_FEATURES_ENTRY         *PreviousFeature,\r
-  IN OUT CPU_FEATURES_ENTRY         *CurrentFeature,\r
-  IN     BOOLEAN                    Before\r
+  IN OUT CPU_FEATURES_ENTRY  *PreviousFeature,\r
+  IN OUT CPU_FEATURES_ENTRY  *CurrentFeature,\r
+  IN     CPU_FEATURES_ENTRY  *FindFeature,\r
+  IN     BOOLEAN             Before\r
   )\r
 {\r
-  CPU_FEATURE_DEPENDENCE_TYPE            PreDependType;\r
-  CPU_FEATURE_DEPENDENCE_TYPE            CurrentDependType;\r
+  CPU_FEATURE_DEPENDENCE_TYPE  PreDependType;\r
+  CPU_FEATURE_DEPENDENCE_TYPE  CurrentDependType;\r
 \r
-  PreDependType     = DetectFeatureScope(PreviousFeature, Before);\r
-  CurrentDependType = DetectFeatureScope(CurrentFeature, Before);\r
+  PreDependType     = DetectFeatureScope (PreviousFeature, Before, FindFeature->FeatureMask);\r
+  CurrentDependType = DetectFeatureScope (CurrentFeature, Before, FindFeature->FeatureMask);\r
 \r
   //\r
   // If previous feature has no dependence with the find featue.\r
@@ -243,10 +332,8 @@ AdjustFeaturesDependence (
   // processors and clear the dependence for the other one.\r
   //\r
   if (PreDependType >= CurrentDependType) {\r
-    ClearFeatureScope (CurrentFeature, Before);\r
     return TRUE;\r
   } else {\r
-    ClearFeatureScope (PreviousFeature, Before);\r
     return FALSE;\r
   }\r
 }\r
@@ -262,15 +349,16 @@ AdjustFeaturesDependence (
 **/\r
 VOID\r
 AdjustEntry (\r
-  IN      LIST_ENTRY                *FeatureList,\r
-  IN OUT  LIST_ENTRY                *FindEntry,\r
-  IN OUT  LIST_ENTRY                *CurrentEntry,\r
-  IN      BOOLEAN                   Before\r
+  IN      LIST_ENTRY  *FeatureList,\r
+  IN OUT  LIST_ENTRY  *FindEntry,\r
+  IN OUT  LIST_ENTRY  *CurrentEntry,\r
+  IN      BOOLEAN     Before\r
   )\r
 {\r
-  LIST_ENTRY                *PreviousEntry;\r
-  CPU_FEATURES_ENTRY        *PreviousFeature;\r
-  CPU_FEATURES_ENTRY        *CurrentFeature;\r
+  LIST_ENTRY          *PreviousEntry;\r
+  CPU_FEATURES_ENTRY  *PreviousFeature;\r
+  CPU_FEATURES_ENTRY  *CurrentFeature;\r
+  CPU_FEATURES_ENTRY  *FindFeature;\r
 \r
   //\r
   // For CPU feature which has core or package type dependence, later code need to insert\r
@@ -287,11 +375,11 @@ AdjustEntry (
   //\r
   if (Before) {\r
     PreviousEntry = GetPreviousNode (FeatureList, FindEntry);\r
-  } else {\r\r
+  } else {\r
     PreviousEntry = GetNextNode (FeatureList, FindEntry);\r
   }\r
 \r
-  CurrentFeature  = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);\r
+  CurrentFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);\r
   RemoveEntryList (CurrentEntry);\r
 \r
   if (IsNull (FeatureList, PreviousEntry)) {\r
@@ -308,8 +396,9 @@ AdjustEntry (
     // If exist the previous or next entry, need to check it before insert curent entry.\r
     //\r
     PreviousFeature = CPU_FEATURE_ENTRY_FROM_LINK (PreviousEntry);\r
+    FindFeature     = CPU_FEATURE_ENTRY_FROM_LINK (FindEntry);\r
 \r
-    if (AdjustFeaturesDependence (PreviousFeature, CurrentFeature, Before)) {\r
+    if (AdjustFeaturesDependence (PreviousFeature, CurrentFeature, FindFeature, Before)) {\r
       //\r
       // Return TRUE means current feature dependence has been cleared and the previous\r
       // feature dependence has been kept and used. So insert current feature before (or after)\r
@@ -328,7 +417,7 @@ AdjustEntry (
       }\r
     }\r
   }\r
-}\r\r
+}\r
 \r
 /**\r
   Checks and adjusts current CPU features per dependency relationship.\r
@@ -341,14 +430,14 @@ AdjustEntry (
 **/\r
 BOOLEAN\r
 InsertToBeforeEntry (\r
-  IN LIST_ENTRY              *FeatureList,\r
-  IN LIST_ENTRY              *CurrentEntry,\r
-  IN UINT8                   *FeatureMask\r
+  IN LIST_ENTRY  *FeatureList,\r
+  IN LIST_ENTRY  *CurrentEntry,\r
+  IN UINT8       *FeatureMask\r
   )\r
 {\r
-  LIST_ENTRY                 *CheckEntry;\r
-  CPU_FEATURES_ENTRY         *CheckFeature;\r
-  BOOLEAN                    Swapped;\r
+  LIST_ENTRY          *CheckEntry;\r
+  CPU_FEATURES_ENTRY  *CheckFeature;\r
+  BOOLEAN             Swapped;\r
 \r
   Swapped = FALSE;\r
 \r
@@ -363,6 +452,7 @@ InsertToBeforeEntry (
       Swapped = TRUE;\r
       break;\r
     }\r
+\r
     CheckEntry = CheckEntry->ForwardLink;\r
   }\r
 \r
@@ -380,14 +470,14 @@ InsertToBeforeEntry (
 **/\r
 BOOLEAN\r
 InsertToAfterEntry (\r
-  IN LIST_ENTRY              *FeatureList,\r
-  IN LIST_ENTRY              *CurrentEntry,\r
-  IN UINT8                   *FeatureMask\r
+  IN LIST_ENTRY  *FeatureList,\r
+  IN LIST_ENTRY  *CurrentEntry,\r
+  IN UINT8       *FeatureMask\r
   )\r
 {\r
-  LIST_ENTRY                 *CheckEntry;\r
-  CPU_FEATURES_ENTRY         *CheckFeature;\r
-  BOOLEAN                    Swapped;\r
+  LIST_ENTRY          *CheckEntry;\r
+  CPU_FEATURES_ENTRY  *CheckFeature;\r
+  BOOLEAN             Swapped;\r
 \r
   Swapped = FALSE;\r
 \r
@@ -402,6 +492,7 @@ InsertToAfterEntry (
       Swapped = TRUE;\r
       break;\r
     }\r
+\r
     CheckEntry = CheckEntry->ForwardLink;\r
   }\r
 \r
@@ -415,22 +506,22 @@ InsertToAfterEntry (
 **/\r
 VOID\r
 CheckCpuFeaturesDependency (\r
-  IN LIST_ENTRY              *FeatureList\r
+  IN LIST_ENTRY  *FeatureList\r
   )\r
 {\r
-  LIST_ENTRY                 *CurrentEntry;\r
-  CPU_FEATURES_ENTRY         *CpuFeature;\r
-  LIST_ENTRY                 *CheckEntry;\r
-  CPU_FEATURES_ENTRY         *CheckFeature;\r
-  BOOLEAN                    Swapped;\r
-  LIST_ENTRY                 *TempEntry;\r
-  LIST_ENTRY                 *NextEntry;\r
+  LIST_ENTRY          *CurrentEntry;\r
+  CPU_FEATURES_ENTRY  *CpuFeature;\r
+  LIST_ENTRY          *CheckEntry;\r
+  CPU_FEATURES_ENTRY  *CheckFeature;\r
+  BOOLEAN             Swapped;\r
+  LIST_ENTRY          *TempEntry;\r
+  LIST_ENTRY          *NextEntry;\r
 \r
   CurrentEntry = GetFirstNode (FeatureList);\r
   while (!IsNull (FeatureList, CurrentEntry)) {\r
-    Swapped = FALSE;\r
+    Swapped    = FALSE;\r
     CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);\r
-    NextEntry = CurrentEntry->ForwardLink;\r
+    NextEntry  = CurrentEntry->ForwardLink;\r
     if (CpuFeature->BeforeAll) {\r
       //\r
       // Check all features dispatched before this entry\r
@@ -448,8 +539,10 @@ CheckCpuFeaturesDependency (
           Swapped = TRUE;\r
           break;\r
         }\r
+\r
         CheckEntry = CheckEntry->ForwardLink;\r
       }\r
+\r
       if (Swapped) {\r
         CurrentEntry = NextEntry;\r
         continue;\r
@@ -472,29 +565,29 @@ CheckCpuFeaturesDependency (
           RemoveEntryList (CurrentEntry);\r
           InsertHeadList (CheckEntry, CurrentEntry);\r
           CurrentEntry = TempEntry;\r
-          Swapped = TRUE;\r
+          Swapped      = TRUE;\r
           break;\r
         }\r
+\r
         CheckEntry = CheckEntry->ForwardLink;\r
       }\r
+\r
       if (Swapped) {\r
         CurrentEntry = NextEntry;\r
         continue;\r
       }\r
     }\r
 \r
-    if (CpuFeature->BeforeFeatureBitMask != NULL) {\r
-      Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->BeforeFeatureBitMask);\r
+    if (CpuFeature->ThreadBeforeFeatureBitMask != NULL) {\r
+      Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->ThreadBeforeFeatureBitMask);\r
       if (Swapped) {\r
-        CurrentEntry = NextEntry;\r
         continue;\r
       }\r
     }\r
 \r
-    if (CpuFeature->AfterFeatureBitMask != NULL) {\r
-      Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->AfterFeatureBitMask);\r
+    if (CpuFeature->ThreadAfterFeatureBitMask != NULL) {\r
+      Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->ThreadAfterFeatureBitMask);\r
       if (Swapped) {\r
-        CurrentEntry = NextEntry;\r
         continue;\r
       }\r
     }\r
@@ -502,7 +595,6 @@ CheckCpuFeaturesDependency (
     if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {\r
       Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->CoreBeforeFeatureBitMask);\r
       if (Swapped) {\r
-        CurrentEntry = NextEntry;\r
         continue;\r
       }\r
     }\r
@@ -510,7 +602,6 @@ CheckCpuFeaturesDependency (
     if (CpuFeature->CoreAfterFeatureBitMask != NULL) {\r
       Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->CoreAfterFeatureBitMask);\r
       if (Swapped) {\r
-        CurrentEntry = NextEntry;\r
         continue;\r
       }\r
     }\r
@@ -518,7 +609,6 @@ CheckCpuFeaturesDependency (
     if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {\r
       Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->PackageBeforeFeatureBitMask);\r
       if (Swapped) {\r
-        CurrentEntry = NextEntry;\r
         continue;\r
       }\r
     }\r
@@ -526,7 +616,6 @@ CheckCpuFeaturesDependency (
     if (CpuFeature->PackageAfterFeatureBitMask != NULL) {\r
       Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->PackageAfterFeatureBitMask);\r
       if (Swapped) {\r
-        CurrentEntry = NextEntry;\r
         continue;\r
       }\r
     }\r
@@ -538,6 +627,7 @@ CheckCpuFeaturesDependency (
 /**\r
   Worker function to register CPU Feature.\r
 \r
+  @param[in]  CpuFeaturesData       Pointer to CPU feature data structure.\r
   @param[in]  CpuFeature            Pointer to CPU feature entry\r
 \r
   @retval  RETURN_SUCCESS           The CPU feature was successfully registered.\r
@@ -549,49 +639,39 @@ CheckCpuFeaturesDependency (
 **/\r
 RETURN_STATUS\r
 RegisterCpuFeatureWorker (\r
-  IN CPU_FEATURES_ENTRY      *CpuFeature\r
+  IN CPU_FEATURES_DATA   *CpuFeaturesData,\r
+  IN CPU_FEATURES_ENTRY  *CpuFeature\r
   )\r
 {\r
-  EFI_STATUS                 Status;\r
-  CPU_FEATURES_DATA          *CpuFeaturesData;\r
-  CPU_FEATURES_ENTRY         *CpuFeatureEntry;\r
-  LIST_ENTRY                 *Entry;\r
-  UINTN                      BitMaskSize;\r
-  BOOLEAN                    FeatureExist;\r
+  EFI_STATUS          Status;\r
+  CPU_FEATURES_ENTRY  *CpuFeatureEntry;\r
+  LIST_ENTRY          *Entry;\r
+  BOOLEAN             FeatureExist;\r
 \r
-  BitMaskSize     = PcdGetSize (PcdCpuFeaturesSupport);\r
-  CpuFeaturesData = GetCpuFeaturesData ();\r
-  if (CpuFeaturesData->FeaturesCount == 0) {\r
-    InitializeListHead (&CpuFeaturesData->FeatureList);\r
-    InitializeSpinLock (&CpuFeaturesData->CpuFlags.MemoryMappedLock);\r
-    InitializeSpinLock (&CpuFeaturesData->CpuFlags.ConsoleLogLock);\r
-    CpuFeaturesData->BitMaskSize = (UINT32) BitMaskSize;\r
-  }\r
-  ASSERT (CpuFeaturesData->BitMaskSize == BitMaskSize);\r
-\r
-  FeatureExist = FALSE;\r
+  FeatureExist    = FALSE;\r
   CpuFeatureEntry = NULL;\r
-  Entry = GetFirstNode (&CpuFeaturesData->FeatureList);\r
+  Entry           = GetFirstNode (&CpuFeaturesData->FeatureList);\r
   while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {\r
     CpuFeatureEntry = CPU_FEATURE_ENTRY_FROM_LINK (Entry);\r
-    if (IsCpuFeatureMatch (CpuFeature->FeatureMask, CpuFeatureEntry->FeatureMask)) {\r
+    if (CompareMem (CpuFeature->FeatureMask, CpuFeatureEntry->FeatureMask, CpuFeaturesData->BitMaskSize) == 0) {\r
       //\r
       // If this feature already registered\r
       //\r
       FeatureExist = TRUE;\r
       break;\r
     }\r
+\r
     Entry = Entry->ForwardLink;\r
   }\r
 \r
   if (!FeatureExist) {\r
     DEBUG ((DEBUG_INFO, "[NEW] "));\r
-    DumpCpuFeature (CpuFeature);\r
+    DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize);\r
     InsertTailList (&CpuFeaturesData->FeatureList, &CpuFeature->Link);\r
     CpuFeaturesData->FeaturesCount++;\r
   } else {\r
     DEBUG ((DEBUG_INFO, "[OVERRIDE] "));\r
-    DumpCpuFeature (CpuFeature);\r
+    DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize);\r
     ASSERT (CpuFeatureEntry != NULL);\r
     //\r
     // Overwrite original parameters of CPU feature\r
@@ -599,55 +679,71 @@ RegisterCpuFeatureWorker (
     if (CpuFeature->GetConfigDataFunc != NULL) {\r
       CpuFeatureEntry->GetConfigDataFunc = CpuFeature->GetConfigDataFunc;\r
     }\r
+\r
     if (CpuFeature->SupportFunc != NULL) {\r
       CpuFeatureEntry->SupportFunc = CpuFeature->SupportFunc;\r
     }\r
+\r
     if (CpuFeature->InitializeFunc != NULL) {\r
       CpuFeatureEntry->InitializeFunc = CpuFeature->InitializeFunc;\r
     }\r
+\r
     if (CpuFeature->FeatureName != NULL) {\r
       if (CpuFeatureEntry->FeatureName == NULL) {\r
         CpuFeatureEntry->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE);\r
         ASSERT (CpuFeatureEntry->FeatureName != NULL);\r
       }\r
+\r
       Status = AsciiStrCpyS (CpuFeatureEntry->FeatureName, CPU_FEATURE_NAME_SIZE, CpuFeature->FeatureName);\r
       ASSERT_EFI_ERROR (Status);\r
       FreePool (CpuFeature->FeatureName);\r
     }\r
-    if (CpuFeature->BeforeFeatureBitMask != NULL) {\r
-      if (CpuFeatureEntry->BeforeFeatureBitMask != NULL) {\r
-        FreePool (CpuFeatureEntry->BeforeFeatureBitMask);\r
+\r
+    if (CpuFeature->ThreadBeforeFeatureBitMask != NULL) {\r
+      if (CpuFeatureEntry->ThreadBeforeFeatureBitMask != NULL) {\r
+        FreePool (CpuFeatureEntry->ThreadBeforeFeatureBitMask);\r
       }\r
-      CpuFeatureEntry->BeforeFeatureBitMask = CpuFeature->BeforeFeatureBitMask;\r
+\r
+      CpuFeatureEntry->ThreadBeforeFeatureBitMask = CpuFeature->ThreadBeforeFeatureBitMask;\r
     }\r
-    if (CpuFeature->AfterFeatureBitMask != NULL) {\r
-      if (CpuFeatureEntry->AfterFeatureBitMask != NULL) {\r
-        FreePool (CpuFeatureEntry->AfterFeatureBitMask);\r
+\r
+    if (CpuFeature->ThreadAfterFeatureBitMask != NULL) {\r
+      if (CpuFeatureEntry->ThreadAfterFeatureBitMask != NULL) {\r
+        FreePool (CpuFeatureEntry->ThreadAfterFeatureBitMask);\r
       }\r
-      CpuFeatureEntry->AfterFeatureBitMask = CpuFeature->AfterFeatureBitMask;\r
+\r
+      CpuFeatureEntry->ThreadAfterFeatureBitMask = CpuFeature->ThreadAfterFeatureBitMask;\r
     }\r
+\r
     if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {\r
       if (CpuFeatureEntry->CoreBeforeFeatureBitMask != NULL) {\r
         FreePool (CpuFeatureEntry->CoreBeforeFeatureBitMask);\r
       }\r
+\r
       CpuFeatureEntry->CoreBeforeFeatureBitMask = CpuFeature->CoreBeforeFeatureBitMask;\r
     }\r
+\r
     if (CpuFeature->CoreAfterFeatureBitMask != NULL) {\r
       if (CpuFeatureEntry->CoreAfterFeatureBitMask != NULL) {\r
         FreePool (CpuFeatureEntry->CoreAfterFeatureBitMask);\r
       }\r
+\r
       CpuFeatureEntry->CoreAfterFeatureBitMask = CpuFeature->CoreAfterFeatureBitMask;\r
     }\r
+\r
     if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {\r
       if (CpuFeatureEntry->PackageBeforeFeatureBitMask != NULL) {\r
         FreePool (CpuFeatureEntry->PackageBeforeFeatureBitMask);\r
       }\r
+\r
       CpuFeatureEntry->PackageBeforeFeatureBitMask = CpuFeature->PackageBeforeFeatureBitMask;\r
     }\r
+\r
     if (CpuFeature->PackageAfterFeatureBitMask != NULL) {\r
       if (CpuFeatureEntry->PackageAfterFeatureBitMask != NULL) {\r
         FreePool (CpuFeatureEntry->PackageAfterFeatureBitMask);\r
       }\r
+\r
       CpuFeatureEntry->PackageAfterFeatureBitMask = CpuFeature->PackageAfterFeatureBitMask;\r
     }\r
 \r
@@ -657,6 +753,7 @@ RegisterCpuFeatureWorker (
     FreePool (CpuFeature->FeatureMask);\r
     FreePool (CpuFeature);\r
   }\r
+\r
   //\r
   // Verify CPU features dependency can change CPU feature order\r
   //\r
@@ -673,12 +770,12 @@ RegisterCpuFeatureWorker (
 **/\r
 VOID\r
 SetCpuFeaturesBitMask (\r
-  IN UINT8               **FeaturesBitMask,\r
-  IN UINT32              Feature,\r
-  IN UINTN               BitMaskSize\r
+  IN UINT8   **FeaturesBitMask,\r
+  IN UINT32  Feature,\r
+  IN UINTN   BitMaskSize\r
   )\r
 {\r
-  UINT8                  *CpuFeaturesBitMask;\r
+  UINT8  *CpuFeaturesBitMask;\r
 \r
   ASSERT (FeaturesBitMask != NULL);\r
   CpuFeaturesBitMask = *FeaturesBitMask;\r
@@ -689,7 +786,7 @@ SetCpuFeaturesBitMask (
   }\r
 \r
   CpuFeaturesBitMask  += (Feature / 8);\r
-  *CpuFeaturesBitMask |= (UINT8) (1 << (Feature % 8));\r
+  *CpuFeaturesBitMask |= (UINT8)(1 << (Feature % 8));\r
 }\r
 \r
 /**\r
@@ -741,80 +838,108 @@ SetCpuFeaturesBitMask (
 RETURN_STATUS\r
 EFIAPI\r
 RegisterCpuFeature (\r
-  IN CHAR8                             *FeatureName,       OPTIONAL\r
-  IN CPU_FEATURE_GET_CONFIG_DATA       GetConfigDataFunc,  OPTIONAL\r
-  IN CPU_FEATURE_SUPPORT               SupportFunc,        OPTIONAL\r
-  IN CPU_FEATURE_INITIALIZE            InitializeFunc,     OPTIONAL\r
+  IN CHAR8                        *FeatureName        OPTIONAL,\r
+  IN CPU_FEATURE_GET_CONFIG_DATA  GetConfigDataFunc   OPTIONAL,\r
+  IN CPU_FEATURE_SUPPORT          SupportFunc         OPTIONAL,\r
+  IN CPU_FEATURE_INITIALIZE       InitializeFunc      OPTIONAL,\r
   ...\r
   )\r
 {\r
-  EFI_STATUS                 Status;\r
-  VA_LIST                    Marker;\r
-  UINT32                     Feature;\r
-  UINTN                      BitMaskSize;\r
-  CPU_FEATURES_ENTRY         *CpuFeature;\r
-  UINT8                      *FeatureMask;\r
-  UINT8                      *BeforeFeatureBitMask;\r
-  UINT8                      *AfterFeatureBitMask;\r
-  UINT8                      *CoreBeforeFeatureBitMask;\r
-  UINT8                      *CoreAfterFeatureBitMask;\r
-  UINT8                      *PackageBeforeFeatureBitMask;\r
-  UINT8                      *PackageAfterFeatureBitMask;\r
-  BOOLEAN                    BeforeAll;\r
-  BOOLEAN                    AfterAll;\r
+  EFI_STATUS          Status;\r
+  VA_LIST             Marker;\r
+  UINT32              Feature;\r
+  CPU_FEATURES_ENTRY  *CpuFeature;\r
+  UINT8               *FeatureMask;\r
+  UINT8               *ThreadBeforeFeatureBitMask;\r
+  UINT8               *ThreadAfterFeatureBitMask;\r
+  UINT8               *CoreBeforeFeatureBitMask;\r
+  UINT8               *CoreAfterFeatureBitMask;\r
+  UINT8               *PackageBeforeFeatureBitMask;\r
+  UINT8               *PackageAfterFeatureBitMask;\r
+  BOOLEAN             BeforeAll;\r
+  BOOLEAN             AfterAll;\r
+  CPU_FEATURES_DATA   *CpuFeaturesData;\r
 \r
   FeatureMask                 = NULL;\r
-  BeforeFeatureBitMask        = NULL;\r
-  AfterFeatureBitMask         = NULL;\r
+  ThreadBeforeFeatureBitMask  = NULL;\r
+  ThreadAfterFeatureBitMask   = NULL;\r
   CoreBeforeFeatureBitMask    = NULL;\r
   CoreAfterFeatureBitMask     = NULL;\r
   PackageBeforeFeatureBitMask = NULL;\r
   PackageAfterFeatureBitMask  = NULL;\r
-  BeforeAll            = FALSE;\r
-  AfterAll             = FALSE;\r
+  BeforeAll                   = FALSE;\r
+  AfterAll                    = FALSE;\r
 \r
-  BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
+  CpuFeaturesData = GetCpuFeaturesData ();\r
+  if (CpuFeaturesData->FeaturesCount == 0) {\r
+    InitializeListHead (&CpuFeaturesData->FeatureList);\r
+    InitializeSpinLock (&CpuFeaturesData->CpuFlags.MemoryMappedLock);\r
+    //\r
+    // Code assumes below three PCDs have PCD same buffer size.\r
+    //\r
+    ASSERT (PcdGetSize (PcdCpuFeaturesSetting) == PcdGetSize (PcdCpuFeaturesCapability));\r
+    ASSERT (PcdGetSize (PcdCpuFeaturesSetting) == PcdGetSize (PcdCpuFeaturesSupport));\r
+    CpuFeaturesData->BitMaskSize = (UINT32)PcdGetSize (PcdCpuFeaturesSetting);\r
+  }\r
 \r
   VA_START (Marker, InitializeFunc);\r
   Feature = VA_ARG (Marker, UINT32);\r
   while (Feature != CPU_FEATURE_END) {\r
-    ASSERT ((Feature & (CPU_FEATURE_BEFORE | CPU_FEATURE_AFTER))\r
-                    != (CPU_FEATURE_BEFORE | CPU_FEATURE_AFTER));\r
-    ASSERT ((Feature & (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL))\r
-                    != (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL));\r
-    ASSERT ((Feature & (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER))\r
-                    != (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER));\r
-    ASSERT ((Feature & (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER))\r
-                    != (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER));\r
-    if (Feature < CPU_FEATURE_BEFORE) {\r
+    //\r
+    // It's invalid to require a feature is before AND after all other features.\r
+    //\r
+    ASSERT (\r
+      (Feature & (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL))\r
+      != (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL)\r
+      );\r
+\r
+    //\r
+    // It's invalid to require feature A is before AND after before feature B,\r
+    // either in thread level, core level or package level.\r
+    //\r
+    ASSERT (\r
+      (Feature & (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER))\r
+      != (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER)\r
+      );\r
+    ASSERT (\r
+      (Feature & (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER))\r
+      != (CPU_FEATURE_CORE_BEFORE | CPU_FEATURE_CORE_AFTER)\r
+      );\r
+    ASSERT (\r
+      (Feature & (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER))\r
+      != (CPU_FEATURE_PACKAGE_BEFORE | CPU_FEATURE_PACKAGE_AFTER)\r
+      );\r
+    if (Feature < CPU_FEATURE_THREAD_BEFORE) {\r
       BeforeAll = ((Feature & CPU_FEATURE_BEFORE_ALL) != 0) ? TRUE : FALSE;\r
       AfterAll  = ((Feature & CPU_FEATURE_AFTER_ALL) != 0) ? TRUE : FALSE;\r
       Feature  &= ~(CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL);\r
       ASSERT (FeatureMask == NULL);\r
-      SetCpuFeaturesBitMask (&FeatureMask, Feature, BitMaskSize);\r
-    } else if ((Feature & CPU_FEATURE_BEFORE) != 0) {\r
-      SetCpuFeaturesBitMask (&BeforeFeatureBitMask, Feature & ~CPU_FEATURE_BEFORE, BitMaskSize);\r
-    } else if ((Feature & CPU_FEATURE_AFTER) != 0) {\r
-      SetCpuFeaturesBitMask (&AfterFeatureBitMask, Feature & ~CPU_FEATURE_AFTER, BitMaskSize);\r
+      SetCpuFeaturesBitMask (&FeatureMask, Feature, CpuFeaturesData->BitMaskSize);\r
+    } else if ((Feature & CPU_FEATURE_THREAD_BEFORE) != 0) {\r
+      SetCpuFeaturesBitMask (&ThreadBeforeFeatureBitMask, Feature & ~CPU_FEATURE_THREAD_BEFORE, CpuFeaturesData->BitMaskSize);\r
+    } else if ((Feature & CPU_FEATURE_THREAD_AFTER) != 0) {\r
+      SetCpuFeaturesBitMask (&ThreadAfterFeatureBitMask, Feature & ~CPU_FEATURE_THREAD_AFTER, CpuFeaturesData->BitMaskSize);\r
     } else if ((Feature & CPU_FEATURE_CORE_BEFORE) != 0) {\r
-      SetCpuFeaturesBitMask (&CoreBeforeFeatureBitMask, Feature & ~CPU_FEATURE_CORE_BEFORE, BitMaskSize);\r
+      SetCpuFeaturesBitMask (&CoreBeforeFeatureBitMask, Feature & ~CPU_FEATURE_CORE_BEFORE, CpuFeaturesData->BitMaskSize);\r
     } else if ((Feature & CPU_FEATURE_CORE_AFTER) != 0) {\r
-      SetCpuFeaturesBitMask (&CoreAfterFeatureBitMask, Feature & ~CPU_FEATURE_CORE_AFTER, BitMaskSize);\r
+      SetCpuFeaturesBitMask (&CoreAfterFeatureBitMask, Feature & ~CPU_FEATURE_CORE_AFTER, CpuFeaturesData->BitMaskSize);\r
     } else if ((Feature & CPU_FEATURE_PACKAGE_BEFORE) != 0) {\r
-      SetCpuFeaturesBitMask (&PackageBeforeFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_BEFORE, BitMaskSize);\r
+      SetCpuFeaturesBitMask (&PackageBeforeFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_BEFORE, CpuFeaturesData->BitMaskSize);\r
     } else if ((Feature & CPU_FEATURE_PACKAGE_AFTER) != 0) {\r
-      SetCpuFeaturesBitMask (&PackageAfterFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_AFTER, BitMaskSize);\r
+      SetCpuFeaturesBitMask (&PackageAfterFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_AFTER, CpuFeaturesData->BitMaskSize);\r
     }\r
+\r
     Feature = VA_ARG (Marker, UINT32);\r
   }\r
+\r
   VA_END (Marker);\r
 \r
   CpuFeature = AllocateZeroPool (sizeof (CPU_FEATURES_ENTRY));\r
   ASSERT (CpuFeature != NULL);\r
   CpuFeature->Signature                   = CPU_FEATURE_ENTRY_SIGNATURE;\r
   CpuFeature->FeatureMask                 = FeatureMask;\r
-  CpuFeature->BeforeFeatureBitMask        = BeforeFeatureBitMask;\r
-  CpuFeature->AfterFeatureBitMask         = AfterFeatureBitMask;\r
+  CpuFeature->ThreadBeforeFeatureBitMask  = ThreadBeforeFeatureBitMask;\r
+  CpuFeature->ThreadAfterFeatureBitMask   = ThreadAfterFeatureBitMask;\r
   CpuFeature->CoreBeforeFeatureBitMask    = CoreBeforeFeatureBitMask;\r
   CpuFeature->CoreAfterFeatureBitMask     = CoreAfterFeatureBitMask;\r
   CpuFeature->PackageBeforeFeatureBitMask = PackageBeforeFeatureBitMask;\r
@@ -825,13 +950,13 @@ RegisterCpuFeature (
   CpuFeature->SupportFunc                 = SupportFunc;\r
   CpuFeature->InitializeFunc              = InitializeFunc;\r
   if (FeatureName != NULL) {\r
-    CpuFeature->FeatureName          = AllocatePool (CPU_FEATURE_NAME_SIZE);\r
+    CpuFeature->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE);\r
     ASSERT (CpuFeature->FeatureName != NULL);\r
     Status = AsciiStrCpyS (CpuFeature->FeatureName, CPU_FEATURE_NAME_SIZE, FeatureName);\r
     ASSERT_EFI_ERROR (Status);\r
   }\r
 \r
-  Status = RegisterCpuFeatureWorker (CpuFeature);\r
+  Status = RegisterCpuFeatureWorker (CpuFeaturesData, CpuFeature);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   return RETURN_SUCCESS;\r
@@ -847,55 +972,65 @@ GetAcpiCpuData (
   VOID\r
   )\r
 {\r
-  EFI_STATUS                           Status;\r
-  UINTN                                NumberOfCpus;\r
-  UINTN                                NumberOfEnabledProcessors;\r
-  ACPI_CPU_DATA                        *AcpiCpuData;\r
-  UINTN                                TableSize;\r
-  CPU_REGISTER_TABLE                   *RegisterTable;\r
-  UINTN                                Index;\r
-  EFI_PROCESSOR_INFORMATION            ProcessorInfoBuffer;\r
-\r
-  AcpiCpuData = (ACPI_CPU_DATA *) (UINTN) PcdGet64 (PcdCpuS3DataAddress);\r
-  if (AcpiCpuData != NULL) {\r
-    return AcpiCpuData;\r
-  }\r
+  EFI_STATUS                 Status;\r
+  UINTN                      NumberOfCpus;\r
+  UINTN                      NumberOfEnabledProcessors;\r
+  ACPI_CPU_DATA              *AcpiCpuData;\r
+  UINTN                      TableSize;\r
+  CPU_REGISTER_TABLE         *RegisterTable;\r
+  UINTN                      Index;\r
+  EFI_PROCESSOR_INFORMATION  ProcessorInfoBuffer;\r
+\r
+  AcpiCpuData = (ACPI_CPU_DATA *)(UINTN)PcdGet64 (PcdCpuS3DataAddress);\r
+  if (AcpiCpuData == NULL) {\r
+    AcpiCpuData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)));\r
+    ASSERT (AcpiCpuData != NULL);\r
+    ZeroMem (AcpiCpuData, sizeof (ACPI_CPU_DATA));\r
 \r
-  AcpiCpuData  = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)));\r
-  ASSERT (AcpiCpuData != NULL);\r
+    //\r
+    // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure\r
+    //\r
+    Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData);\r
+    ASSERT_EFI_ERROR (Status);\r
 \r
-  //\r
-  // Set PcdCpuS3DataAddress to the base address of the ACPI_CPU_DATA structure\r
-  //\r
-  Status = PcdSet64S (PcdCpuS3DataAddress, (UINT64)(UINTN)AcpiCpuData);\r
-  ASSERT_EFI_ERROR (Status);\r
+    GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors);\r
+    AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;\r
+  }\r
 \r
-  GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors);\r
-  AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;\r
+  if ((AcpiCpuData->CpuFeatureInitData.RegisterTable == 0) ||\r
+      (AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable == 0))\r
+  {\r
+    //\r
+    // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs\r
+    //\r
+    NumberOfCpus  = AcpiCpuData->NumberOfCpus;\r
+    TableSize     = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);\r
+    RegisterTable = AllocatePages (EFI_SIZE_TO_PAGES (TableSize));\r
+    ASSERT (RegisterTable != NULL);\r
 \r
-  //\r
-  // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs\r
-  //\r
-  TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);\r
-  RegisterTable  = AllocatePages (EFI_SIZE_TO_PAGES (TableSize));\r
-  ASSERT (RegisterTable != NULL);\r
+    for (Index = 0; Index < NumberOfCpus; Index++) {\r
+      Status = GetProcessorInformation (Index, &ProcessorInfoBuffer);\r
+      ASSERT_EFI_ERROR (Status);\r
 \r
-  for (Index = 0; Index < NumberOfCpus; Index++) {\r
-    Status = GetProcessorInformation (Index, &ProcessorInfoBuffer);\r
-    ASSERT_EFI_ERROR (Status);\r
+      RegisterTable[Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
+      RegisterTable[Index].TableLength        = 0;\r
+      RegisterTable[Index].AllocatedSize      = 0;\r
+      RegisterTable[Index].RegisterTableEntry = 0;\r
+\r
+      RegisterTable[NumberOfCpus + Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
+      RegisterTable[NumberOfCpus + Index].TableLength        = 0;\r
+      RegisterTable[NumberOfCpus + Index].AllocatedSize      = 0;\r
+      RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;\r
+    }\r
 \r
-    RegisterTable[Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
-    RegisterTable[Index].TableLength        = 0;\r
-    RegisterTable[Index].AllocatedSize      = 0;\r
-    RegisterTable[Index].RegisterTableEntry = 0;\r
+    if (AcpiCpuData->CpuFeatureInitData.RegisterTable == 0) {\r
+      AcpiCpuData->CpuFeatureInitData.RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;\r
+    }\r
 \r
-    RegisterTable[NumberOfCpus + Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
-    RegisterTable[NumberOfCpus + Index].TableLength        = 0;\r
-    RegisterTable[NumberOfCpus + Index].AllocatedSize      = 0;\r
-    RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;\r
+    if (AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable == 0) {\r
+      AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);\r
+    }\r
   }\r
-  AcpiCpuData->RegisterTable           = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;\r
-  AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);\r
 \r
   return AcpiCpuData;\r
 }\r
@@ -908,14 +1043,14 @@ GetAcpiCpuData (
 STATIC\r
 VOID\r
 EnlargeRegisterTable (\r
-  IN OUT CPU_REGISTER_TABLE            *RegisterTable\r
+  IN OUT CPU_REGISTER_TABLE  *RegisterTable\r
   )\r
 {\r
   EFI_PHYSICAL_ADDRESS  Address;\r
   UINTN                 UsedPages;\r
 \r
   UsedPages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;\r
-  Address  = (UINTN)AllocatePages (UsedPages + 1);\r
+  Address   = (UINTN)AllocatePages (UsedPages + 1);\r
   ASSERT (Address != 0);\r
 \r
   //\r
@@ -924,8 +1059,8 @@ EnlargeRegisterTable (
   //\r
   if (RegisterTable->AllocatedSize > 0) {\r
     CopyMem (\r
-      (VOID *) (UINTN) Address,\r
-      (VOID *) (UINTN) RegisterTable->RegisterTableEntry,\r
+      (VOID *)(UINTN)Address,\r
+      (VOID *)(UINTN)RegisterTable->RegisterTableEntry,\r
       RegisterTable->AllocatedSize\r
       );\r
 \r
@@ -953,29 +1088,32 @@ EnlargeRegisterTable (
   @param[in]  ValidBitStart    Start of the bit section\r
   @param[in]  ValidBitLength   Length of the bit section\r
   @param[in]  Value            Value to write\r
+  @param[in]  TestThenWrite    Whether need to test current Value before writing.\r
+\r
 **/\r
 VOID\r
 CpuRegisterTableWriteWorker (\r
-  IN BOOLEAN                 PreSmmFlag,\r
-  IN UINTN                   ProcessorNumber,\r
-  IN REGISTER_TYPE           RegisterType,\r
-  IN UINT64                  Index,\r
-  IN UINT8                   ValidBitStart,\r
-  IN UINT8                   ValidBitLength,\r
-  IN UINT64                  Value\r
+  IN BOOLEAN        PreSmmFlag,\r
+  IN UINTN          ProcessorNumber,\r
+  IN REGISTER_TYPE  RegisterType,\r
+  IN UINT64         Index,\r
+  IN UINT8          ValidBitStart,\r
+  IN UINT8          ValidBitLength,\r
+  IN UINT64         Value,\r
+  IN BOOLEAN        TestThenWrite\r
   )\r
 {\r
-  CPU_FEATURES_DATA        *CpuFeaturesData;\r
-  ACPI_CPU_DATA            *AcpiCpuData;\r
-  CPU_REGISTER_TABLE       *RegisterTable;\r
-  CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;\r
+  CPU_FEATURES_DATA         *CpuFeaturesData;\r
+  ACPI_CPU_DATA             *AcpiCpuData;\r
+  CPU_REGISTER_TABLE        *RegisterTable;\r
+  CPU_REGISTER_TABLE_ENTRY  *RegisterTableEntry;\r
 \r
   CpuFeaturesData = GetCpuFeaturesData ();\r
   if (CpuFeaturesData->RegisterTable == NULL) {\r
     AcpiCpuData = GetAcpiCpuData ();\r
-    ASSERT ((AcpiCpuData != NULL) && (AcpiCpuData->RegisterTable != 0));\r
-    CpuFeaturesData->RegisterTable = (CPU_REGISTER_TABLE *) (UINTN) AcpiCpuData->RegisterTable;\r
-    CpuFeaturesData->PreSmmRegisterTable = (CPU_REGISTER_TABLE *) (UINTN) AcpiCpuData->PreSmmInitRegisterTable;\r
+    ASSERT ((AcpiCpuData != NULL) && (AcpiCpuData->CpuFeatureInitData.RegisterTable != 0));\r
+    CpuFeaturesData->RegisterTable       = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->CpuFeatureInitData.RegisterTable;\r
+    CpuFeaturesData->PreSmmRegisterTable = (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->CpuFeatureInitData.PreSmmInitRegisterTable;\r
   }\r
 \r
   if (PreSmmFlag) {\r
@@ -991,13 +1129,14 @@ CpuRegisterTableWriteWorker (
   //\r
   // Append entry in the register table.\r
   //\r
-  RegisterTableEntry = (CPU_REGISTER_TABLE_ENTRY *) (UINTN) RegisterTable->RegisterTableEntry;\r
+  RegisterTableEntry                                            = (CPU_REGISTER_TABLE_ENTRY *)(UINTN)RegisterTable->RegisterTableEntry;\r
   RegisterTableEntry[RegisterTable->TableLength].RegisterType   = RegisterType;\r
-  RegisterTableEntry[RegisterTable->TableLength].Index          = (UINT32) Index;\r
-  RegisterTableEntry[RegisterTable->TableLength].HighIndex      = (UINT32) RShiftU64 (Index, 32);\r
+  RegisterTableEntry[RegisterTable->TableLength].Index          = (UINT32)Index;\r
+  RegisterTableEntry[RegisterTable->TableLength].HighIndex      = (UINT32)RShiftU64 (Index, 32);\r
   RegisterTableEntry[RegisterTable->TableLength].ValidBitStart  = ValidBitStart;\r
   RegisterTableEntry[RegisterTable->TableLength].ValidBitLength = ValidBitLength;\r
   RegisterTableEntry[RegisterTable->TableLength].Value          = Value;\r
+  RegisterTableEntry[RegisterTable->TableLength].TestThenWrite  = TestThenWrite;\r
 \r
   RegisterTable->TableLength++;\r
 }\r
@@ -1019,21 +1158,55 @@ CpuRegisterTableWriteWorker (
 VOID\r
 EFIAPI\r
 CpuRegisterTableWrite (\r
-  IN UINTN               ProcessorNumber,\r
-  IN REGISTER_TYPE       RegisterType,\r
-  IN UINT64              Index,\r
-  IN UINT64              ValueMask,\r
-  IN UINT64              Value\r
+  IN UINTN          ProcessorNumber,\r
+  IN REGISTER_TYPE  RegisterType,\r
+  IN UINT64         Index,\r
+  IN UINT64         ValueMask,\r
+  IN UINT64         Value\r
+  )\r
+{\r
+  UINT8  Start;\r
+  UINT8  End;\r
+  UINT8  Length;\r
+\r
+  Start  = (UINT8)LowBitSet64 (ValueMask);\r
+  End    = (UINT8)HighBitSet64 (ValueMask);\r
+  Length = End - Start + 1;\r
+  CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE);\r
+}\r
+\r
+/**\r
+  Adds an entry in specified register table.\r
+\r
+  This function adds an entry in specified register table, with given register type,\r
+  register index, bit section and value.\r
+\r
+  @param[in]  ProcessorNumber  The index of the CPU to add a register table entry\r
+  @param[in]  RegisterType     Type of the register to program\r
+  @param[in]  Index            Index of the register to program\r
+  @param[in]  ValueMask        Mask of bits in register to write\r
+  @param[in]  Value            Value to write\r
+\r
+  @note This service could be called by BSP only.\r
+**/\r
+VOID\r
+EFIAPI\r
+CpuRegisterTableTestThenWrite (\r
+  IN UINTN          ProcessorNumber,\r
+  IN REGISTER_TYPE  RegisterType,\r
+  IN UINT64         Index,\r
+  IN UINT64         ValueMask,\r
+  IN UINT64         Value\r
   )\r
 {\r
-  UINT8                   Start;\r
-  UINT8                   End;\r
-  UINT8                   Length;\r
+  UINT8  Start;\r
+  UINT8  End;\r
+  UINT8  Length;\r
 \r
-  Start  = (UINT8)LowBitSet64  (ValueMask);\r
+  Start  = (UINT8)LowBitSet64 (ValueMask);\r
   End    = (UINT8)HighBitSet64 (ValueMask);\r
   Length = End - Start + 1;\r
-  CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value);\r
+  CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, TRUE);\r
 }\r
 \r
 /**\r
@@ -1053,21 +1226,21 @@ CpuRegisterTableWrite (
 VOID\r
 EFIAPI\r
 PreSmmCpuRegisterTableWrite (\r
-  IN UINTN               ProcessorNumber,\r
-  IN REGISTER_TYPE       RegisterType,\r
-  IN UINT64              Index,\r
-  IN UINT64              ValueMask,\r
-  IN UINT64              Value\r
+  IN UINTN          ProcessorNumber,\r
+  IN REGISTER_TYPE  RegisterType,\r
+  IN UINT64         Index,\r
+  IN UINT64         ValueMask,\r
+  IN UINT64         Value\r
   )\r
 {\r
   UINT8  Start;\r
   UINT8  End;\r
   UINT8  Length;\r
 \r
-  Start  = (UINT8)LowBitSet64  (ValueMask);\r
+  Start  = (UINT8)LowBitSet64 (ValueMask);\r
   End    = (UINT8)HighBitSet64 (ValueMask);\r
   Length = End - Start + 1;\r
-  CpuRegisterTableWriteWorker (TRUE, ProcessorNumber, RegisterType, Index, Start, Length, Value);\r
+  CpuRegisterTableWriteWorker (TRUE, ProcessorNumber, RegisterType, Index, Start, Length, Value, FALSE);\r
 }\r
 \r
 /**\r
@@ -1077,20 +1250,21 @@ PreSmmCpuRegisterTableWrite (
   @param[in]  CpuBitMaskSize  The size of CPU feature bit mask buffer\r
   @param[in]  Feature         The bit number of the CPU feature\r
 \r
-  @retval  TRUE   The CPU feature is set in PcdCpuFeaturesSupport.\r
-  @retval  FALSE  The CPU feature is not set in PcdCpuFeaturesSupport.\r
+  @retval  TRUE   The CPU feature is set in CpuBitMask.\r
+  @retval  FALSE  The CPU feature is not set in CpuBitMask.\r
 \r
 **/\r
 BOOLEAN\r
 IsCpuFeatureSetInCpuPcd (\r
-  IN UINT8               *CpuBitMask,\r
-  IN UINTN               CpuBitMaskSize,\r
-  IN UINT32              Feature\r
+  IN UINT8   *CpuBitMask,\r
+  IN UINTN   CpuBitMaskSize,\r
+  IN UINT32  Feature\r
   )\r
 {\r
   if ((Feature >> 3) >= CpuBitMaskSize) {\r
     return FALSE;\r
   }\r
+\r
   return ((*(CpuBitMask + (Feature >> 3)) & (1 << (Feature & 0x07))) != 0);\r
 }\r
 \r
@@ -1111,7 +1285,7 @@ IsCpuFeatureSetInCpuPcd (
 BOOLEAN\r
 EFIAPI\r
 IsCpuFeatureSupported (\r
-  IN UINT32              Feature\r
+  IN UINT32  Feature\r
   )\r
 {\r
   return IsCpuFeatureSetInCpuPcd (\r
@@ -1135,7 +1309,7 @@ IsCpuFeatureSupported (
 BOOLEAN\r
 EFIAPI\r
 IsCpuFeatureInSetting (\r
-  IN UINT32              Feature\r
+  IN UINT32  Feature\r
   )\r
 {\r
   return IsCpuFeatureSetInCpuPcd (\r
@@ -1145,56 +1319,6 @@ IsCpuFeatureInSetting (
            );\r
 }\r
 \r
-/**\r
-  Determines if a CPU feature is set in PcdCpuFeaturesCapability bit mask.\r
-\r
-  @param[in]  Feature  The bit number of the CPU feature to check in the PCD\r
-                       PcdCpuFeaturesCapability\r
-\r
-  @retval  TRUE   The CPU feature is set in PcdCpuFeaturesCapability.\r
-  @retval  FALSE  The CPU feature is not set in PcdCpuFeaturesCapability.\r
-\r
-  @note This service could be called by BSP only.\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-IsCpuFeatureCapability (\r
-  IN UINT32              Feature\r
-  )\r
-{\r
-  return IsCpuFeatureSetInCpuPcd (\r
-           (UINT8 *)PcdGetPtr (PcdCpuFeaturesCapability),\r
-           PcdGetSize (PcdCpuFeaturesCapability),\r
-           Feature\r
-           );\r
-\r
-}\r
-\r
-/**\r
-  Determines if a CPU feature is set in PcdCpuFeaturesUserConfiguration bit mask.\r
-\r
-  @param[in]  Feature  The bit number of the CPU feature to check in the PCD\r
-                       PcdCpuFeaturesUserConfiguration\r
-\r
-  @retval  TRUE   The CPU feature is set in PcdCpuFeaturesUserConfiguration.\r
-  @retval  FALSE  The CPU feature is not set in PcdCpuFeaturesUserConfiguration.\r
-\r
-  @note This service could be called by BSP only.\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-IsCpuFeatureUserConfiguration (\r
-  IN UINT32              Feature\r
-  )\r
-{\r
-  return IsCpuFeatureSetInCpuPcd (\r
-           (UINT8 *)PcdGetPtr (PcdCpuFeaturesUserConfiguration),\r
-           PcdGetSize (PcdCpuFeaturesUserConfiguration),\r
-           Feature\r
-           );\r
-\r
-}\r
-\r
 /**\r
   Switches to assigned BSP after CPU features initialization.\r
 \r
@@ -1205,12 +1329,11 @@ IsCpuFeatureUserConfiguration (
 VOID\r
 EFIAPI\r
 SwitchBspAfterFeaturesInitialize (\r
-  IN UINTN               ProcessorNumber\r
+  IN UINTN  ProcessorNumber\r
   )\r
 {\r
-  CPU_FEATURES_DATA      *CpuFeaturesData;\r
+  CPU_FEATURES_DATA  *CpuFeaturesData;\r
 \r
-  CpuFeaturesData = GetCpuFeaturesData ();\r
+  CpuFeaturesData            = GetCpuFeaturesData ();\r
   CpuFeaturesData->BspNumber = ProcessorNumber;\r
 }\r
-\r