summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg
diff options
context:
space:
mode:
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r--UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c75
-rw-r--r--UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeatures.h16
-rw-r--r--UefiCpuPkg/Library/RegisterCpuFeaturesLib/RegisterCpuFeaturesLib.c122
3 files changed, 193 insertions, 20 deletions
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
@@ -528,6 +528,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.
@param[in] NumberOfCpus Number of processor in system
@@ -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.
+ //
+ NoneNeibBeforeDep = DetectNoneNeighborhoodFeatureScope(CpuFeatureInOrder, TRUE, &CpuInitOrder->OrderList);
+
+ //
+ // Get the biggest dependence and add semaphore for it.
+ // PackageDepType > CoreDepType > ThreadDepType > NoneDepType.
//
- ASSERT (!(BeforeDep > ThreadDepType && AfterDep > ThreadDepType));
+ 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
@@ -207,6 +207,22 @@ DetectFeatureScope (
);
/**
+ 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.
@param[in,out] Buffer The pointer to private data buffer.
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
@@ -113,6 +113,75 @@ IsBitMaskMatchCheck (
}
/**
+ 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.
@param[in] CpuFeature Pointer to CPU feature.
@@ -179,6 +248,59 @@ DetectFeatureScope (
}
/**
+ 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.
ONLY when the feature before(or after) the find feature also has