]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c
UefiCpuPkg/RegisterCpuFeaturesLib: Rename [Before|After]FeatureBitMask
[mirror_edk2.git] / UefiCpuPkg / Library / RegisterCpuFeaturesLib / RegisterCpuFeaturesLib.c
index fa0f0b41e26bdff055db5bd0affd6b56bd3cee3d..4063d45760ad4094ce72226abcec6d21e5c7cee4 100644 (file)
@@ -1,53 +1,29 @@
 /** @file\r
   CPU Register Table Library functions.\r
 \r
-  Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2017 - 2020, 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 (PcdCpuFeaturesSetting);\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
 \r
-  BitMaskSize = PcdGetSize (PcdCpuFeaturesSetting);\r
   Data8       = (UINT8 *) FeatureMask;\r
   for (Index = 0; Index < BitMaskSize; Index++) {\r
     DEBUG ((DEBUG_INFO, " %02x ", *Data8++));\r
@@ -59,10 +35,13 @@ 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
@@ -70,7 +49,7 @@ DumpCpuFeature (
     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
@@ -89,16 +68,16 @@ IsBitMaskMatchCheck (
   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 (PcdCpuFeaturesSetting);\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
@@ -215,8 +194,8 @@ DetectFeatureScope (
       return CoreDepType;\r
     }\r
 \r
-    if ((CpuFeature->BeforeFeatureBitMask != NULL) &&\r
-        IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->BeforeFeatureBitMask)) {\r
+    if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) &&\r
+        IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadBeforeFeatureBitMask)) {\r
       return ThreadDepType;\r
     }\r
 \r
@@ -233,8 +212,8 @@ DetectFeatureScope (
     return CoreDepType;\r
   }\r
 \r
-  if ((CpuFeature->AfterFeatureBitMask != NULL) &&\r
-      IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->AfterFeatureBitMask)) {\r
+  if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) &&\r
+      IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->ThreadAfterFeatureBitMask)) {\r
     return ThreadDepType;\r
   }\r
 \r
@@ -268,8 +247,8 @@ DetectNoneNeighborhoodFeatureScope (
       return CoreDepType;\r
     }\r
 \r
-    if ((CpuFeature->BeforeFeatureBitMask != NULL) &&\r
-        FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->BeforeFeatureBitMask)) {\r
+    if ((CpuFeature->ThreadBeforeFeatureBitMask != NULL) &&\r
+        FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->ThreadBeforeFeatureBitMask)) {\r
       return ThreadDepType;\r
     }\r
 \r
@@ -286,8 +265,8 @@ DetectNoneNeighborhoodFeatureScope (
     return CoreDepType;\r
   }\r
 \r
-  if ((CpuFeature->AfterFeatureBitMask != NULL) &&\r
-      FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->AfterFeatureBitMask)) {\r
+  if ((CpuFeature->ThreadAfterFeatureBitMask != NULL) &&\r
+      FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->ThreadAfterFeatureBitMask)) {\r
     return ThreadDepType;\r
   }\r
 \r
@@ -582,15 +561,15 @@ CheckCpuFeaturesDependency (
       }\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
         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
         continue;\r
       }\r
@@ -631,6 +610,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
@@ -642,32 +622,21 @@ CheckCpuFeaturesDependency (
 **/\r
 RETURN_STATUS\r
 RegisterCpuFeatureWorker (\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
 \r
-  BitMaskSize     = PcdGetSize (PcdCpuFeaturesSetting);\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
   CpuFeatureEntry = NULL;\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
@@ -679,12 +648,12 @@ RegisterCpuFeatureWorker (
 \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
@@ -707,17 +676,17 @@ RegisterCpuFeatureWorker (
       ASSERT_EFI_ERROR (Status);\r
       FreePool (CpuFeature->FeatureName);\r
     }\r
-    if (CpuFeature->BeforeFeatureBitMask != NULL) {\r
-      if (CpuFeatureEntry->BeforeFeatureBitMask != NULL) {\r
-        FreePool (CpuFeatureEntry->BeforeFeatureBitMask);\r
+    if (CpuFeature->ThreadBeforeFeatureBitMask != NULL) {\r
+      if (CpuFeatureEntry->ThreadBeforeFeatureBitMask != NULL) {\r
+        FreePool (CpuFeatureEntry->ThreadBeforeFeatureBitMask);\r
       }\r
-      CpuFeatureEntry->BeforeFeatureBitMask = CpuFeature->BeforeFeatureBitMask;\r
+      CpuFeatureEntry->ThreadBeforeFeatureBitMask = CpuFeature->ThreadBeforeFeatureBitMask;\r
     }\r
-    if (CpuFeature->AfterFeatureBitMask != NULL) {\r
-      if (CpuFeatureEntry->AfterFeatureBitMask != NULL) {\r
-        FreePool (CpuFeatureEntry->AfterFeatureBitMask);\r
+    if (CpuFeature->ThreadAfterFeatureBitMask != NULL) {\r
+      if (CpuFeatureEntry->ThreadAfterFeatureBitMask != NULL) {\r
+        FreePool (CpuFeatureEntry->ThreadAfterFeatureBitMask);\r
       }\r
-      CpuFeatureEntry->AfterFeatureBitMask = CpuFeature->AfterFeatureBitMask;\r
+      CpuFeatureEntry->ThreadAfterFeatureBitMask = CpuFeature->ThreadAfterFeatureBitMask;\r
     }\r
     if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {\r
       if (CpuFeatureEntry->CoreBeforeFeatureBitMask != NULL) {\r
@@ -844,21 +813,21 @@ RegisterCpuFeature (
   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                      *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
@@ -866,37 +835,55 @@ RegisterCpuFeature (
   BeforeAll            = FALSE;\r
   AfterAll             = FALSE;\r
 \r
-  BitMaskSize = PcdGetSize (PcdCpuFeaturesSetting);\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
+    //\r
+    // It's invalid to require a feature is before AND after all other features.\r
+    //\r
     ASSERT ((Feature & (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL))\r
                     != (CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL));\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 ((Feature & (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER))\r
+                    != (CPU_FEATURE_THREAD_BEFORE | CPU_FEATURE_THREAD_AFTER));\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
+    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
     Feature = VA_ARG (Marker, UINT32);\r
   }\r
@@ -906,8 +893,8 @@ RegisterCpuFeature (
   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
@@ -924,7 +911,7 @@ RegisterCpuFeature (
     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
@@ -1046,6 +1033,8 @@ 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
@@ -1055,7 +1044,8 @@ CpuRegisterTableWriteWorker (
   IN UINT64                  Index,\r
   IN UINT8                   ValidBitStart,\r
   IN UINT8                   ValidBitLength,\r
-  IN UINT64                  Value\r
+  IN UINT64                  Value,\r
+  IN BOOLEAN                 TestThenWrite\r
   )\r
 {\r
   CPU_FEATURES_DATA        *CpuFeaturesData;\r
@@ -1091,6 +1081,7 @@ CpuRegisterTableWriteWorker (
   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
@@ -1126,7 +1117,41 @@ CpuRegisterTableWrite (
   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, 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
+\r
+  Start  = (UINT8)LowBitSet64  (ValueMask);\r
+  End    = (UINT8)HighBitSet64 (ValueMask);\r
+  Length = End - Start + 1;\r
+  CpuRegisterTableWriteWorker (FALSE, ProcessorNumber, RegisterType, Index, Start, Length, Value, TRUE);\r
 }\r
 \r
 /**\r
@@ -1160,7 +1185,7 @@ PreSmmCpuRegisterTableWrite (
   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