summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorManish Pandey <manish.pandey2@arm.com>2023-01-19 18:19:50 +0100
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2023-01-19 18:19:50 +0100
commit344e5e8149f98fcbb2360cabc1dfc99db210ef82 (patch)
treeca911d4700d2e0604961aef4916f9734cd9ee446 /common
parent96df1f1db6e824cd3802dd7bcf245359e779cfcb (diff)
parent2e1241888ee82a5a9b3b30acd83a1f4ea6732f1b (diff)
downloadarm-trusted-firmware-344e5e8149f98fcbb2360cabc1dfc99db210ef82.tar.gz
Merge changes from topic "feat_state_rework" into integration
* changes: feat(fvp): enable FEAT_HCX by default refactor(context-mgmt): move FEAT_HCX save/restore into C refactor(cpufeat): convert FEAT_HCX to new scheme feat(fvp): enable FEAT_FGT by default refactor(context-mgmt): move FEAT_FGT save/restore code into C refactor(amu): convert FEAT_AMUv1 to new scheme refactor(cpufeat): decouple FGT feature detection and build flags refactor(cpufeat): check FEAT_FGT in a new way refactor(cpufeat): move helpers into .c file, rename FEAT_STATE_ feat(aarch64): make ID system register reads non-volatile
Diffstat (limited to 'common')
-rw-r--r--common/feat_detect.c128
1 files changed, 70 insertions, 58 deletions
diff --git a/common/feat_detect.c b/common/feat_detect.c
index ee3458865..a8c40f70d 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -4,24 +4,59 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arch_features.h>
+#include <common/debug.h>
#include <common/feat_detect.h>
+static bool tainted;
+
/*******************************************************************************
* This section lists the wrapper modules for each feature to evaluate the
- * feature states (FEAT_STATE_1 and FEAT_STATE_2) and perform necessary action
- * as below:
+ * feature states (FEAT_STATE_ALWAYS and FEAT_STATE_CHECK) and perform
+ * necessary action as below:
*
* It verifies whether the FEAT_XXX (eg: FEAT_SB) is supported by the PE or not.
* Without this check an exception would occur during context save/restore
* routines, if the feature is enabled but not supported by PE.
******************************************************************************/
+#define feat_detect_panic(a, b) ((a) ? (void)0 : feature_panic(b))
+
+/*******************************************************************************
+ * Function : feature_panic
+ * Customised panic function with error logging mechanism to list the feature
+ * not supported by the PE.
+ ******************************************************************************/
+static inline void feature_panic(char *feat_name)
+{
+ ERROR("FEAT_%s not supported by the PE\n", feat_name);
+ panic();
+}
+
+/*******************************************************************************
+ * 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.
+ *
+ * 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)
+{
+ if (state == FEAT_STATE_ALWAYS && field == 0U) {
+ ERROR("FEAT_%s not supported by the PE\n", feat_name);
+ tainted = true;
+ }
+}
+
/******************************************
* Feature : FEAT_SB (Speculation Barrier)
*****************************************/
static void read_feat_sb(void)
{
-#if (ENABLE_FEAT_SB == FEAT_STATE_1)
+#if (ENABLE_FEAT_SB == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_0_feat_sb_present(), "SB");
#endif
}
@@ -31,7 +66,7 @@ static void read_feat_sb(void)
*****************************************************/
static void read_feat_csv2_2(void)
{
-#if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_1)
+#if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_0_feat_csv2_2_present(), "CSV2_2");
#endif
}
@@ -41,7 +76,7 @@ static void read_feat_csv2_2(void)
**********************************************/
static void read_feat_pan(void)
{
-#if (ENABLE_FEAT_PAN == FEAT_STATE_1)
+#if (ENABLE_FEAT_PAN == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_1_pan_present(), "PAN");
#endif
}
@@ -51,7 +86,7 @@ static void read_feat_pan(void)
*****************************************************/
static void read_feat_vhe(void)
{
-#if (ENABLE_FEAT_VHE == FEAT_STATE_1)
+#if (ENABLE_FEAT_VHE == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_1_vhe_present(), "VHE");
#endif
}
@@ -61,7 +96,7 @@ static void read_feat_vhe(void)
******************************************************************************/
static void read_feat_ras(void)
{
-#if (RAS_EXTENSION == FEAT_STATE_1)
+#if (RAS_EXTENSION == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_2_feat_ras_present(), "RAS");
#endif
}
@@ -71,7 +106,7 @@ static void read_feat_ras(void)
***********************************************/
static void read_feat_pauth(void)
{
-#if (ENABLE_PAUTH == FEAT_STATE_1) || (CTX_INCLUDE_PAUTH_REGS == FEAT_STATE_1)
+#if (ENABLE_PAUTH == FEAT_STATE_ALWAYS) || (CTX_INCLUDE_PAUTH_REGS == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_3_pauth_present(), "PAUTH");
#endif
}
@@ -81,27 +116,17 @@ static void read_feat_pauth(void)
***********************************************************/
static void read_feat_dit(void)
{
-#if (ENABLE_FEAT_DIT == FEAT_STATE_1)
+#if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_4_feat_dit_present(), "DIT");
#endif
}
-/*********************************************************
- * Feature : FEAT_AMUv1 (Activity Monitors Extensions v1)
- ********************************************************/
-static void read_feat_amuv1(void)
-{
-#if (ENABLE_FEAT_AMUv1 == FEAT_STATE_1)
- feat_detect_panic(is_armv8_4_feat_amuv1_present(), "AMUv1");
-#endif
-}
-
/****************************************************************************
* Feature : FEAT_MPAM (Memory Partitioning and Monitoring (MPAM) Extension)
***************************************************************************/
static void read_feat_mpam(void)
{
-#if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_1)
+#if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_ALWAYS)
feat_detect_panic(get_mpam_version() != 0U, "MPAM");
#endif
}
@@ -111,7 +136,7 @@ static void read_feat_mpam(void)
*************************************************************/
static void read_feat_nv2(void)
{
-#if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_1)
+#if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_ALWAYS)
unsigned int nv = get_armv8_4_feat_nv_support();
feat_detect_panic((nv == ID_AA64MMFR2_EL1_NV2_SUPPORTED), "NV2");
@@ -123,7 +148,7 @@ static void read_feat_nv2(void)
**********************************/
static void read_feat_sel2(void)
{
-#if (ENABLE_FEAT_SEL2 == FEAT_STATE_1)
+#if (ENABLE_FEAT_SEL2 == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_4_sel2_present(), "SEL2");
#endif
}
@@ -133,7 +158,7 @@ static void read_feat_sel2(void)
***************************************************/
static void read_feat_trf(void)
{
-#if (ENABLE_TRF_FOR_NS == FEAT_STATE_1)
+#if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS)
feat_detect_panic(is_arm8_4_feat_trf_present(), "TRF");
#endif
}
@@ -143,7 +168,7 @@ static void read_feat_trf(void)
***********************************************/
static void read_feat_mte(void)
{
-#if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_1)
+#if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_ALWAYS)
unsigned int mte = get_armv8_5_mte_support();
feat_detect_panic((mte != MTE_UNIMPLEMENTED), "MTE");
@@ -155,7 +180,7 @@ static void read_feat_mte(void)
**********************************************/
static void read_feat_rng(void)
{
-#if (ENABLE_FEAT_RNG == FEAT_STATE_1)
+#if (ENABLE_FEAT_RNG == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_5_rng_present(), "RNG");
#endif
}
@@ -165,27 +190,17 @@ static void read_feat_rng(void)
***************************************************/
static void read_feat_bti(void)
{
-#if (ENABLE_BTI == FEAT_STATE_1)
+#if (ENABLE_BTI == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_5_bti_present(), "BTI");
#endif
}
-/****************************************
- * Feature : FEAT_FGT (Fine Grain Traps)
- ***************************************/
-static void read_feat_fgt(void)
-{
-#if (ENABLE_FEAT_FGT == FEAT_STATE_1)
- feat_detect_panic(is_armv8_6_fgt_present(), "FGT");
-#endif
-}
-
/***********************************************
* Feature : FEAT_AMUv1p1 (AMU Extensions v1.1)
**********************************************/
static void read_feat_amuv1p1(void)
{
-#if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_1)
+#if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_6_feat_amuv1p1_present(), "AMUv1p1");
#endif
}
@@ -195,7 +210,7 @@ static void read_feat_amuv1p1(void)
******************************************************/
static void read_feat_ecv(void)
{
-#if (ENABLE_FEAT_ECV == FEAT_STATE_1)
+#if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS)
unsigned int ecv = get_armv8_6_ecv_support();
feat_detect_panic(((ecv == ID_AA64MMFR0_EL1_ECV_SUPPORTED) ||
@@ -208,27 +223,17 @@ static void read_feat_ecv(void)
**********************************************************/
static void read_feat_twed(void)
{
-#if (ENABLE_FEAT_TWED == FEAT_STATE_1)
+#if (ENABLE_FEAT_TWED == FEAT_STATE_ALWAYS)
feat_detect_panic(is_armv8_6_twed_present(), "TWED");
#endif
}
-/******************************************************************
- * Feature : FEAT_HCX (Extended Hypervisor Configuration Register)
- *****************************************************************/
-static void read_feat_hcx(void)
-{
-#if (ENABLE_FEAT_HCX == FEAT_STATE_1)
- feat_detect_panic(is_feat_hcx_present(), "HCX");
-#endif
-}
-
/**************************************************
* Feature : FEAT_RME (Realm Management Extension)
*************************************************/
static void read_feat_rme(void)
{
-#if (ENABLE_RME == FEAT_STATE_1)
+#if (ENABLE_RME == FEAT_STATE_ALWAYS)
feat_detect_panic((get_armv9_2_feat_rme_support() !=
ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED), "RME");
#endif
@@ -239,7 +244,7 @@ static void read_feat_rme(void)
*****************************************************/
static void read_feat_brbe(void)
{
-#if (ENABLE_BRBE_FOR_NS == FEAT_STATE_1)
+#if (ENABLE_BRBE_FOR_NS == FEAT_STATE_ALWAYS)
feat_detect_panic(is_feat_brbe_present(), "BRBE");
#endif
}
@@ -249,7 +254,7 @@ static void read_feat_brbe(void)
*****************************************************/
static void read_feat_trbe(void)
{
-#if (ENABLE_TRBE_FOR_NS == FEAT_STATE_1)
+#if (ENABLE_TRBE_FOR_NS == FEAT_STATE_ALWAYS)
feat_detect_panic(is_feat_trbe_present(), "TRBE");
#endif
}
@@ -259,7 +264,7 @@ static void read_feat_trbe(void)
*****************************************************************/
static void read_feat_rng_trap(void)
{
-#if (ENABLE_FEAT_RNG_TRAP == FEAT_STATE_1)
+#if (ENABLE_FEAT_RNG_TRAP == FEAT_STATE_ALWAYS)
feat_detect_panic(is_feat_rng_trap_present(), "RNG_TRAP");
#endif
}
@@ -283,11 +288,14 @@ static void read_feat_rng_trap(void)
* ENABLE_FEAT_xxx = 2 : The feature is enabled but dynamically enabled at runtime
* depending on hardware capability.
*
- * For better readability, state values are defined with macros namely:
- * { FEAT_STATE_0, FEAT_STATE_1, FEAT_STATE_2 } taking values as their naming.
+ * For better readability, state values are defined with macros, namely:
+ * { FEAT_STATE_DISABLED, FEAT_STATE_ALWAYS, FEAT_STATE_CHECK }, taking values
+ * { 0, 1, 2 }, respectively, as their naming.
**********************************************************************************/
void detect_arch_features(void)
{
+ tainted = false;
+
/* v8.0 features */
read_feat_sb();
read_feat_csv2_2();
@@ -304,7 +312,7 @@ void detect_arch_features(void)
/* v8.4 features */
read_feat_dit();
- read_feat_amuv1();
+ check_feature(ENABLE_FEAT_AMUv1, read_feat_amu_id_field(), "AMUv1");
read_feat_mpam();
read_feat_nv2();
read_feat_sel2();
@@ -318,12 +326,12 @@ void detect_arch_features(void)
/* v8.6 features */
read_feat_amuv1p1();
- read_feat_fgt();
+ check_feature(ENABLE_FEAT_FGT, read_feat_fgt_id_field(), "FGT");
read_feat_ecv();
read_feat_twed();
/* v8.7 features */
- read_feat_hcx();
+ check_feature(ENABLE_FEAT_HCX, read_feat_hcx_id_field(), "HCX");
/* v9.0 features */
read_feat_brbe();
@@ -331,4 +339,8 @@ void detect_arch_features(void)
/* v9.2 features */
read_feat_rme();
+
+ if (tainted) {
+ panic();
+ }
}