/** @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 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
{\r
UINTN BitMaskSize;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
+ BitMaskSize = PcdGetSize (PcdCpuFeaturesSetting);\r
if (CompareMem (FirstFeatureMask, SecondFeatureMask, BitMaskSize) == 0) {\r
return TRUE;\r
} else {\r
UINT8 *Data8;\r
UINTN BitMaskSize;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
+ BitMaskSize = PcdGetSize (PcdCpuFeaturesSetting);\r
Data8 = (UINT8 *) FeatureMask;\r
for (Index = 0; Index < BitMaskSize; Index++) {\r
DEBUG ((DEBUG_INFO, " %02x ", *Data8++));\r
}\r
}\r
\r
-/**\r
- Determines if the CPU feature is valid.\r
-\r
- @param[in] Feature Pointer to CPU feature\r
-\r
- @retval TRUE The CPU feature is valid.\r
- @retval FALSE The CPU feature is invalid.\r
-**/\r
-BOOLEAN\r
-RegisterCpuFeatureLibIsFeatureValid (\r
- IN UINT32 Feature\r
- )\r
-{\r
- UINT32 Data;\r
-\r
- Data = Feature;\r
- Data &= ~(CPU_FEATURE_BEFORE | CPU_FEATURE_AFTER | CPU_FEATURE_BEFORE_ALL | CPU_FEATURE_AFTER_ALL);\r
- //\r
- // Currently, CPU_FEATURE_PROC_TRACE is the MAX feature we support.\r
- // If you define a feature bigger than it, please replace it at below.\r
- //\r
- if (Data > CPU_FEATURE_PROC_TRACE) {\r
- DEBUG ((DEBUG_ERROR, "Invalid CPU feature: 0x%x ", Feature));\r
- return FALSE;\r
- }\r
- return TRUE;\r
-}\r
-\r
/**\r
Determines if the feature bit mask is in dependent CPU feature bit mask buffer.\r
\r
UINT8 *Data1;\r
UINT8 *Data2;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
+ BitMaskSize = PcdGetSize (PcdCpuFeaturesSetting);\r
\r
Data1 = FeatureMask;\r
Data2 = DependentBitMask;\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] 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 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
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageBeforeFeatureBitMask)) {\r
+ return PackageDepType;\r
+ }\r
+\r
+ if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) &&\r
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreBeforeFeatureBitMask)) {\r
+ return CoreDepType;\r
+ }\r
+\r
+ if ((CpuFeature->BeforeFeatureBitMask != NULL) &&\r
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->BeforeFeatureBitMask)) {\r
+ return ThreadDepType;\r
+ }\r
+\r
+ return NoneDepType;\r
+ }\r
+\r
+ if ((CpuFeature->PackageAfterFeatureBitMask != NULL) &&\r
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->PackageAfterFeatureBitMask)) {\r
+ return PackageDepType;\r
+ }\r
+\r
+ if ((CpuFeature->CoreAfterFeatureBitMask != NULL) &&\r
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->CoreAfterFeatureBitMask)) {\r
+ return CoreDepType;\r
+ }\r
+\r
+ if ((CpuFeature->AfterFeatureBitMask != NULL) &&\r
+ IsBitMaskMatchCheck (NextCpuFeatureMask, CpuFeature->AfterFeatureBitMask)) {\r
+ return ThreadDepType;\r
+ }\r
+\r
+ return NoneDepType;\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] FeatureList Pointer to CPU feature list.\r
+\r
+ @retval return the dependence result.\r
+**/\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->PackageBeforeFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->PackageBeforeFeatureBitMask)) {\r
+ return PackageDepType;\r
+ }\r
+\r
+ if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->CoreBeforeFeatureBitMask)) {\r
+ return CoreDepType;\r
+ }\r
+\r
+ if ((CpuFeature->BeforeFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->BeforeFeatureBitMask)) {\r
+ return ThreadDepType;\r
+ }\r
+\r
+ return NoneDepType;\r
+ }\r
+\r
+ if ((CpuFeature->PackageAfterFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->PackageAfterFeatureBitMask)) {\r
+ return PackageDepType;\r
+ }\r
+\r
+ if ((CpuFeature->CoreAfterFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->CoreAfterFeatureBitMask)) {\r
+ return CoreDepType;\r
+ }\r
+\r
+ if ((CpuFeature->AfterFeatureBitMask != NULL) &&\r
+ FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->AfterFeatureBitMask)) {\r
+ return ThreadDepType;\r
+ }\r
+\r
+ return NoneDepType;\r
+}\r
+\r
+/**\r
+ Base on dependence relationship to asjust feature dependence.\r
+\r
+ ONLY when the feature before(or after) the find feature also has\r
+ dependence with the find feature. In this case, driver need to base\r
+ on dependce relationship to decide how to insert current feature and\r
+ adjust the feature dependence.\r
+\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
+\r
+ @retval FALSE means the previous feature dependence has been adjusted.\r
+ or previous feature has no dependence with the find one.\r
+\r
+**/\r
+BOOLEAN\r
+AdjustFeaturesDependence (\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
+\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
+ // return FALSE.\r
+ //\r
+ if (PreDependType == NoneDepType) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // If both feature have dependence, keep the one which needs use more\r
+ // processors and clear the dependence for the other one.\r
+ //\r
+ if (PreDependType >= CurrentDependType) {\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Base on dependence relationship to asjust feature order.\r
+\r
+ @param[in] FeatureList Pointer to CPU feature list\r
+ @param[in, out] FindEntry The entry this feature depend on.\r
+ @param[in, out] CurrentEntry The entry for this feature.\r
+ @param[in] Before Before or after dependence relationship.\r
+\r
+**/\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
+ )\r
+{\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
+ // AcquireSpinLock/ReleaseSpinLock logic to sequency the execute order.\r
+ // So if driver finds both feature A and B need to execute before feature C, driver will\r
+ // base on dependence type of feature A and B to update the logic here.\r
+ // For example, feature A has package type dependence and feature B has core type dependence,\r
+ // because package type dependence need to wait for more processors which has strong dependence\r
+ // than core type dependence. So driver will adjust the feature order to B -> A -> C. and driver\r
+ // will remove the feature dependence in feature B.\r
+ // Driver just needs to make sure before feature C been executed, feature A has finished its task\r
+ // in all all thread. Feature A finished in all threads also means feature B have finshed in all\r
+ // threads.\r
+ //\r
+ if (Before) {\r
+ PreviousEntry = GetPreviousNode (FeatureList, FindEntry);\r
+ } else {\r
+\r
+ PreviousEntry = GetNextNode (FeatureList, FindEntry);\r
+ }\r
+\r
+ CurrentFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);\r
+ RemoveEntryList (CurrentEntry);\r
+\r
+ if (IsNull (FeatureList, PreviousEntry)) {\r
+ //\r
+ // If not exist the previous or next entry, just insert the current entry.\r
+ //\r
+ if (Before) {\r
+ InsertTailList (FindEntry, CurrentEntry);\r
+ } else {\r
+ InsertHeadList (FindEntry, CurrentEntry);\r
+ }\r
+ } else {\r
+ //\r
+ // 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, 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
+ // the previous feature.\r
+ //\r
+ if (Before) {\r
+ InsertTailList (PreviousEntry, CurrentEntry);\r
+ } else {\r
+ InsertHeadList (PreviousEntry, CurrentEntry);\r
+ }\r
+ } else {\r
+ if (Before) {\r
+ InsertTailList (FindEntry, CurrentEntry);\r
+ } else {\r
+ InsertHeadList (FindEntry, CurrentEntry);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Checks and adjusts current CPU features per dependency relationship.\r
+\r
+ @param[in] FeatureList Pointer to CPU feature list\r
+ @param[in] CurrentEntry Pointer to current checked CPU feature\r
+ @param[in] FeatureMask The feature bit mask.\r
+\r
+ @retval return Swapped info.\r
+**/\r
+BOOLEAN\r
+InsertToBeforeEntry (\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
+\r
+ Swapped = FALSE;\r
+\r
+ //\r
+ // Check all features dispatched before this entry\r
+ //\r
+ CheckEntry = GetFirstNode (FeatureList);\r
+ while (CheckEntry != CurrentEntry) {\r
+ CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);\r
+ if (IsBitMaskMatchCheck (CheckFeature->FeatureMask, FeatureMask)) {\r
+ AdjustEntry (FeatureList, CheckEntry, CurrentEntry, TRUE);\r
+ Swapped = TRUE;\r
+ break;\r
+ }\r
+ CheckEntry = CheckEntry->ForwardLink;\r
+ }\r
+\r
+ return Swapped;\r
+}\r
+\r
+/**\r
+ Checks and adjusts current CPU features per dependency relationship.\r
+\r
+ @param[in] FeatureList Pointer to CPU feature list\r
+ @param[in] CurrentEntry Pointer to current checked CPU feature\r
+ @param[in] FeatureMask The feature bit mask.\r
+\r
+ @retval return Swapped info.\r
+**/\r
+BOOLEAN\r
+InsertToAfterEntry (\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
+\r
+ Swapped = FALSE;\r
+\r
+ //\r
+ // Check all features dispatched after this entry\r
+ //\r
+ CheckEntry = GetNextNode (FeatureList, CurrentEntry);\r
+ while (!IsNull (FeatureList, CheckEntry)) {\r
+ CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);\r
+ if (IsBitMaskMatchCheck (CheckFeature->FeatureMask, FeatureMask)) {\r
+ AdjustEntry (FeatureList, CheckEntry, CurrentEntry, FALSE);\r
+ Swapped = TRUE;\r
+ break;\r
+ }\r
+ CheckEntry = CheckEntry->ForwardLink;\r
+ }\r
+\r
+ return Swapped;\r
+}\r
+\r
/**\r
Checks and adjusts CPU features order per dependency relationship.\r
\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
CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (CurrentEntry);\r
+ NextEntry = CurrentEntry->ForwardLink;\r
if (CpuFeature->BeforeAll) {\r
//\r
// Check all features dispatched before this entry\r
CheckEntry = CheckEntry->ForwardLink;\r
}\r
if (Swapped) {\r
+ CurrentEntry = NextEntry;\r
continue;\r
}\r
}\r
CheckEntry = CheckEntry->ForwardLink;\r
}\r
if (Swapped) {\r
+ CurrentEntry = NextEntry;\r
continue;\r
}\r
}\r
\r
if (CpuFeature->BeforeFeatureBitMask != NULL) {\r
- //\r
- // Check all features dispatched before this entry\r
- //\r
- CheckEntry = GetFirstNode (FeatureList);\r
- while (CheckEntry != CurrentEntry) {\r
- CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);\r
- if (IsBitMaskMatchCheck (CheckFeature->FeatureMask, CpuFeature->BeforeFeatureBitMask)) {\r
- //\r
- // If there is dependency, swap them\r
- //\r
- RemoveEntryList (CurrentEntry);\r
- InsertTailList (CheckEntry, CurrentEntry);\r
- Swapped = TRUE;\r
- break;\r
- }\r
- CheckEntry = CheckEntry->ForwardLink;\r
- }\r
+ Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->BeforeFeatureBitMask);\r
if (Swapped) {\r
continue;\r
}\r
}\r
\r
if (CpuFeature->AfterFeatureBitMask != NULL) {\r
- //\r
- // Check all features dispatched after this entry\r
- //\r
- CheckEntry = GetNextNode (FeatureList, CurrentEntry);\r
- while (!IsNull (FeatureList, CheckEntry)) {\r
- CheckFeature = CPU_FEATURE_ENTRY_FROM_LINK (CheckEntry);\r
- if (IsBitMaskMatchCheck (CheckFeature->FeatureMask, CpuFeature->AfterFeatureBitMask)) {\r
- //\r
- // If there is dependency, swap them\r
- //\r
- TempEntry = GetNextNode (FeatureList, CurrentEntry);\r
- RemoveEntryList (CurrentEntry);\r
- InsertHeadList (CheckEntry, CurrentEntry);\r
- CurrentEntry = TempEntry;\r
- Swapped = TRUE;\r
- break;\r
- }\r
- CheckEntry = CheckEntry->ForwardLink;\r
+ Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->AfterFeatureBitMask);\r
+ if (Swapped) {\r
+ continue;\r
}\r
+ }\r
+\r
+ if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {\r
+ Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->CoreBeforeFeatureBitMask);\r
if (Swapped) {\r
continue;\r
}\r
}\r
- //\r
- // No swap happened, check the next feature\r
- //\r
+\r
+ if (CpuFeature->CoreAfterFeatureBitMask != NULL) {\r
+ Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->CoreAfterFeatureBitMask);\r
+ if (Swapped) {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {\r
+ Swapped = InsertToBeforeEntry (FeatureList, CurrentEntry, CpuFeature->PackageBeforeFeatureBitMask);\r
+ if (Swapped) {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ if (CpuFeature->PackageAfterFeatureBitMask != NULL) {\r
+ Swapped = InsertToAfterEntry (FeatureList, CurrentEntry, CpuFeature->PackageAfterFeatureBitMask);\r
+ if (Swapped) {\r
+ continue;\r
+ }\r
+ }\r
+\r
CurrentEntry = CurrentEntry->ForwardLink;\r
}\r
}\r
UINTN BitMaskSize;\r
BOOLEAN FeatureExist;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
+ BitMaskSize = PcdGetSize (PcdCpuFeaturesSetting);\r
CpuFeaturesData = GetCpuFeaturesData ();\r
if (CpuFeaturesData->FeaturesCount == 0) {\r
InitializeListHead (&CpuFeaturesData->FeatureList);\r
- InitializeSpinLock (&CpuFeaturesData->MsrLock);\r
- InitializeSpinLock (&CpuFeaturesData->MemoryMappedLock);\r
+ InitializeSpinLock (&CpuFeaturesData->CpuFlags.MemoryMappedLock);\r
+ InitializeSpinLock (&CpuFeaturesData->CpuFlags.ConsoleLogLock);\r
CpuFeaturesData->BitMaskSize = (UINT32) BitMaskSize;\r
}\r
ASSERT (CpuFeaturesData->BitMaskSize == BitMaskSize);\r
}\r
CpuFeatureEntry->AfterFeatureBitMask = CpuFeature->AfterFeatureBitMask;\r
}\r
+ if (CpuFeature->CoreBeforeFeatureBitMask != NULL) {\r
+ if (CpuFeatureEntry->CoreBeforeFeatureBitMask != NULL) {\r
+ FreePool (CpuFeatureEntry->CoreBeforeFeatureBitMask);\r
+ }\r
+ CpuFeatureEntry->CoreBeforeFeatureBitMask = CpuFeature->CoreBeforeFeatureBitMask;\r
+ }\r
+ if (CpuFeature->CoreAfterFeatureBitMask != NULL) {\r
+ if (CpuFeatureEntry->CoreAfterFeatureBitMask != NULL) {\r
+ FreePool (CpuFeatureEntry->CoreAfterFeatureBitMask);\r
+ }\r
+ CpuFeatureEntry->CoreAfterFeatureBitMask = CpuFeature->CoreAfterFeatureBitMask;\r
+ }\r
+ if (CpuFeature->PackageBeforeFeatureBitMask != NULL) {\r
+ if (CpuFeatureEntry->PackageBeforeFeatureBitMask != NULL) {\r
+ FreePool (CpuFeatureEntry->PackageBeforeFeatureBitMask);\r
+ }\r
+ CpuFeatureEntry->PackageBeforeFeatureBitMask = CpuFeature->PackageBeforeFeatureBitMask;\r
+ }\r
+ if (CpuFeature->PackageAfterFeatureBitMask != NULL) {\r
+ if (CpuFeatureEntry->PackageAfterFeatureBitMask != NULL) {\r
+ FreePool (CpuFeatureEntry->PackageAfterFeatureBitMask);\r
+ }\r
+ CpuFeatureEntry->PackageAfterFeatureBitMask = CpuFeature->PackageAfterFeatureBitMask;\r
+ }\r
+\r
CpuFeatureEntry->BeforeAll = CpuFeature->BeforeAll;\r
CpuFeatureEntry->AfterAll = CpuFeature->AfterAll;\r
\r
@retval RETURN_UNSUPPORTED Registration of the CPU feature is not\r
supported due to a circular dependency between\r
BEFORE and AFTER features.\r
+ @retval RETURN_NOT_READY CPU feature PCD PcdCpuFeaturesUserConfiguration\r
+ not updated by Platform driver yet.\r
\r
@note This service could be called by BSP only.\r
**/\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
\r
- FeatureMask = NULL;\r
- BeforeFeatureBitMask = NULL;\r
- AfterFeatureBitMask = NULL;\r
+ FeatureMask = NULL;\r
+ BeforeFeatureBitMask = NULL;\r
+ AfterFeatureBitMask = NULL;\r
+ CoreBeforeFeatureBitMask = NULL;\r
+ CoreAfterFeatureBitMask = NULL;\r
+ PackageBeforeFeatureBitMask = NULL;\r
+ PackageAfterFeatureBitMask = NULL;\r
BeforeAll = FALSE;\r
AfterAll = FALSE;\r
\r
- BitMaskSize = PcdGetSize (PcdCpuFeaturesSupport);\r
+ BitMaskSize = PcdGetSize (PcdCpuFeaturesSetting);\r
\r
VA_START (Marker, InitializeFunc);\r
Feature = VA_ARG (Marker, UINT32);\r
- ASSERT (RegisterCpuFeatureLibIsFeatureValid(Feature));\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
BeforeAll = ((Feature & CPU_FEATURE_BEFORE_ALL) != 0) ? TRUE : FALSE;\r
AfterAll = ((Feature & CPU_FEATURE_AFTER_ALL) != 0) ? TRUE : FALSE;\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
+ } else if ((Feature & CPU_FEATURE_CORE_BEFORE) != 0) {\r
+ SetCpuFeaturesBitMask (&CoreBeforeFeatureBitMask, Feature & ~CPU_FEATURE_CORE_BEFORE, BitMaskSize);\r
+ } else if ((Feature & CPU_FEATURE_CORE_AFTER) != 0) {\r
+ SetCpuFeaturesBitMask (&CoreAfterFeatureBitMask, Feature & ~CPU_FEATURE_CORE_AFTER, BitMaskSize);\r
+ } else if ((Feature & CPU_FEATURE_PACKAGE_BEFORE) != 0) {\r
+ SetCpuFeaturesBitMask (&PackageBeforeFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_BEFORE, BitMaskSize);\r
+ } else if ((Feature & CPU_FEATURE_PACKAGE_AFTER) != 0) {\r
+ SetCpuFeaturesBitMask (&PackageAfterFeatureBitMask, Feature & ~CPU_FEATURE_PACKAGE_AFTER, BitMaskSize);\r
}\r
Feature = VA_ARG (Marker, UINT32);\r
}\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->BeforeAll = BeforeAll;\r
- CpuFeature->AfterAll = AfterAll;\r
- CpuFeature->GetConfigDataFunc = GetConfigDataFunc;\r
- CpuFeature->SupportFunc = SupportFunc;\r
- CpuFeature->InitializeFunc = InitializeFunc;\r
+ CpuFeature->Signature = CPU_FEATURE_ENTRY_SIGNATURE;\r
+ CpuFeature->FeatureMask = FeatureMask;\r
+ CpuFeature->BeforeFeatureBitMask = BeforeFeatureBitMask;\r
+ CpuFeature->AfterFeatureBitMask = AfterFeatureBitMask;\r
+ CpuFeature->CoreBeforeFeatureBitMask = CoreBeforeFeatureBitMask;\r
+ CpuFeature->CoreAfterFeatureBitMask = CoreAfterFeatureBitMask;\r
+ CpuFeature->PackageBeforeFeatureBitMask = PackageBeforeFeatureBitMask;\r
+ CpuFeature->PackageAfterFeatureBitMask = PackageAfterFeatureBitMask;\r
+ CpuFeature->BeforeAll = BeforeAll;\r
+ CpuFeature->AfterAll = AfterAll;\r
+ CpuFeature->GetConfigDataFunc = GetConfigDataFunc;\r
+ CpuFeature->SupportFunc = SupportFunc;\r
+ CpuFeature->InitializeFunc = InitializeFunc;\r
if (FeatureName != NULL) {\r
CpuFeature->FeatureName = AllocatePool (CPU_FEATURE_NAME_SIZE);\r
ASSERT (CpuFeature->FeatureName != NULL);\r
return RETURN_SUCCESS;\r
}\r
\r
+/**\r
+ Return ACPI_CPU_DATA data.\r
+\r
+ @return Pointer to ACPI_CPU_DATA data.\r
+**/\r
+ACPI_CPU_DATA *\r
+GetAcpiCpuData (\r
+ 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
+\r
+ AcpiCpuData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)));\r
+ ASSERT (AcpiCpuData != NULL);\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
+\r
+ GetNumberOfProcessor (&NumberOfCpus, &NumberOfEnabledProcessors);\r
+ AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;\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
+\r
+ for (Index = 0; Index < NumberOfCpus; Index++) {\r
+ Status = GetProcessorInformation (Index, &ProcessorInfoBuffer);\r
+ ASSERT_EFI_ERROR (Status);\r
+\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
+ AcpiCpuData->RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;\r
+ AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);\r
+\r
+ return AcpiCpuData;\r
+}\r
+\r
+/**\r
+ Enlarges CPU register table for each processor.\r
+\r
+ @param[in, out] RegisterTable Pointer processor's CPU register table\r
+**/\r
+STATIC\r
+VOID\r
+EnlargeRegisterTable (\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
+ ASSERT (Address != 0);\r
+\r
+ //\r
+ // If there are records existing in the register table, then copy its contents\r
+ // to new region and free the old one.\r
+ //\r
+ if (RegisterTable->AllocatedSize > 0) {\r
+ CopyMem (\r
+ (VOID *) (UINTN) Address,\r
+ (VOID *) (UINTN) RegisterTable->RegisterTableEntry,\r
+ RegisterTable->AllocatedSize\r
+ );\r
+\r
+ FreePages ((VOID *)(UINTN)RegisterTable->RegisterTableEntry, UsedPages);\r
+ }\r
+\r
+ //\r
+ // Adjust the allocated size and register table base address.\r
+ //\r
+ RegisterTable->AllocatedSize += EFI_PAGE_SIZE;\r
+ RegisterTable->RegisterTableEntry = Address;\r
+}\r
+\r
/**\r
Add an entry in specified register table.\r
\r
IN UINT64 Value\r
)\r
{\r
- EFI_STATUS Status;\r
CPU_FEATURES_DATA *CpuFeaturesData;\r
ACPI_CPU_DATA *AcpiCpuData;\r
CPU_REGISTER_TABLE *RegisterTable;\r
\r
CpuFeaturesData = GetCpuFeaturesData ();\r
if (CpuFeaturesData->RegisterTable == NULL) {\r
- AcpiCpuData = (ACPI_CPU_DATA *) (UINTN) PcdGet64 (PcdCpuS3DataAddress);\r
- if (AcpiCpuData == NULL) {\r
- AcpiCpuData = AllocateAcpiCpuData ();\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
- ASSERT (AcpiCpuData->RegisterTable != 0);\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
}\r
@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
);\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