mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 01:54:22 +00:00
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 <andre.przywara@arm.com>
This commit is contained in:
parent
fd1dd4cb2c
commit
a4cccb4f6c
1 changed files with 17 additions and 7 deletions
|
@ -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. <min> 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 <max>.
|
||||
*
|
||||
* 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();
|
||||
|
|
Loading…
Add table
Reference in a new issue