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
This commit is contained in:
Manish Pandey 2023-01-19 18:19:50 +01:00 committed by TrustedFirmware Code Review
commit 344e5e8149
11 changed files with 217 additions and 199 deletions

View file

@ -93,15 +93,6 @@ void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
/* Perform late platform-specific setup */ /* Perform late platform-specific setup */
bl31_plat_arch_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 #if CTX_INCLUDE_PAUTH_REGS
/* /*
* Assert that the ARMv8.3-PAuth registers are present or an access * Assert that the ARMv8.3-PAuth registers are present or an access

View file

@ -101,6 +101,9 @@ subsections:
- title: Extended Cache Index (FEAT_CCIDX) - title: Extended Cache Index (FEAT_CCIDX)
scope: ccidx scope: ccidx
- title: CPU feature / ID register handling in general
scope: cpufeat
- title: Support for the `HCRX_EL2` register (FEAT_HCX) - title: Support for the `HCRX_EL2` register (FEAT_HCX)
scope: hcx scope: hcx

View file

@ -4,24 +4,59 @@
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include <arch_features.h>
#include <common/debug.h>
#include <common/feat_detect.h> #include <common/feat_detect.h>
static bool tainted;
/******************************************************************************* /*******************************************************************************
* This section lists the wrapper modules for each feature to evaluate the * 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 * feature states (FEAT_STATE_ALWAYS and FEAT_STATE_CHECK) and perform
* as below: * necessary action as below:
* *
* It verifies whether the FEAT_XXX (eg: FEAT_SB) is supported by the PE or not. * 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 * Without this check an exception would occur during context save/restore
* routines, if the feature is enabled but not supported by PE. * 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) * Feature : FEAT_SB (Speculation Barrier)
*****************************************/ *****************************************/
static void read_feat_sb(void) 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"); feat_detect_panic(is_armv8_0_feat_sb_present(), "SB");
#endif #endif
} }
@ -31,7 +66,7 @@ static void read_feat_sb(void)
*****************************************************/ *****************************************************/
static void read_feat_csv2_2(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"); feat_detect_panic(is_armv8_0_feat_csv2_2_present(), "CSV2_2");
#endif #endif
} }
@ -41,7 +76,7 @@ static void read_feat_csv2_2(void)
**********************************************/ **********************************************/
static void read_feat_pan(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"); feat_detect_panic(is_armv8_1_pan_present(), "PAN");
#endif #endif
} }
@ -51,7 +86,7 @@ static void read_feat_pan(void)
*****************************************************/ *****************************************************/
static void read_feat_vhe(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"); feat_detect_panic(is_armv8_1_vhe_present(), "VHE");
#endif #endif
} }
@ -61,7 +96,7 @@ static void read_feat_vhe(void)
******************************************************************************/ ******************************************************************************/
static void read_feat_ras(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"); feat_detect_panic(is_armv8_2_feat_ras_present(), "RAS");
#endif #endif
} }
@ -71,7 +106,7 @@ static void read_feat_ras(void)
***********************************************/ ***********************************************/
static void read_feat_pauth(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"); feat_detect_panic(is_armv8_3_pauth_present(), "PAUTH");
#endif #endif
} }
@ -81,27 +116,17 @@ static void read_feat_pauth(void)
***********************************************************/ ***********************************************************/
static void read_feat_dit(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"); feat_detect_panic(is_armv8_4_feat_dit_present(), "DIT");
#endif #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) * Feature : FEAT_MPAM (Memory Partitioning and Monitoring (MPAM) Extension)
***************************************************************************/ ***************************************************************************/
static void read_feat_mpam(void) 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"); feat_detect_panic(get_mpam_version() != 0U, "MPAM");
#endif #endif
} }
@ -111,7 +136,7 @@ static void read_feat_mpam(void)
*************************************************************/ *************************************************************/
static void read_feat_nv2(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(); unsigned int nv = get_armv8_4_feat_nv_support();
feat_detect_panic((nv == ID_AA64MMFR2_EL1_NV2_SUPPORTED), "NV2"); 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) 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"); feat_detect_panic(is_armv8_4_sel2_present(), "SEL2");
#endif #endif
} }
@ -133,7 +158,7 @@ static void read_feat_sel2(void)
***************************************************/ ***************************************************/
static void read_feat_trf(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"); feat_detect_panic(is_arm8_4_feat_trf_present(), "TRF");
#endif #endif
} }
@ -143,7 +168,7 @@ static void read_feat_trf(void)
***********************************************/ ***********************************************/
static void read_feat_mte(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(); unsigned int mte = get_armv8_5_mte_support();
feat_detect_panic((mte != MTE_UNIMPLEMENTED), "MTE"); feat_detect_panic((mte != MTE_UNIMPLEMENTED), "MTE");
@ -155,7 +180,7 @@ static void read_feat_mte(void)
**********************************************/ **********************************************/
static void read_feat_rng(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"); feat_detect_panic(is_armv8_5_rng_present(), "RNG");
#endif #endif
} }
@ -165,27 +190,17 @@ static void read_feat_rng(void)
***************************************************/ ***************************************************/
static void read_feat_bti(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"); feat_detect_panic(is_armv8_5_bti_present(), "BTI");
#endif #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) * Feature : FEAT_AMUv1p1 (AMU Extensions v1.1)
**********************************************/ **********************************************/
static void read_feat_amuv1p1(void) 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"); feat_detect_panic(is_armv8_6_feat_amuv1p1_present(), "AMUv1p1");
#endif #endif
} }
@ -195,7 +210,7 @@ static void read_feat_amuv1p1(void)
******************************************************/ ******************************************************/
static void read_feat_ecv(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(); unsigned int ecv = get_armv8_6_ecv_support();
feat_detect_panic(((ecv == ID_AA64MMFR0_EL1_ECV_SUPPORTED) || 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) 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"); feat_detect_panic(is_armv8_6_twed_present(), "TWED");
#endif #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) * Feature : FEAT_RME (Realm Management Extension)
*************************************************/ *************************************************/
static void read_feat_rme(void) 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() != feat_detect_panic((get_armv9_2_feat_rme_support() !=
ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED), "RME"); ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED), "RME");
#endif #endif
@ -239,7 +244,7 @@ static void read_feat_rme(void)
*****************************************************/ *****************************************************/
static void read_feat_brbe(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"); feat_detect_panic(is_feat_brbe_present(), "BRBE");
#endif #endif
} }
@ -249,7 +254,7 @@ static void read_feat_brbe(void)
*****************************************************/ *****************************************************/
static void read_feat_trbe(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"); feat_detect_panic(is_feat_trbe_present(), "TRBE");
#endif #endif
} }
@ -259,7 +264,7 @@ static void read_feat_trbe(void)
*****************************************************************/ *****************************************************************/
static void read_feat_rng_trap(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"); feat_detect_panic(is_feat_rng_trap_present(), "RNG_TRAP");
#endif #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 * ENABLE_FEAT_xxx = 2 : The feature is enabled but dynamically enabled at runtime
* depending on hardware capability. * depending on hardware capability.
* *
* For better readability, state values are defined with macros namely: * For better readability, state values are defined with macros, namely:
* { FEAT_STATE_0, FEAT_STATE_1, FEAT_STATE_2 } taking values as their naming. * { FEAT_STATE_DISABLED, FEAT_STATE_ALWAYS, FEAT_STATE_CHECK }, taking values
* { 0, 1, 2 }, respectively, as their naming.
**********************************************************************************/ **********************************************************************************/
void detect_arch_features(void) void detect_arch_features(void)
{ {
tainted = false;
/* v8.0 features */ /* v8.0 features */
read_feat_sb(); read_feat_sb();
read_feat_csv2_2(); read_feat_csv2_2();
@ -304,7 +312,7 @@ void detect_arch_features(void)
/* v8.4 features */ /* v8.4 features */
read_feat_dit(); read_feat_dit();
read_feat_amuv1(); check_feature(ENABLE_FEAT_AMUv1, read_feat_amu_id_field(), "AMUv1");
read_feat_mpam(); read_feat_mpam();
read_feat_nv2(); read_feat_nv2();
read_feat_sel2(); read_feat_sel2();
@ -318,12 +326,12 @@ void detect_arch_features(void)
/* v8.6 features */ /* v8.6 features */
read_feat_amuv1p1(); read_feat_amuv1p1();
read_feat_fgt(); check_feature(ENABLE_FEAT_FGT, read_feat_fgt_id_field(), "FGT");
read_feat_ecv(); read_feat_ecv();
read_feat_twed(); read_feat_twed();
/* v8.7 features */ /* v8.7 features */
read_feat_hcx(); check_feature(ENABLE_FEAT_HCX, read_feat_hcx_id_field(), "HCX");
/* v9.0 features */ /* v9.0 features */
read_feat_brbe(); read_feat_brbe();
@ -331,4 +339,8 @@ void detect_arch_features(void)
/* v9.2 features */ /* v9.2 features */
read_feat_rme(); read_feat_rme();
if (tainted) {
panic();
}
} }

View file

@ -10,6 +10,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <arch_helpers.h> #include <arch_helpers.h>
#include <common/feat_detect.h>
static inline bool is_armv7_gentimer_present(void) 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); 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) & return (read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_FGT_SHIFT) &
ID_AA64MMFR0_EL1_FGT_MASK) != 0U; 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) 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); 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) static inline bool is_armv8_6_feat_amuv1p1_present(void)
{ {
return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) & return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1P1;
ID_AA64PFR0_AMU_MASK) >= 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)); 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) & return (read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) &
ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED); ID_AA64MMFR1_EL1_HCX_MASK;
}
static inline bool is_feat_hcx_supported(void)
{
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) 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); 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 * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization
* Support) * Support)

