diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c index 8588800e4a..e61ace9bad 100644 --- a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c @@ -527,6 +527,32 @@ DumpRegisterTableOnProcessor ( } } +/** + Get the biggest dependence type. + PackageDepType > CoreDepType > ThreadDepType > NoneDepType. + + @param[in] BeforeDep Before dependence type. + @param[in] AfterDep After dependence type. + @param[in] NoneNeibBeforeDep Before dependence type for not neighborhood features. + @param[in] NoneNeibAfterDep After dependence type for not neighborhood features. + + @retval Return the biggest dependence type. +**/ +CPU_FEATURE_DEPENDENCE_TYPE +BiggestDep ( + IN CPU_FEATURE_DEPENDENCE_TYPE BeforeDep, + IN CPU_FEATURE_DEPENDENCE_TYPE AfterDep, + IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibBeforeDep, + IN CPU_FEATURE_DEPENDENCE_TYPE NoneNeibAfterDep + ) +{ + CPU_FEATURE_DEPENDENCE_TYPE Bigger; + + Bigger = MAX (BeforeDep, AfterDep); + Bigger = MAX (Bigger, NoneNeibBeforeDep); + return MAX(Bigger, NoneNeibAfterDep); +} + /** Analysis register CPU features on each processor and save CPU setting in CPU register table. @@ -551,6 +577,8 @@ AnalysisProcessorFeatures ( BOOLEAN Success; CPU_FEATURE_DEPENDENCE_TYPE BeforeDep; CPU_FEATURE_DEPENDENCE_TYPE AfterDep; + CPU_FEATURE_DEPENDENCE_TYPE NoneNeibBeforeDep; + CPU_FEATURE_DEPENDENCE_TYPE NoneNeibAfterDep; CpuFeaturesData = GetCpuFeaturesData (); CpuFeaturesData->CapabilityPcd = AllocatePool (CpuFeaturesData->BitMaskSize); @@ -627,14 +655,9 @@ AnalysisProcessorFeatures ( // CpuInfo = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo; Entry = GetFirstNode (&CpuInitOrder->OrderList); - NextEntry = Entry->ForwardLink; while (!IsNull (&CpuInitOrder->OrderList, Entry)) { CpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (Entry); - if (!IsNull (&CpuInitOrder->OrderList, NextEntry)) { - NextCpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry); - } else { - NextCpuFeatureInOrder = NULL; - } + Success = FALSE; if (IsBitMaskMatch (CpuFeatureInOrder->FeatureMask, CpuFeaturesData->SettingPcd)) { Status = CpuFeatureInOrder->InitializeFunc (ProcessorNumber, CpuInfo, CpuFeatureInOrder->ConfigData, TRUE); @@ -667,31 +690,43 @@ AnalysisProcessorFeatures ( } if (Success) { - // - // If feature has dependence with the next feature (ONLY care core/package dependency). - // and feature initialize succeed, add sync semaphere here. - // - if (NextCpuFeatureInOrder != NULL) { + NextEntry = Entry->ForwardLink; + if (!IsNull (&CpuInitOrder->OrderList, NextEntry)) { + NextCpuFeatureInOrder = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry); + + // + // If feature has dependence with the next feature (ONLY care core/package dependency). + // and feature initialize succeed, add sync semaphere here. + // BeforeDep = DetectFeatureScope (CpuFeatureInOrder, TRUE, NextCpuFeatureInOrder->FeatureMask); AfterDep = DetectFeatureScope (NextCpuFeatureInOrder, FALSE, CpuFeatureInOrder->FeatureMask); + // + // Check whether next feature has After type dependence with not neighborhood CPU + // Features in former CPU features. + // + NoneNeibAfterDep = DetectNoneNeighborhoodFeatureScope(NextCpuFeatureInOrder, FALSE, &CpuInitOrder->OrderList); } else { - BeforeDep = DetectFeatureScope (CpuFeatureInOrder, TRUE, NULL); - AfterDep = NoneDepType; + BeforeDep = NoneDepType; + AfterDep = NoneDepType; + NoneNeibAfterDep = NoneDepType; } // - // Assume only one of the depend is valid. + // Check whether current feature has Before type dependence with none neighborhood + // CPU features in after Cpu features. // - ASSERT (!(BeforeDep > ThreadDepType && AfterDep > ThreadDepType)); + NoneNeibBeforeDep = DetectNoneNeighborhoodFeatureScope(CpuFeatureInOrder, TRUE, &CpuInitOrder->OrderList); + + // + // Get the biggest dependence and add semaphore for it. + // PackageDepType > CoreDepType > ThreadDepType > NoneDepType. + // + BeforeDep = BiggestDep(BeforeDep, AfterDep, NoneNeibBeforeDep, NoneNeibAfterDep); if (BeforeDep > ThreadDepType) { CPU_REGISTER_TABLE_WRITE32 (ProcessorNumber, Semaphore, 0, BeforeDep); } - if (AfterDep > ThreadDepType) { - CPU_REGISTER_TABLE_WRITE32 (ProcessorNumber, Semaphore, 0, AfterDep); - } } - Entry = Entry->ForwardLink; - NextEntry = Entry->ForwardLink; + Entry = Entry->ForwardLink; } // diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeatures.h b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeatures.h index b4c8ab777e..0a67a0581a 100644 --- a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeatures.h +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeatures.h @@ -206,6 +206,22 @@ DetectFeatureScope ( IN UINT8 *NextCpuFeatureMask ); +/** + Return feature dependence result. + + @param[in] CpuFeature Pointer to CPU feature. + @param[in] Before Check before dependence or after. + @param[in] FeatureList Pointer to CPU feature list. + + @retval return the dependence result. +**/ +CPU_FEATURE_DEPENDENCE_TYPE +DetectNoneNeighborhoodFeatureScope ( + IN CPU_FEATURES_ENTRY *CpuFeature, + IN BOOLEAN Before, + IN LIST_ENTRY *FeatureList + ); + /** Programs registers for the calling processor. diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c index 394695baf2..ed8d526325 100644 --- a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c +++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c @@ -112,6 +112,75 @@ IsBitMaskMatchCheck ( return FALSE; } +/** + Try to find the specify cpu featuren in former/after feature list. + + @param[in] FeatureList Pointer to dependent CPU feature list + @param[in] CurrentEntry Pointer to current CPU feature entry. + @param[in] SearchFormer Find in former feature or after features. + @param[in] FeatureMask Pointer to CPU feature bit mask + + @retval TRUE The feature bit mask is in dependent CPU feature bit mask buffer. + @retval FALSE The feature bit mask is not in dependent CPU feature bit mask buffer. +**/ +BOOLEAN +FindSpecifyFeature ( + IN LIST_ENTRY *FeatureList, + IN LIST_ENTRY *CurrentEntry, + IN BOOLEAN SearchFormer, + IN UINT8 *FeatureMask + ) +{ + CPU_FEATURES_ENTRY *CpuFeature; + LIST_ENTRY *NextEntry; + + // + // Check whether exist the not neighborhood entry first. + // If not exist, return FALSE means not found status. + // + if (SearchFormer) { + NextEntry = CurrentEntry->BackLink; + if (IsNull (FeatureList, NextEntry)) { + return FALSE; + } + + NextEntry = NextEntry->BackLink; + if (IsNull (FeatureList, NextEntry)) { + return FALSE; + } + + NextEntry = CurrentEntry->BackLink->BackLink; + } else { + NextEntry = CurrentEntry->ForwardLink; + if (IsNull (FeatureList, NextEntry)) { + return FALSE; + } + + NextEntry = NextEntry->ForwardLink; + if (IsNull (FeatureList, NextEntry)) { + return FALSE; + } + + NextEntry = CurrentEntry->ForwardLink->ForwardLink; + } + + while (!IsNull (FeatureList, NextEntry)) { + CpuFeature = CPU_FEATURE_ENTRY_FROM_LINK (NextEntry); + + if (IsBitMaskMatchCheck (FeatureMask, CpuFeature->FeatureMask)) { + return TRUE; + } + + if (SearchFormer) { + NextEntry = NextEntry->BackLink; + } else { + NextEntry = NextEntry->ForwardLink; + } + } + + return FALSE; +} + /** Return feature dependence result. @@ -178,6 +247,59 @@ DetectFeatureScope ( return NoneDepType; } +/** + Return feature dependence result. + + @param[in] CpuFeature Pointer to CPU feature. + @param[in] Before Check before dependence or after. + @param[in] FeatureList Pointer to CPU feature list. + + @retval return the dependence result. +**/ +CPU_FEATURE_DEPENDENCE_TYPE +DetectNoneNeighborhoodFeatureScope ( + IN CPU_FEATURES_ENTRY *CpuFeature, + IN BOOLEAN Before, + IN LIST_ENTRY *FeatureList + ) +{ + if (Before) { + if ((CpuFeature->PackageBeforeFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->PackageBeforeFeatureBitMask)) { + return PackageDepType; + } + + if ((CpuFeature->CoreBeforeFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->CoreBeforeFeatureBitMask)) { + return CoreDepType; + } + + if ((CpuFeature->BeforeFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, FALSE, CpuFeature->BeforeFeatureBitMask)) { + return ThreadDepType; + } + + return NoneDepType; + } + + if ((CpuFeature->PackageAfterFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->PackageAfterFeatureBitMask)) { + return PackageDepType; + } + + if ((CpuFeature->CoreAfterFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->CoreAfterFeatureBitMask)) { + return CoreDepType; + } + + if ((CpuFeature->AfterFeatureBitMask != NULL) && + FindSpecifyFeature(FeatureList, &CpuFeature->Link, TRUE, CpuFeature->AfterFeatureBitMask)) { + return ThreadDepType; + } + + return NoneDepType; +} + /** Base on dependence relationship to asjust feature dependence.