From: Andre Przywara Date: Wed, 1 Feb 2023 11:46:31 +0000 (+0000) Subject: feat(cpufeat): extend check_feature() to deal with min/max X-Git-Tag: baikal/aarch64/sdk5.10~1^2~185^2~4 X-Git-Url: https://git.baikalelectronics.ru/?a=commitdiff_plain;h=a4cccb4f6cbbb35d12bd5f8779f3c6d8d762619c;p=arm-tf.git feat(cpufeat): extend check_feature() to deal with min/max So far the check_feature() function compares the subfield of a CPU ID register against 0, to learn if a feature is enabled or not. This is problematic for checks that require a certain revision of a feature, so we should check against a minimum version number instead. On top of that we might need to add code to support newer versions of a feature, so we should be alerted if new hardware introduces a higher number. Extend the check_feature() function to take two extra arguments: the minimum version, and the greatest currently known number. Then make sure that the CPU ID field is in this range. Change-Id: I425b68535a2ba9eafd31854e74d142183b521cd5 Signed-off-by: Andre Przywara --- diff --git a/common/feat_detect.c b/common/feat_detect.c index a8c40f70d..cbe78c057 100644 --- a/common/feat_detect.c +++ b/common/feat_detect.c @@ -36,19 +36,28 @@ static inline void feature_panic(char *feat_name) /******************************************************************************* * Function : check_feature * Check for a valid combination of build time flags (ENABLE_FEAT_xxx) and - * feature availability on the hardware. - * Panics if a feature is forcefully enabled, but not available on the PE. + * feature availability on the hardware. is the smallest feature + * ID field value that is required for that feature. + * Triggers a panic later if a feature is forcefully enabled, but not + * available on the PE. Also will panic if the hardware feature ID field + * is larger than the maximum known and supported number, specified by . * * We force inlining here to let the compiler optimise away the whole check * if the feature is disabled at build time (FEAT_STATE_DISABLED). ******************************************************************************/ static inline void __attribute((__always_inline__)) -check_feature(int state, unsigned long field, const char *feat_name) +check_feature(int state, unsigned long field, const char *feat_name, + unsigned int min, unsigned int max) { - if (state == FEAT_STATE_ALWAYS && field == 0U) { + if (state == FEAT_STATE_ALWAYS && field < min) { ERROR("FEAT_%s not supported by the PE\n", feat_name); tainted = true; } + if (state >= FEAT_STATE_ALWAYS && field > max) { + ERROR("FEAT_%s is version %ld, but is only known up to version %d\n", + feat_name, field, max); + tainted = true; + } } /****************************************** @@ -312,7 +321,8 @@ void detect_arch_features(void) /* v8.4 features */ read_feat_dit(); - check_feature(ENABLE_FEAT_AMUv1, read_feat_amu_id_field(), "AMUv1"); + check_feature(ENABLE_FEAT_AMUv1, read_feat_amu_id_field(), + "AMUv1", 1, 2); read_feat_mpam(); read_feat_nv2(); read_feat_sel2(); @@ -326,12 +336,12 @@ void detect_arch_features(void) /* v8.6 features */ read_feat_amuv1p1(); - check_feature(ENABLE_FEAT_FGT, read_feat_fgt_id_field(), "FGT"); + check_feature(ENABLE_FEAT_FGT, read_feat_fgt_id_field(), "FGT", 1, 1); read_feat_ecv(); read_feat_twed(); /* v8.7 features */ - check_feature(ENABLE_FEAT_HCX, read_feat_hcx_id_field(), "HCX"); + check_feature(ENABLE_FEAT_HCX, read_feat_hcx_id_field(), "HCX", 1, 1); /* v9.0 features */ read_feat_brbe();