View file

@ -27,6 +27,14 @@ static inline u_register_t read_ ## _name(void) \
return v; \ 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) \ #define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) \
static inline void write_ ## _name(u_register_t v) \ 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 DEFINE_RENAME_SYSREG_WRITE_FUNC(_name, _reg_name) \
_DEFINE_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 * 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 write_daifset(val) SYSREG_WRITE_CONST(daifset, val)
DEFINE_SYSREG_RW_FUNCS(par_el1) DEFINE_SYSREG_RW_FUNCS(par_el1)
DEFINE_SYSREG_READ_FUNC(id_pfr1_el1) DEFINE_IDREG_READ_FUNC(id_pfr1_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64isar0_el1) DEFINE_IDREG_READ_FUNC(id_aa64isar0_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1) DEFINE_IDREG_READ_FUNC(id_aa64isar1_el1)
DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64isar2_el1, ID_AA64ISAR2_EL1) DEFINE_RENAME_IDREG_READ_FUNC(id_aa64isar2_el1, ID_AA64ISAR2_EL1)
DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1) DEFINE_IDREG_READ_FUNC(id_aa64pfr0_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64pfr1_el1) DEFINE_IDREG_READ_FUNC(id_aa64pfr1_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1) DEFINE_IDREG_READ_FUNC(id_aa64dfr0_el1)
DEFINE_SYSREG_READ_FUNC(id_afr0_el1) DEFINE_IDREG_READ_FUNC(id_afr0_el1)
DEFINE_SYSREG_READ_FUNC(CurrentEl) DEFINE_SYSREG_READ_FUNC(CurrentEl)
DEFINE_SYSREG_READ_FUNC(ctr_el0) DEFINE_SYSREG_READ_FUNC(ctr_el0)
DEFINE_SYSREG_RW_FUNCS(daif) 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 * 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(mpidr_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64mmfr0_el1) DEFINE_IDREG_READ_FUNC(id_aa64mmfr0_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64mmfr1_el1) DEFINE_IDREG_READ_FUNC(id_aa64mmfr1_el1)
DEFINE_SYSREG_RW_FUNCS(scr_el3) DEFINE_SYSREG_RW_FUNCS(scr_el3)
DEFINE_SYSREG_RW_FUNCS(hcr_el2) 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_el3, ZCR_EL3)
DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el2, ZCR_EL2) 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_RW_FUNCS(smcr_el3, SMCR_EL3)
DEFINE_RENAME_SYSREG_READ_FUNC(erridr_el1, ERRIDR_EL1) 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) DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
/* Armv8.2 Registers */ /* 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 */ /* Armv8.3 Pointer Authentication Registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(apiakeyhi_el1, APIAKeyHi_EL1) 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(rndr, RNDR)
DEFINE_RENAME_SYSREG_READ_FUNC(rndrrs, RNDRRS) 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 */ /* FEAT_HCX Register */
DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2) DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2)

