}\r
}\r
\r
+/**\r
+ Get the biggest dependence type.\r
+ PackageDepType > CoreDepType > ThreadDepType > NoneDepType.\r
+\r
+ @param[in] BeforeDep Before dependence type.\r
+ @param[in] AfterDep After dependence type.\r
+ @param[in] NoneNeibBeforeDep Before dependence type for not neighborhood features.\r
+ @param[in] NoneNeibAfterDep After dependence type for not neighborhood features.\r
+\r
+ @retval Return the biggest dependence type.\r
+**/\r
+CPU_FEATURE_DEPENDENCE_TYPE\r
+BiggestDep (\r
+ IN CPU_FEATURE_DEPENDENCE_TYPE BeforeDep,\r
+ IN CPU_FEATURE_DEPENDENCE_TYPE AfterDep,\r
+ IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibBeforeDep,\r
+ IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibAfterDep\r
+ )\r
+{\r
+ CPU_FEATURE_DEPENDENCE_TYPE Bigger;\r
+\r
+ Bigger = MAX (BeforeDep, AfterDep);\r
+ Bigger = MAX (Bigger, NoneNeibBeforeDep);\r
+ return MAX(Bigger, NoneNeibAfterDep);\r
+}\r
+\r
/**\r
Analysis register CPU features on each processor and save CPU setting in CPU register table.\r
\r
BOOLEAN Success;\r
CPU_FEATURE_DEPENDENCE_TYPE BeforeDep;\r
CPU_FEATURE_DEPENDENCE_TYPE AfterDep;\r
+ CPU_FEATURE_DEPENDENCE_TYPE NoneNeibBeforeDep;\r
+ CPU_FEATURE_DEPENDENCE_TYPE NoneNeibAfterDep;\r
\r
CpuFeaturesData = GetCpuFeaturesData ();\r
CpuFeaturesData->CapabilityPcd = AllocatePool (CpuFeaturesData->BitMaskSize);\r
//\r
CpuInfo = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo;\r
Entry = GetFirstNode (&CpuInitOrder->OrderList);\r
- NextEntry = Entry->ForwardLink;\r
while (!IsNull (&CpuInitOrder->OrderList, Entry)) {\r
CpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (Entry);\r
- if (!IsNull (&CpuInitOrder->OrderList, NextEntry)) {\r
- NextCpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry);\r
- } else {\r
- NextCpuFeatureInOrder = NULL;\r
- }\r
+\r
Success = FALSE;\r
if (IsBitMaskMatch (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->SettingPcd)) {\r
Status = CpuFeatureInOrder->InitializeFunc (ProcessorNumber, CpuInfo, CpuFeatureInOrder->ConfigData, TRUE);\r
}\r
\r
if (Success) {\r
- //\r
- // If feature has dependence with the next feature (ONLY care core/package dependency).\r
- // and feature initialize succeed, add sync semaphere here.\r
- //\r
- if (NextCpuFeatureInOrder != NULL) {\r
+ NextEntry = Entry->ForwardLink;\r
+ if (!IsNull (&CpuInitOrder->OrderList, NextEntry)) {\r
+ NextCpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry);\r
+\r
+ //\r
+ // If feature has dependence with the next feature (ONLY care core/package dependency).\r
+ // and feature initialize succeed, add sync semaphere here.\r
+ //\r
BeforeDep = DetectFeatureScope (CpuFeatureInOrder, TRUE, NextCpuFeatureInOrder->FeatureMask);\r
AfterDep = DetectFeatureScope (NextCpuFeatureInOrder, FALSE, CpuFeatureInOrder->FeatureMask);\r
+ //\r
+ // Check whether next feature has After type dependence with not neighborhood CPU\r
+ // Features in former CPU features.\r
+ //\r
+ NoneNeibAfterDep = DetectNoneNeighborhoodFeatureScope(NextCpuFeatureInOrder, FALSE, &CpuInitOrder->OrderList);\r
} else {\r
- BeforeDep = DetectFeatureScope (CpuFeatureInOrder, TRUE, NULL);\r
- AfterDep = NoneDepType;\r
+ BeforeDep = NoneDepType;\r
+ AfterDep = NoneDepType;\r
+ NoneNeibAfterDep = NoneDepType;\r
}\r
//\r
- // Assume only one of the depend is valid.\r
+ // Check whether current feature has Before type dependence with none neighborhood\r
+ // CPU features in after Cpu features.\r
+ //\r
+ NoneNeibBeforeDep = DetectNoneNeighborhoodFeatureScope(CpuFeatureInOrder, TRUE, &CpuInitOrder->OrderList);\r
+\r
+ //\r
+ // Get the biggest dependence and add semaphore for it.\r
+ // PackageDepType > CoreDepType > ThreadDepType > NoneDepType.\r
//\r
- ASSERT (!(BeforeDep > ThreadDepType && AfterDep > ThreadDepType));\r
+ BeforeDep = BiggestDep(BeforeDep, AfterDep, NoneNeibBeforeDep, NoneNeibAfterDep);\r
if (BeforeDep > ThreadDepType) {\r
CPU_REGISTER_TABLE_WRITE32 (ProcessorNumber, Semaphore, 0, BeforeDep);\r
}\r
- if (AfterDep > ThreadDepType) {\r
- CPU_REGISTER_TABLE_WRITE32 (ProcessorNumber, Semaphore, 0, AfterDep);\r
- }\r
}\r
\r
- Entry = Entry->ForwardLink;\r
- NextEntry = Entry->ForwardLink;\r
+ Entry = Entry->ForwardLink;\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
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