diff options
-rw-r--r-- | bl31/bl31_main.c | 9 | ||||
-rw-r--r-- | changelog.yaml | 3 | ||||
-rw-r--r-- | common/feat_detect.c | 128 | ||||
-rw-r--r-- | include/arch/aarch64/arch_features.h | 74 | ||||
-rw-r--r-- | include/arch/aarch64/arch_helpers.h | 50 | ||||
-rw-r--r-- | include/common/feat_detect.h | 20 | ||||
-rw-r--r-- | include/lib/el3_runtime/aarch64/context.h | 8 | ||||
-rw-r--r-- | lib/el3_runtime/aarch64/context.S | 60 | ||||
-rw-r--r-- | lib/el3_runtime/aarch64/context_mgmt.c | 57 | ||||
-rw-r--r-- | plat/arm/board/fvp/platform.mk | 4 | ||||
-rw-r--r-- | plat/qti/common/src/qti_pm.c | 3 |
11 files changed, 217 insertions, 199 deletions
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index 2a3d838e4..e70eb5584 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -93,15 +93,6 @@ void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, /* Perform late platform-specific setup */ bl31_plat_arch_setup(); -#if ENABLE_FEAT_HCX - /* - * Assert that FEAT_HCX is supported on this system, without this check - * an exception would occur during context save/restore if enabled but - * not supported. - */ - assert(is_feat_hcx_present()); -#endif /* ENABLE_FEAT_HCX */ - #if CTX_INCLUDE_PAUTH_REGS /* * Assert that the ARMv8.3-PAuth registers are present or an access diff --git a/changelog.yaml b/changelog.yaml index 1e1f0a105..e100f8283 100644 --- a/changelog.yaml +++ b/changelog.yaml @@ -101,6 +101,9 @@ subsections: - title: Extended Cache Index (FEAT_CCIDX) scope: ccidx + - title: CPU feature / ID register handling in general + scope: cpufeat + - title: Support for the `HCRX_EL2` register (FEAT_HCX) scope: hcx 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(); + } } diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 932e8850a..2b801ac84 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -10,6 +10,7 @@ #include <stdbool.h> #include <arch_helpers.h> +#include <common/feat_detect.h> static inline bool is_armv7_gentimer_present(void) { @@ -97,10 +98,23 @@ static inline bool is_armv8_6_twed_present(void) ID_AA64MMFR1_EL1_TWED_MASK) == ID_AA64MMFR1_EL1_TWED_SUPPORTED); } -static inline bool is_armv8_6_fgt_present(void) +static unsigned int read_feat_fgt_id_field(void) { - return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_FGT_SHIFT) & - ID_AA64MMFR0_EL1_FGT_MASK) != 0U; + return (read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_FGT_SHIFT) & + ID_AA64MMFR0_EL1_FGT_MASK; +} + +static inline bool is_feat_fgt_supported(void) +{ + if (ENABLE_FEAT_FGT == FEAT_STATE_DISABLED) { + return false; + } + + if (ENABLE_FEAT_FGT == FEAT_STATE_ALWAYS) { + return true; + } + + return read_feat_fgt_id_field() != 0U; } static inline unsigned long int get_armv8_6_ecv_support(void) @@ -115,10 +129,31 @@ static inline bool is_armv8_5_rng_present(void) ID_AA64ISAR0_RNDR_MASK); } +/******************************************************************************* + * Functions to identify the presence of the Activity Monitors Extension + ******************************************************************************/ +static unsigned int read_feat_amu_id_field(void) +{ + return (read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) & + ID_AA64PFR0_AMU_MASK; +} + +static inline bool is_feat_amu_supported(void) +{ + if (ENABLE_FEAT_AMUv1 == FEAT_STATE_DISABLED) { + return false; + } + + if (ENABLE_FEAT_AMUv1 == FEAT_STATE_ALWAYS) { + return true; + } + + return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1; +} + static inline bool is_armv8_6_feat_amuv1p1_present(void) { - return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) & - ID_AA64PFR0_AMU_MASK) >= ID_AA64PFR0_AMU_V1P1); + return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1P1; } /* @@ -138,10 +173,23 @@ static inline unsigned int get_mpam_version(void) ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK)); } -static inline bool is_feat_hcx_present(void) +static inline unsigned int read_feat_hcx_id_field(void) +{ + return (read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) & + ID_AA64MMFR1_EL1_HCX_MASK; +} + +static inline bool is_feat_hcx_supported(void) { - return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) & - ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED); + if (ENABLE_FEAT_HCX == FEAT_STATE_DISABLED) { + return false; + } + + if (ENABLE_FEAT_HCX == FEAT_STATE_ALWAYS) { + return true; + } + + return read_feat_hcx_id_field() != 0U; } static inline bool is_feat_rng_trap_present(void) @@ -226,16 +274,6 @@ static inline bool is_arm8_4_feat_trf_present(void) ID_AA64DFR0_TRACEFILT_MASK) == ID_AA64DFR0_TRACEFILT_SUPPORTED); } -/******************************************************************************* - * Function to identify the presence of FEAT_AMUv1 (Activity Monitors- - * Extension v1) - ******************************************************************************/ -static inline bool is_armv8_4_feat_amuv1_present(void) -{ - return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) & - ID_AA64PFR0_AMU_MASK) >= ID_AA64PFR0_AMU_V1); -} - /******************************************************************************** * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization * Support) diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index fe9b5a563..86c1dbe27 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -27,6 +27,14 @@ static inline u_register_t read_ ## _name(void) \ return v; \ } +#define _DEFINE_SYSREG_READ_FUNC_NV(_name, _reg_name) \ +static inline u_register_t read_ ## _name(void) \ +{ \ + u_register_t v; \ + __asm__ ("mrs %0, " #_reg_name : "=r" (v)); \ + return v; \ +} + #define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) \ static inline void write_ ## _name(u_register_t v) \ { \ @@ -58,6 +66,14 @@ static inline void write_ ## _name(u_register_t v) \ #define DEFINE_RENAME_SYSREG_WRITE_FUNC(_name, _reg_name) \ _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) +/* Define read function for ID register (w/o volatile qualifier) */ +#define DEFINE_IDREG_READ_FUNC(_name) \ + _DEFINE_SYSREG_READ_FUNC_NV(_name, _name) + +/* Define read function for renamed ID register (w/o volatile qualifier) */ +#define DEFINE_RENAME_IDREG_READ_FUNC(_name, _reg_name) \ + _DEFINE_SYSREG_READ_FUNC_NV(_name, _reg_name) + /********************************************************************** * Macros to create inline functions for system instructions *********************************************************************/ @@ -247,14 +263,14 @@ void disable_mpu_icache_el2(void); #define write_daifset(val) SYSREG_WRITE_CONST(daifset, val) DEFINE_SYSREG_RW_FUNCS(par_el1) -DEFINE_SYSREG_READ_FUNC(id_pfr1_el1) -DEFINE_SYSREG_READ_FUNC(id_aa64isar0_el1) -DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1) -DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64isar2_el1, ID_AA64ISAR2_EL1) -DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1) -DEFINE_SYSREG_READ_FUNC(id_aa64pfr1_el1) -DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1) -DEFINE_SYSREG_READ_FUNC(id_afr0_el1) +DEFINE_IDREG_READ_FUNC(id_pfr1_el1) +DEFINE_IDREG_READ_FUNC(id_aa64isar0_el1) +DEFINE_IDREG_READ_FUNC(id_aa64isar1_el1) +DEFINE_RENAME_IDREG_READ_FUNC(id_aa64isar2_el1, ID_AA64ISAR2_EL1) +DEFINE_IDREG_READ_FUNC(id_aa64pfr0_el1) +DEFINE_IDREG_READ_FUNC(id_aa64pfr1_el1) +DEFINE_IDREG_READ_FUNC(id_aa64dfr0_el1) +DEFINE_IDREG_READ_FUNC(id_afr0_el1) DEFINE_SYSREG_READ_FUNC(CurrentEl) DEFINE_SYSREG_READ_FUNC(ctr_el0) DEFINE_SYSREG_RW_FUNCS(daif) @@ -367,10 +383,10 @@ void __dead2 smc(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, /******************************************************************************* * System register accessor prototypes ******************************************************************************/ -DEFINE_SYSREG_READ_FUNC(midr_el1) +DEFINE_IDREG_READ_FUNC(midr_el1) DEFINE_SYSREG_READ_FUNC(mpidr_el1) -DEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1) -DEFINE_SYSREG_READ_FUNC(id_aa64mmfr1_el1) +DEFINE_IDREG_READ_FUNC(id_aa64mmfr0_el1) +DEFINE_IDREG_READ_FUNC(id_aa64mmfr1_el1) DEFINE_SYSREG_RW_FUNCS(scr_el3) DEFINE_SYSREG_RW_FUNCS(hcr_el2) @@ -516,7 +532,7 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(pmblimitr_el1, PMBLIMITR_EL1) DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el3, ZCR_EL3) DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el2, ZCR_EL2) -DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64smfr0_el1, ID_AA64SMFR0_EL1) +DEFINE_RENAME_IDREG_READ_FUNC(id_aa64smfr0_el1, ID_AA64SMFR0_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(smcr_el3, SMCR_EL3) DEFINE_RENAME_SYSREG_READ_FUNC(erridr_el1, ERRIDR_EL1) @@ -530,7 +546,7 @@ DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1) DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1) /* Armv8.2 Registers */ -DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1) +DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1) /* Armv8.3 Pointer Authentication Registers */ DEFINE_RENAME_SYSREG_RW_FUNCS(apiakeyhi_el1, APIAKeyHi_EL1) @@ -549,6 +565,14 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1) DEFINE_RENAME_SYSREG_READ_FUNC(rndr, RNDR) DEFINE_RENAME_SYSREG_READ_FUNC(rndrrs, RNDRRS) +/* Armv8.6 FEAT_FGT Registers */ +DEFINE_RENAME_SYSREG_RW_FUNCS(hdfgrtr_el2, HDFGRTR_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(hafgrtr_el2, HAFGRTR_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(hdfgwtr_el2, HDFGWTR_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(hfgitr_el2, HFGITR_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(hfgrtr_el2, HFGRTR_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(hfgwtr_el2, HFGWTR_EL2) + /* FEAT_HCX Register */ DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2) diff --git a/include/common/feat_detect.h b/include/common/feat_detect.h index 0f0f10596..788dfb31f 100644 --- a/include/common/feat_detect.h +++ b/include/common/feat_detect.h @@ -7,26 +7,12 @@ #ifndef FEAT_DETECT_H #define FEAT_DETECT_H -#include <arch_features.h> -#include <common/debug.h> - /* Function Prototypes */ void detect_arch_features(void); /* Macro Definitions */ -#define FEAT_STATE_1 1 -#define FEAT_STATE_2 2 -#define feat_detect_panic(a, b) ((a) ? (void)0 : feature_panic(b)) - -/******************************************************************************* - * Function : feature_panic - * Customised panic module 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(); -} +#define FEAT_STATE_DISABLED 0 +#define FEAT_STATE_ALWAYS 1 +#define FEAT_STATE_CHECK 2 #endif /* FEAT_DETECT_H */ diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index 6c13166e3..6986e0e51 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -523,10 +523,6 @@ void el2_sysregs_context_restore_mte(el2_sysregs_t *regs); void el2_sysregs_context_save_mpam(el2_sysregs_t *regs); void el2_sysregs_context_restore_mpam(el2_sysregs_t *regs); #endif /* ENABLE_MPAM_FOR_LOWER_ELS */ -#if ENABLE_FEAT_FGT -void el2_sysregs_context_save_fgt(el2_sysregs_t *regs); -void el2_sysregs_context_restore_fgt(el2_sysregs_t *regs); -#endif /* ENABLE_FEAT_FGT */ #if ENABLE_FEAT_ECV void el2_sysregs_context_save_ecv(el2_sysregs_t *regs); void el2_sysregs_context_restore_ecv(el2_sysregs_t *regs); @@ -551,10 +547,6 @@ void el2_sysregs_context_restore_trf(el2_sysregs_t *regs); void el2_sysregs_context_save_csv2(el2_sysregs_t *regs); void el2_sysregs_context_restore_csv2(el2_sysregs_t *regs); #endif /* ENABLE_FEAT_CSV2_2 */ -#if ENABLE_FEAT_HCX -void el2_sysregs_context_save_hcx(el2_sysregs_t *regs); -void el2_sysregs_context_restore_hcx(el2_sysregs_t *regs); -#endif /* ENABLE_FEAT_HCX */ #endif /* CTX_INCLUDE_EL2_REGS */ #if CTX_INCLUDE_FPREGS diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index aa0327b51..b5d61ff35 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -25,10 +25,6 @@ .global el2_sysregs_context_save_mpam .global el2_sysregs_context_restore_mpam #endif /* ENABLE_MPAM_FOR_LOWER_ELS */ -#if ENABLE_FEAT_FGT - .global el2_sysregs_context_save_fgt - .global el2_sysregs_context_restore_fgt -#endif /* ENABLE_FEAT_FGT */ #if ENABLE_FEAT_ECV .global el2_sysregs_context_save_ecv .global el2_sysregs_context_restore_ecv @@ -53,10 +49,6 @@ .global el2_sysregs_context_save_csv2 .global el2_sysregs_context_restore_csv2 #endif /* ENABLE_FEAT_CSV2_2 */ -#if ENABLE_FEAT_HCX - .global el2_sysregs_context_save_hcx - .global el2_sysregs_context_restore_hcx -#endif /* ENABLE_FEAT_HCX */ #endif /* CTX_INCLUDE_EL2_REGS */ .global el1_sysregs_context_save @@ -314,45 +306,6 @@ func el2_sysregs_context_restore_mpam endfunc el2_sysregs_context_restore_mpam #endif /* ENABLE_MPAM_FOR_LOWER_ELS */ -#if ENABLE_FEAT_FGT -func el2_sysregs_context_save_fgt - mrs x13, HDFGRTR_EL2 -#if ENABLE_FEAT_AMUv1 - mrs x14, HAFGRTR_EL2 - stp x13, x14, [x0, #CTX_HDFGRTR_EL2] -#else - str x13, [x0, #CTX_HDFGRTR_EL2] -#endif /* ENABLE_FEAT_AMUv1 */ - mrs x15, HDFGWTR_EL2 - mrs x16, HFGITR_EL2 - stp x15, x16, [x0, #CTX_HDFGWTR_EL2] - - mrs x9, HFGRTR_EL2 - mrs x10, HFGWTR_EL2 - stp x9, x10, [x0, #CTX_HFGRTR_EL2] - ret -endfunc el2_sysregs_context_save_fgt - -func el2_sysregs_context_restore_fgt - #if ENABLE_FEAT_AMUv1 - ldp x13, x14, [x0, #CTX_HDFGRTR_EL2] - msr HAFGRTR_EL2, x14 -#else - ldr x13, [x0, #CTX_HDFGRTR_EL2] -#endif /* ENABLE_FEAT_AMUv1 */ - msr HDFGRTR_EL2, x13 - - ldp x15, x16, [x0, #CTX_HDFGWTR_EL2] - msr HDFGWTR_EL2, x15 - msr HFGITR_EL2, x16 - - ldp x9, x10, [x0, #CTX_HFGRTR_EL2] - msr HFGRTR_EL2, x9 - msr HFGWTR_EL2, x10 - ret -endfunc el2_sysregs_context_restore_fgt -#endif /* ENABLE_FEAT_FGT */ - #if ENABLE_FEAT_ECV func el2_sysregs_context_save_ecv mrs x11, CNTPOFF_EL2 @@ -475,19 +428,6 @@ func el2_sysregs_context_restore_csv2 endfunc el2_sysregs_context_restore_csv2 #endif /* ENABLE_FEAT_CSV2_2 */ -#if ENABLE_FEAT_HCX -func el2_sysregs_context_save_hcx - mrs x14, hcrx_el2 - str x14, [x0, #CTX_HCRX_EL2] - ret -endfunc el2_sysregs_context_save_hcx - -func el2_sysregs_context_restore_hcx - ldr x14, [x0, #CTX_HCRX_EL2] - msr hcrx_el2, x14 - ret -endfunc el2_sysregs_context_restore_hcx -#endif /* ENABLE_FEAT_HCX */ #endif /* CTX_INCLUDE_EL2_REGS */ /* ------------------------------------------------------------------ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 866ac4154..3bcefdb5d 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -320,9 +320,9 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e * If FEAT_HCX is enabled, enable access to HCRX_EL2 by setting * SCR_EL3.HXEn. */ -#if ENABLE_FEAT_HCX - scr_el3 |= SCR_HXEn_BIT; -#endif + if (is_feat_hcx_supported()) { + scr_el3 |= SCR_HXEn_BIT; + } /* * If FEAT_RNG_TRAP is enabled, all reads of the RNDR and RNDRRS @@ -359,7 +359,7 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e && (GET_M32(ep->spsr) == MODE32_hyp))) { scr_el3 |= SCR_HCE_BIT; - if (is_armv8_6_fgt_present()) { + if (is_feat_fgt_supported()) { scr_el3 |= SCR_FGTEN_BIT; } @@ -792,6 +792,35 @@ void cm_prepare_el3_exit(uint32_t security_state) } #if CTX_INCLUDE_EL2_REGS + +static void el2_sysregs_context_save_fgt(el2_sysregs_t *ctx) +{ + if (is_feat_fgt_supported()) { + write_ctx_reg(ctx, CTX_HDFGRTR_EL2, read_hdfgrtr_el2()); + if (is_feat_amu_supported()) { + write_ctx_reg(ctx, CTX_HAFGRTR_EL2, read_hafgrtr_el2()); + } + write_ctx_reg(ctx, CTX_HDFGWTR_EL2, read_hdfgwtr_el2()); + write_ctx_reg(ctx, CTX_HFGITR_EL2, read_hfgitr_el2()); + write_ctx_reg(ctx, CTX_HFGRTR_EL2, read_hfgrtr_el2()); + write_ctx_reg(ctx, CTX_HFGWTR_EL2, read_hfgwtr_el2()); + } +} + +static void el2_sysregs_context_restore_fgt(el2_sysregs_t *ctx) +{ + if (is_feat_fgt_supported()) { + write_hdfgrtr_el2(read_ctx_reg(ctx, CTX_HDFGRTR_EL2)); + if (is_feat_amu_supported()) { + write_hafgrtr_el2(read_ctx_reg(ctx, CTX_HAFGRTR_EL2)); + } + write_hdfgwtr_el2(read_ctx_reg(ctx, CTX_HDFGWTR_EL2)); + write_hfgitr_el2(read_ctx_reg(ctx, CTX_HFGITR_EL2)); + write_hfgrtr_el2(read_ctx_reg(ctx, CTX_HFGRTR_EL2)); + write_hfgwtr_el2(read_ctx_reg(ctx, CTX_HFGWTR_EL2)); + } +} + /******************************************************************************* * Save EL2 sysreg context ******************************************************************************/ @@ -823,9 +852,9 @@ void cm_el2_sysregs_context_save(uint32_t security_state) #if ENABLE_MPAM_FOR_LOWER_ELS el2_sysregs_context_save_mpam(el2_sysregs_ctx); #endif -#if ENABLE_FEAT_FGT + el2_sysregs_context_save_fgt(el2_sysregs_ctx); -#endif + #if ENABLE_FEAT_ECV el2_sysregs_context_save_ecv(el2_sysregs_ctx); #endif @@ -844,9 +873,9 @@ void cm_el2_sysregs_context_save(uint32_t security_state) #if ENABLE_FEAT_CSV2_2 el2_sysregs_context_save_csv2(el2_sysregs_ctx); #endif -#if ENABLE_FEAT_HCX - el2_sysregs_context_save_hcx(el2_sysregs_ctx); -#endif + if (is_feat_hcx_supported()) { + write_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2, read_hcrx_el2()); + } } } @@ -881,9 +910,9 @@ void cm_el2_sysregs_context_restore(uint32_t security_state) #if ENABLE_MPAM_FOR_LOWER_ELS el2_sysregs_context_restore_mpam(el2_sysregs_ctx); #endif -#if ENABLE_FEAT_FGT + el2_sysregs_context_restore_fgt(el2_sysregs_ctx); -#endif + #if ENABLE_FEAT_ECV el2_sysregs_context_restore_ecv(el2_sysregs_ctx); #endif @@ -902,9 +931,9 @@ void cm_el2_sysregs_context_restore(uint32_t security_state) #if ENABLE_FEAT_CSV2_2 el2_sysregs_context_restore_csv2(el2_sysregs_ctx); #endif -#if ENABLE_FEAT_HCX - el2_sysregs_context_restore_hcx(el2_sysregs_ctx); -#endif + if (is_feat_hcx_supported()) { + write_hcrx_el2(read_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2)); + } } } #endif /* CTX_INCLUDE_EL2_REGS */ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index f28a6ff75..efbf68f00 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -463,6 +463,10 @@ ENABLE_SYS_REG_TRACE_FOR_NS := 1 # enable trace filter control registers access to NS by default ENABLE_TRF_FOR_NS := 1 +# Linux relies on EL3 enablement if those features are present +ENABLE_FEAT_FGT := 2 +ENABLE_FEAT_HCX := 2 + ifeq (${SPMC_AT_EL3}, 1) PLAT_BL_COMMON_SOURCES += plat/arm/board/fvp/fvp_el3_spmc.c endif diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c index 5f1b7aa1d..ae361e973 100644 --- a/plat/qti/common/src/qti_pm.c +++ b/plat/qti/common/src/qti_pm.c @@ -47,8 +47,7 @@ #define QTI_CORE_PWRDN_EN_MASK 1 /* cpu power control happens to be same across all CPUs */ -_DEFINE_SYSREG_WRITE_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7) -_DEFINE_SYSREG_READ_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7) +DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val, S3_0_C15_C2_7) const unsigned int qti_pm_idle_states[] = { qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_OFF, |