View file

@ -7,26 +7,12 @@
#ifndef FEAT_DETECT_H #ifndef FEAT_DETECT_H
#define FEAT_DETECT_H #define FEAT_DETECT_H
#include <arch_features.h>
#include <common/debug.h>
/* Function Prototypes */ /* Function Prototypes */
void detect_arch_features(void); void detect_arch_features(void);
/* Macro Definitions */ /* Macro Definitions */
#define FEAT_STATE_1 1 #define FEAT_STATE_DISABLED 0
#define FEAT_STATE_2 2 #define FEAT_STATE_ALWAYS 1
#define feat_detect_panic(a, b) ((a) ? (void)0 : feature_panic(b)) #define FEAT_STATE_CHECK 2
/*******************************************************************************
* 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();
}
#endif /* FEAT_DETECT_H */ #endif /* FEAT_DETECT_H */

View file

@ -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_save_mpam(el2_sysregs_t *regs);
void el2_sysregs_context_restore_mpam(el2_sysregs_t *regs); void el2_sysregs_context_restore_mpam(el2_sysregs_t *regs);
#endif /* ENABLE_MPAM_FOR_LOWER_ELS */ #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 #if ENABLE_FEAT_ECV
void el2_sysregs_context_save_ecv(el2_sysregs_t *regs); void el2_sysregs_context_save_ecv(el2_sysregs_t *regs);
void el2_sysregs_context_restore_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_save_csv2(el2_sysregs_t *regs);
void el2_sysregs_context_restore_csv2(el2_sysregs_t *regs); void el2_sysregs_context_restore_csv2(el2_sysregs_t *regs);
#endif /* ENABLE_FEAT_CSV2_2 */ #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 */ #endif /* CTX_INCLUDE_EL2_REGS */
#if CTX_INCLUDE_FPREGS #if CTX_INCLUDE_FPREGS

