/** @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
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
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
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
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
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
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
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
}\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
/**\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
**/\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
\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
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
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
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
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
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
@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 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
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
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
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