CPU Features Initialize functions.\r
\r
Copyright (c) 2017 - 2019, 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
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "RegisterCpuFeatures.h"\r
\r
CHAR16 *mDependTypeStr[] = {L"None", L"Thread", L"Core", L"Package", L"Invalid" };\r
-CHAR16 *mRegisterTypeStr[] = {L"MSR", L"CR", L"MMIO", L"CACHE", L"SEMAP", L"INVALID" };\r
\r
/**\r
Worker function to save PcdCpuFeaturesCapability.\r
\r
@param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer\r
- @param[in] FeatureMaskSize CPU feature bits mask buffer size.\r
+ @param[in] BitMaskSize CPU feature bits mask buffer size.\r
\r
**/\r
VOID\r
SetCapabilityPcd (\r
IN UINT8 *SupportedFeatureMask,\r
- IN UINT32 FeatureMaskSize\r
+ IN UINTN BitMaskSize\r
)\r
{\r
EFI_STATUS Status;\r
- UINTN BitMaskSize;\r
-\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesCapability);\r
- ASSERT (FeatureMaskSize == BitMaskSize);\r
\r
Status = PcdSetPtrS (PcdCpuFeaturesCapability, &BitMaskSize, SupportedFeatureMask);\r
ASSERT_EFI_ERROR (Status);\r
Worker function to save PcdCpuFeaturesSetting.\r
\r
@param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer\r
+ @param[in] BitMaskSize CPU feature bits mask buffer size.\r
**/\r
VOID\r
SetSettingPcd (\r
- IN UINT8 *SupportedFeatureMask\r
+ IN UINT8 *SupportedFeatureMask,\r
+ IN UINTN BitMaskSize\r
)\r
{\r
EFI_STATUS Status;\r
- UINTN BitMaskSize;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSetting);\r
Status = PcdSetPtrS (PcdCpuFeaturesSetting, &BitMaskSize, SupportedFeatureMask);\r
ASSERT_EFI_ERROR (Status);\r
}\r
ASSERT (CpuFeaturesData->CpuFlags.CoreSemaphoreCount != NULL);\r
CpuFeaturesData->CpuFlags.PackageSemaphoreCount = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount);\r
ASSERT (CpuFeaturesData->CpuFlags.PackageSemaphoreCount != NULL);\r
-\r
- //\r
- // Get support and configuration PCDs\r
- //\r
- CpuFeaturesData->SupportPcd = GetSupportPcd ();\r
}\r
\r
/**\r
\r
@param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer\r
@param[in] OrFeatureBitMask The feature bit mask to do OR operation\r
+ @param[in] BitMaskSize The CPU feature bits mask buffer size.\r
+\r
**/\r
VOID\r
SupportedMaskOr (\r
IN UINT8 *SupportedFeatureMask,\r
- IN UINT8 *OrFeatureBitMask\r
+ IN UINT8 *OrFeatureBitMask,\r
+ IN UINT32 BitMaskSize\r
)\r
{\r
UINTN Index;\r
- UINTN BitMaskSize;\r
UINT8 *Data1;\r
UINT8 *Data2;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
Data1 = SupportedFeatureMask;\r
Data2 = OrFeatureBitMask;\r
for (Index = 0; Index < BitMaskSize; Index++) {\r
\r
@param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer\r
@param[in] AndFeatureBitMask The feature bit mask to do AND operation\r
+ @param[in] BitMaskSize CPU feature bits mask buffer size.\r
+\r
**/\r
VOID\r
SupportedMaskAnd (\r
IN UINT8 *SupportedFeatureMask,\r
- IN CONST UINT8 *AndFeatureBitMask\r
+ IN CONST UINT8 *AndFeatureBitMask,\r
+ IN UINT32 BitMaskSize\r
)\r
{\r
UINTN Index;\r
- UINTN BitMaskSize;\r
UINT8 *Data1;\r
CONST UINT8 *Data2;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
Data1 = SupportedFeatureMask;\r
Data2 = AndFeatureBitMask;\r
for (Index = 0; Index < BitMaskSize; Index++) {\r
\r
@param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer\r
@param[in] AndFeatureBitMask The feature bit mask to do XOR operation\r
+ @param[in] BitMaskSize CPU feature bits mask buffer size.\r
**/\r
VOID\r
SupportedMaskCleanBit (\r
IN UINT8 *SupportedFeatureMask,\r
- IN UINT8 *AndFeatureBitMask\r
+ IN UINT8 *AndFeatureBitMask,\r
+ IN UINT32 BitMaskSize\r
)\r
{\r
UINTN Index;\r
- UINTN BitMaskSize;\r
UINT8 *Data1;\r
UINT8 *Data2;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
Data1 = SupportedFeatureMask;\r
Data2 = AndFeatureBitMask;\r
for (Index = 0; Index < BitMaskSize; Index++) {\r
\r
@param[in] SupportedFeatureMask The pointer to CPU feature bits mask buffer\r
@param[in] ComparedFeatureBitMask The feature bit mask to be compared\r
+ @param[in] BitMaskSize CPU feature bits mask buffer size.\r
\r
@retval TRUE The ComparedFeatureBitMask is set in CPU feature supported bits\r
mask buffer.\r
BOOLEAN\r
IsBitMaskMatch (\r
IN UINT8 *SupportedFeatureMask,\r
- IN UINT8 *ComparedFeatureBitMask\r
+ IN UINT8 *ComparedFeatureBitMask,\r
+ IN UINT32 BitMaskSize\r
)\r
{\r
UINTN Index;\r
- UINTN BitMaskSize;\r
UINT8 *Data1;\r
UINT8 *Data2;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
-\r
Data1 = SupportedFeatureMask;\r
Data2 = ComparedFeatureBitMask;\r
for (Index = 0; Index < BitMaskSize; Index++) {\r
Entry = GetFirstNode (&CpuFeaturesData->FeatureList);\r
while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {\r
CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry);\r
- if (IsBitMaskMatch (CpuFeaturesData->SupportPcd, CpuFeature->FeatureMask)) {\r
- if (CpuFeature->SupportFunc == NULL) {\r
- //\r
- // If SupportFunc is NULL, then the feature is supported.\r
- //\r
- SupportedMaskOr (\r
- CpuFeaturesData->InitOrder[ProcessorNumber].FeaturesSupportedMask,\r
- CpuFeature->FeatureMask\r
- );\r
- } else if (CpuFeature->SupportFunc (ProcessorNumber, CpuInfo, CpuFeature->ConfigData)) {\r
- SupportedMaskOr (\r
- CpuFeaturesData->InitOrder[ProcessorNumber].FeaturesSupportedMask,\r
- CpuFeature->FeatureMask\r
- );\r
- }\r
+ if (CpuFeature->SupportFunc == NULL) {\r
+ //\r
+ // If SupportFunc is NULL, then the feature is supported.\r
+ //\r
+ SupportedMaskOr (\r
+ CpuFeaturesData->InitOrder[ProcessorNumber].FeaturesSupportedMask,\r
+ CpuFeature->FeatureMask,\r
+ CpuFeaturesData->BitMaskSize\r
+ );\r
+ } else if (CpuFeature->SupportFunc (ProcessorNumber, CpuInfo, CpuFeature->ConfigData)) {\r
+ SupportedMaskOr (\r
+ CpuFeaturesData->InitOrder[ProcessorNumber].FeaturesSupportedMask,\r
+ CpuFeature->FeatureMask,\r
+ CpuFeaturesData->BitMaskSize\r
+ );\r
}\r
Entry = Entry->ForwardLink;\r
}\r
//\r
// Calculate the last capability on all processors\r
//\r
- SupportedMaskAnd (CpuFeaturesData->CapabilityPcd, CpuInitOrder->FeaturesSupportedMask);\r
+ SupportedMaskAnd (CpuFeaturesData->CapabilityPcd, CpuInitOrder->FeaturesSupportedMask, CpuFeaturesData->BitMaskSize);\r
}\r
//\r
// Calculate the last setting\r
//\r
CpuFeaturesData->SettingPcd = AllocateCopyPool (CpuFeaturesData->BitMaskSize, CpuFeaturesData->CapabilityPcd);\r
ASSERT (CpuFeaturesData->SettingPcd != NULL);\r
- SupportedMaskAnd (CpuFeaturesData->SettingPcd, PcdGetPtr (PcdCpuFeaturesSetting));\r
+ SupportedMaskAnd (CpuFeaturesData->SettingPcd, PcdGetPtr (PcdCpuFeaturesSetting), CpuFeaturesData->BitMaskSize);\r
\r
//\r
// Dump the last CPU feature list\r
Entry = GetFirstNode (&CpuFeaturesData->FeatureList);\r
while (!IsNull (&CpuFeaturesData->FeatureList, Entry)) {\r
CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry);\r
- if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->CapabilityPcd)) {\r
- if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->SettingPcd)) {\r
+ if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize)) {\r
+ if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize)) {\r
DEBUG ((DEBUG_INFO, "[Enable ] "));\r
} else {\r
DEBUG ((DEBUG_INFO, "[Disable ] "));\r
} else {\r
DEBUG ((DEBUG_INFO, "[Unsupport] "));\r
}\r
- DumpCpuFeature (CpuFeature);\r
+ DumpCpuFeature (CpuFeature, CpuFeaturesData->BitMaskSize);\r
Entry = Entry->ForwardLink;\r
}\r
- DEBUG ((DEBUG_INFO, "PcdCpuFeaturesSupport:\n"));\r
- DumpCpuFeatureMask (CpuFeaturesData->SupportPcd);\r
DEBUG ((DEBUG_INFO, "PcdCpuFeaturesCapability:\n"));\r
- DumpCpuFeatureMask (CpuFeaturesData->CapabilityPcd);\r
+ DumpCpuFeatureMask (CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize);\r
DEBUG ((DEBUG_INFO, "Origin PcdCpuFeaturesSetting:\n"));\r
- DumpCpuFeatureMask (PcdGetPtr (PcdCpuFeaturesSetting));\r
+ DumpCpuFeatureMask (PcdGetPtr (PcdCpuFeaturesSetting), CpuFeaturesData->BitMaskSize);\r
DEBUG ((DEBUG_INFO, "Final PcdCpuFeaturesSetting:\n"));\r
- DumpCpuFeatureMask (CpuFeaturesData->SettingPcd);\r
+ DumpCpuFeatureMask (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize);\r
);\r
\r
//\r
// Save PCDs and display CPU PCDs\r
//\r
SetCapabilityPcd (CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize);\r
- SetSettingPcd (CpuFeaturesData->SettingPcd);\r
+ SetSettingPcd (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize);\r
\r
for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
CpuInitOrder = &CpuFeaturesData->InitOrder[ProcessorNumber];\r
// Insert each feature into processor's order list\r
//\r
CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (Entry);\r
- if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->CapabilityPcd)) {\r
+ if (IsBitMaskMatch (CpuFeature->FeatureMask, CpuFeaturesData->CapabilityPcd, CpuFeaturesData->BitMaskSize)) {\r
CpuFeatureInOrder = AllocateCopyPool (sizeof (CPU_FEATURES_ENTRY), CpuFeature);\r
ASSERT (CpuFeatureInOrder != NULL);\r
InsertTailList (&CpuInitOrder->OrderList, &CpuFeatureInOrder->Link);\r
CpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (Entry);\r
\r
Success = FALSE;\r
- if (IsBitMaskMatch (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->SettingPcd)) {\r
+ if (IsBitMaskMatch (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize)) {\r
Status = CpuFeatureInOrder->InitializeFunc (ProcessorNumber, CpuInfo, CpuFeatureInOrder->ConfigData, TRUE);\r
if (EFI_ERROR (Status)) {\r
//\r
// Clean the CpuFeatureInOrder->FeatureMask in setting PCD.\r
//\r
- SupportedMaskCleanBit (CpuFeaturesData->SettingPcd, CpuFeatureInOrder->FeatureMask);\r
+ SupportedMaskCleanBit (CpuFeaturesData->SettingPcd, CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize);\r
if (CpuFeatureInOrder->FeatureName != NULL) {\r
DEBUG ((DEBUG_WARN, "Warning :: Failed to enable Feature: Name = %a.\n", CpuFeatureInOrder->FeatureName));\r
} else {\r
DEBUG ((DEBUG_WARN, "Warning :: Failed to enable Feature: Mask = "));\r
- DumpCpuFeatureMask (CpuFeatureInOrder->FeatureMask);\r
+ DumpCpuFeatureMask (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize);\r
}\r
} else {\r
Success = TRUE;\r
DEBUG ((DEBUG_WARN, "Warning :: Failed to disable Feature: Name = %a.\n", CpuFeatureInOrder->FeatureName));\r
} else {\r
DEBUG ((DEBUG_WARN, "Warning :: Failed to disable Feature: Mask = "));\r
- DumpCpuFeatureMask (CpuFeatureInOrder->FeatureMask);\r
+ DumpCpuFeatureMask (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->BitMaskSize);\r
}\r
} else {\r
Success = TRUE;\r
// again during initialize the features.\r
//\r
DEBUG ((DEBUG_INFO, "Dump final value for PcdCpuFeaturesSetting:\n"));\r
- DumpCpuFeatureMask (CpuFeaturesData->SettingPcd);\r
+ DumpCpuFeatureMask (CpuFeaturesData->SettingPcd, CpuFeaturesData->BitMaskSize);\r
\r
//\r
// Dump the RegisterTable\r
) != Value);\r
}\r
\r
+/**\r
+ Read / write CR value.\r
+\r
+ @param[in] CrIndex The CR index which need to read/write.\r
+ @param[in] Read Read or write. TRUE is read.\r
+ @param[in,out] CrValue CR value.\r
+\r
+ @retval EFI_SUCCESS means read/write success, else return EFI_UNSUPPORTED.\r
+**/\r
+UINTN\r
+ReadWriteCr (\r
+ IN UINT32 CrIndex,\r
+ IN BOOLEAN Read,\r
+ IN OUT UINTN *CrValue\r
+ )\r
+{\r
+ switch (CrIndex) {\r
+ case 0:\r
+ if (Read) {\r
+ *CrValue = AsmReadCr0 ();\r
+ } else {\r
+ AsmWriteCr0 (*CrValue);\r
+ }\r
+ break;\r
+ case 2:\r
+ if (Read) {\r
+ *CrValue = AsmReadCr2 ();\r
+ } else {\r
+ AsmWriteCr2 (*CrValue);\r
+ }\r
+ break;\r
+ case 3:\r
+ if (Read) {\r
+ *CrValue = AsmReadCr3 ();\r
+ } else {\r
+ AsmWriteCr3 (*CrValue);\r
+ }\r
+ break;\r
+ case 4:\r
+ if (Read) {\r
+ *CrValue = AsmReadCr4 ();\r
+ } else {\r
+ AsmWriteCr4 (*CrValue);\r
+ }\r
+ break;\r
+ default:\r
+ return EFI_UNSUPPORTED;;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Initialize the CPU registers from a register table.\r
\r
UINT32 PackageThreadsCount;\r
UINT32 CurrentThread;\r
UINTN ProcessorIndex;\r
- UINTN ThreadIndex;\r
UINTN ValidThreadCount;\r
UINT32 *ValidCoreCountPerPackage;\r
+ EFI_STATUS Status;\r
+ UINT64 CurrentValue;\r
\r
//\r
// Traverse Register Table of this logical processor\r
\r
RegisterTableEntry = &RegisterTableEntryHead[Index];\r
\r
- DEBUG_CODE_BEGIN ();\r
- //\r
- // Wait for the AP to release the MSR spin lock.\r
- //\r
- while (!AcquireSpinLockOrFail (&CpuFlags->ConsoleLogLock)) {\r
- CpuPause ();\r
- }\r
- ThreadIndex = ApLocation->Package * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount +\r
- ApLocation->Core * CpuStatus->MaxThreadCount +\r
- ApLocation->Thread;\r
- DEBUG ((\r
- DEBUG_INFO,\r
- "Processor = %08lu, Index %08lu, Type = %s!\n",\r
- (UINT64)ThreadIndex,\r
- (UINT64)Index,\r
- mRegisterTypeStr[MIN ((REGISTER_TYPE)RegisterTableEntry->RegisterType, InvalidReg)]\r
- ));\r
- ReleaseSpinLock (&CpuFlags->ConsoleLogLock);\r
- DEBUG_CODE_END ();\r
-\r
//\r
// Check the type of specified register\r
//\r
// The specified register is Control Register\r
//\r
case ControlRegister:\r
- switch (RegisterTableEntry->Index) {\r
- case 0:\r
- Value = AsmReadCr0 ();\r
- Value = (UINTN) BitFieldWrite64 (\r
- Value,\r
- RegisterTableEntry->ValidBitStart,\r
- RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,\r
- RegisterTableEntry->Value\r
- );\r
- AsmWriteCr0 (Value);\r
- break;\r
- case 2:\r
- Value = AsmReadCr2 ();\r
- Value = (UINTN) BitFieldWrite64 (\r
- Value,\r
- RegisterTableEntry->ValidBitStart,\r
- RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,\r
- RegisterTableEntry->Value\r
- );\r
- AsmWriteCr2 (Value);\r
- break;\r
- case 3:\r
- Value = AsmReadCr3 ();\r
- Value = (UINTN) BitFieldWrite64 (\r
- Value,\r
- RegisterTableEntry->ValidBitStart,\r
- RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,\r
- RegisterTableEntry->Value\r
- );\r
- AsmWriteCr3 (Value);\r
- break;\r
- case 4:\r
- Value = AsmReadCr4 ();\r
- Value = (UINTN) BitFieldWrite64 (\r
- Value,\r
- RegisterTableEntry->ValidBitStart,\r
- RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,\r
- RegisterTableEntry->Value\r
- );\r
- AsmWriteCr4 (Value);\r
- break;\r
- case 8:\r
- //\r
- // Do we need to support CR8?\r
- //\r
- break;\r
- default:\r
+ Status = ReadWriteCr (RegisterTableEntry->Index, TRUE, &Value);\r
+ if (EFI_ERROR (Status)) {\r
break;\r
}\r
+ if (RegisterTableEntry->TestThenWrite) {\r
+ CurrentValue = BitFieldRead64 (\r
+ Value,\r
+ RegisterTableEntry->ValidBitStart,\r
+ RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1\r
+ );\r
+ if (CurrentValue == RegisterTableEntry->Value) {\r
+ break;\r
+ }\r
+ }\r
+ Value = (UINTN) BitFieldWrite64 (\r
+ Value,\r
+ RegisterTableEntry->ValidBitStart,\r
+ RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,\r
+ RegisterTableEntry->Value\r
+ );\r
+ ReadWriteCr (RegisterTableEntry->Index, FALSE, &Value);\r
break;\r
+\r
//\r
// The specified register is Model Specific Register\r
//\r
case Msr:\r
+ if (RegisterTableEntry->TestThenWrite) {\r
+ Value = (UINTN)AsmReadMsr64 (RegisterTableEntry->Index);\r
+ if (RegisterTableEntry->ValidBitLength >= 64) {\r
+ if (Value == RegisterTableEntry->Value) {\r
+ break;\r
+ }\r
+ } else {\r
+ CurrentValue = BitFieldRead64 (\r
+ Value,\r
+ RegisterTableEntry->ValidBitStart,\r
+ RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1\r
+ );\r
+ if (CurrentValue == RegisterTableEntry->Value) {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
if (RegisterTableEntry->ValidBitLength >= 64) {\r
//\r
// If length is not less than 64 bits, then directly write without reading\r
\r
CpuInitDataInitialize ();\r
\r
- //\r
- // Wakeup all APs for data collection.\r
- //\r
- StartupAPsWorker (CollectProcessorData, NULL);\r
+ if (CpuFeaturesData->NumberOfCpus > 1) {\r
+ //\r
+ // Wakeup all APs for data collection.\r
+ //\r
+ StartupAllAPsWorker (CollectProcessorData, NULL);\r
+ }\r
\r
//\r
// Collect data on BSP\r