View file

@ -25,10 +25,6 @@
.global el2_sysregs_context_save_mpam .global el2_sysregs_context_save_mpam
.global el2_sysregs_context_restore_mpam .global el2_sysregs_context_restore_mpam
#endif /* ENABLE_MPAM_FOR_LOWER_ELS */ #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 #if ENABLE_FEAT_ECV
.global el2_sysregs_context_save_ecv .global el2_sysregs_context_save_ecv
.global el2_sysregs_context_restore_ecv .global el2_sysregs_context_restore_ecv
@ -53,10 +49,6 @@
.global el2_sysregs_context_save_csv2 .global el2_sysregs_context_save_csv2
.global el2_sysregs_context_restore_csv2 .global el2_sysregs_context_restore_csv2
#endif /* ENABLE_FEAT_CSV2_2 */ #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 */ #endif /* CTX_INCLUDE_EL2_REGS */
.global el1_sysregs_context_save .global el1_sysregs_context_save
@ -314,45 +306,6 @@ func el2_sysregs_context_restore_mpam
endfunc el2_sysregs_context_restore_mpam endfunc el2_sysregs_context_restore_mpam
#endif /* ENABLE_MPAM_FOR_LOWER_ELS */ #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 #if ENABLE_FEAT_ECV
func el2_sysregs_context_save_ecv func el2_sysregs_context_save_ecv
mrs x11, CNTPOFF_EL2 mrs x11, CNTPOFF_EL2
@ -475,19 +428,6 @@ func el2_sysregs_context_restore_csv2
endfunc el2_sysregs_context_restore_csv2 endfunc el2_sysregs_context_restore_csv2
#endif /* ENABLE_FEAT_CSV2_2 */ #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 */ #endif /* CTX_INCLUDE_EL2_REGS */
/* ------------------------------------------------------------------ /* ------------------------------------------------------------------

View file

@ -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 * If FEAT_HCX is enabled, enable access to HCRX_EL2 by setting
* SCR_EL3.HXEn. * SCR_EL3.HXEn.
*/ */
#if ENABLE_FEAT_HCX if (is_feat_hcx_supported()) {
scr_el3 |= SCR_HXEn_BIT; scr_el3 |= SCR_HXEn_BIT;
#endif }
/* /*
* If FEAT_RNG_TRAP is enabled, all reads of the RNDR and RNDRRS * 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))) { && (GET_M32(ep->spsr) == MODE32_hyp))) {
scr_el3 |= SCR_HCE_BIT; scr_el3 |= SCR_HCE_BIT;
if (is_armv8_6_fgt_present()) { if (is_feat_fgt_supported()) {
scr_el3 |= SCR_FGTEN_BIT; scr_el3 |= SCR_FGTEN_BIT;
} }
@ -792,6 +792,35 @@ void cm_prepare_el3_exit(uint32_t security_state)
} }
#if CTX_INCLUDE_EL2_REGS #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 * Save EL2 sysreg context
******************************************************************************/ ******************************************************************************/
@ -823,9 +852,9 @@ void cm_el2_sysregs_context_save(uint32_t security_state)
#if ENABLE_MPAM_FOR_LOWER_ELS #if ENABLE_MPAM_FOR_LOWER_ELS
el2_sysregs_context_save_mpam(el2_sysregs_ctx); el2_sysregs_context_save_mpam(el2_sysregs_ctx);
#endif #endif
#if ENABLE_FEAT_FGT
el2_sysregs_context_save_fgt(el2_sysregs_ctx); el2_sysregs_context_save_fgt(el2_sysregs_ctx);
#endif
#if ENABLE_FEAT_ECV #if ENABLE_FEAT_ECV
el2_sysregs_context_save_ecv(el2_sysregs_ctx); el2_sysregs_context_save_ecv(el2_sysregs_ctx);
#endif #endif
@ -844,9 +873,9 @@ void cm_el2_sysregs_context_save(uint32_t security_state)
#if ENABLE_FEAT_CSV2_2 #if ENABLE_FEAT_CSV2_2
el2_sysregs_context_save_csv2(el2_sysregs_ctx); el2_sysregs_context_save_csv2(el2_sysregs_ctx);
#endif #endif
#if ENABLE_FEAT_HCX if (is_feat_hcx_supported()) {
el2_sysregs_context_save_hcx(el2_sysregs_ctx); write_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2, read_hcrx_el2());
#endif }
} }
} }
@ -881,9 +910,9 @@ void cm_el2_sysregs_context_restore(uint32_t security_state)
#if ENABLE_MPAM_FOR_LOWER_ELS #if ENABLE_MPAM_FOR_LOWER_ELS
el2_sysregs_context_restore_mpam(el2_sysregs_ctx); el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
#endif #endif
#if ENABLE_FEAT_FGT
el2_sysregs_context_restore_fgt(el2_sysregs_ctx); el2_sysregs_context_restore_fgt(el2_sysregs_ctx);
#endif
#if ENABLE_FEAT_ECV #if ENABLE_FEAT_ECV
el2_sysregs_context_restore_ecv(el2_sysregs_ctx); el2_sysregs_context_restore_ecv(el2_sysregs_ctx);
#endif #endif
@ -902,9 +931,9 @@ void cm_el2_sysregs_context_restore(uint32_t security_state)
#if ENABLE_FEAT_CSV2_2 #if ENABLE_FEAT_CSV2_2
el2_sysregs_context_restore_csv2(el2_sysregs_ctx); el2_sysregs_context_restore_csv2(el2_sysregs_ctx);
#endif #endif
#if ENABLE_FEAT_HCX if (is_feat_hcx_supported()) {
el2_sysregs_context_restore_hcx(el2_sysregs_ctx); write_hcrx_el2(read_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2));
#endif }
} }
} }
#endif /* CTX_INCLUDE_EL2_REGS */ #endif /* CTX_INCLUDE_EL2_REGS */

View file

@ -463,6 +463,10 @@ ENABLE_SYS_REG_TRACE_FOR_NS := 1
# enable trace filter control registers access to NS by default # enable trace filter control registers access to NS by default
ENABLE_TRF_FOR_NS := 1 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) ifeq (${SPMC_AT_EL3}, 1)
PLAT_BL_COMMON_SOURCES += plat/arm/board/fvp/fvp_el3_spmc.c PLAT_BL_COMMON_SOURCES += plat/arm/board/fvp/fvp_el3_spmc.c
endif endif

View file

@ -47,8 +47,7 @@
#define QTI_CORE_PWRDN_EN_MASK 1 #define QTI_CORE_PWRDN_EN_MASK 1
/* cpu power control happens to be same across all CPUs */ /* cpu power control happens to be same across all CPUs */
_DEFINE_SYSREG_WRITE_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7) DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val, S3_0_C15_C2_7)
_DEFINE_SYSREG_READ_FUNC(cpu_pwrctrl_val, S3_0_C15_C2_7)
const unsigned int qti_pm_idle_states[] = { const unsigned int qti_pm_idle_states[] = {
qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_OFF, qti_make_pwrstate_lvl0(QTI_LOCAL_STATE_OFF,