mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-08 05:43:53 +00:00
feat(the): add support for FEAT_THE
Arm v8.9 introduces FEAT_THE, adding Translation Hardening Extension Read-Check-Write mask registers, RCWMASK_EL1 and RCWSMASK_EL1. Support this, context switching the registers and disabling traps so lower ELs can access the new registers. Change the FVP platform to default to handling this as a dynamic option so the right decision can be made by the code at runtime. Change-Id: I8775787f523639b39faf61d046ef482f73b2a562 Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com> Signed-off-by: Govindraj Raja <govindraj.raja@arm.com>
This commit is contained in:
parent
75b0d5756f
commit
6d0433f040
10 changed files with 85 additions and 0 deletions
2
Makefile
2
Makefile
|
@ -1263,6 +1263,7 @@ $(eval $(call assert_numerics,\
|
|||
ENABLE_FEAT_RNG_TRAP \
|
||||
ENABLE_FEAT_SEL2 \
|
||||
ENABLE_FEAT_TCR2 \
|
||||
ENABLE_FEAT_THE \
|
||||
ENABLE_FEAT_SB \
|
||||
ENABLE_FEAT_S2PIE \
|
||||
ENABLE_FEAT_S1PIE \
|
||||
|
@ -1419,6 +1420,7 @@ $(eval $(call add_defines,\
|
|||
ENABLE_FEAT_CSV2_3 \
|
||||
ENABLE_FEAT_PAN \
|
||||
ENABLE_FEAT_TCR2 \
|
||||
ENABLE_FEAT_THE \
|
||||
ENABLE_FEAT_S2PIE \
|
||||
ENABLE_FEAT_S1PIE \
|
||||
ENABLE_FEAT_S2POE \
|
||||
|
|
|
@ -257,6 +257,12 @@ static unsigned int read_feat_mtpmu_id_field(void)
|
|||
|
||||
}
|
||||
|
||||
static unsigned int read_feat_the_id_field(void)
|
||||
{
|
||||
return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_THE_SHIFT,
|
||||
ID_AA64PFR1_EL1_THE_MASK);
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
* TF-A supports many Arm architectural features starting from arch version
|
||||
* (8.0 till 8.7+). These features are mostly enabled through build flags. This
|
||||
|
@ -365,6 +371,8 @@ void detect_arch_features(void)
|
|||
"CSV2_3", 3, 3);
|
||||
check_feature(ENABLE_FEAT_DEBUGV8P9, read_feat_debugv8p9_id_field(),
|
||||
"DEBUGV8P9", 11, 11);
|
||||
check_feature(ENABLE_FEAT_THE, read_feat_the_id_field(),
|
||||
"THE", 1, 1);
|
||||
|
||||
/* v9.0 features */
|
||||
check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
|
||||
|
|
|
@ -455,6 +455,14 @@ Common build options
|
|||
the values 0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
|
||||
Default value is ``0``.
|
||||
|
||||
- ``ENABLE_FEAT_THE``: Numeric value to enable support for FEAT_THE
|
||||
(Translation Hardening Extension) at EL2 and below, setting the bit
|
||||
SCR_EL3.RCWMASKEn in EL3 to allow access to RCWMASK_EL1 and RCWSMASK_EL1
|
||||
registers and context switch them.
|
||||
Its an optional architectural feature and is available from v8.8 and upwards.
|
||||
This flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
|
||||
mechanism. Default value is ``0``.
|
||||
|
||||
- ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
|
||||
support in GCC for TF-A. This option is currently only supported for
|
||||
AArch64. Default is 0.
|
||||
|
|
|
@ -433,6 +433,10 @@
|
|||
#define ID_AA64PFR1_EL1_GCS_MASK ULL(0xf)
|
||||
#define GCS_IMPLEMENTED ULL(1)
|
||||
|
||||
#define ID_AA64PFR1_EL1_THE_SHIFT U(48)
|
||||
#define ID_AA64PFR1_EL1_THE_MASK ULL(0xf)
|
||||
#define THE_IMPLEMENTED ULL(1)
|
||||
|
||||
#define RNG_TRAP_IMPLEMENTED ULL(0x1)
|
||||
|
||||
/* ID_AA64PFR2_EL1 definitions */
|
||||
|
@ -590,6 +594,7 @@
|
|||
#define SCR_TWEDEL_MASK ULL(0xf)
|
||||
#define SCR_PIEN_BIT (UL(1) << 45)
|
||||
#define SCR_TCR2EN_BIT (UL(1) << 43)
|
||||
#define SCR_RCWMASKEn_BIT (UL(1) << 42)
|
||||
#define SCR_TRNDR_BIT (UL(1) << 40)
|
||||
#define SCR_GCSEn_BIT (UL(1) << 39)
|
||||
#define SCR_HXEn_BIT (UL(1) << 38)
|
||||
|
@ -1472,6 +1477,12 @@
|
|||
#define TRFCR_EL2 S3_4_C1_C2_1
|
||||
#define TRFCR_EL1 S3_0_C1_C2_1
|
||||
|
||||
/*******************************************************************************
|
||||
* FEAT_THE - Translation Hardening Extension Registers
|
||||
******************************************************************************/
|
||||
#define RCWMASK_EL1 S3_0_C13_C0_6
|
||||
#define RCWSMASK_EL1 S3_0_C13_C0_3
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions for DynamicIQ Shared Unit registers
|
||||
******************************************************************************/
|
||||
|
|
|
@ -134,6 +134,8 @@ CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard)
|
|||
* +----------------------------+
|
||||
* | FEAT_FGT2 |
|
||||
* +----------------------------+
|
||||
* | FEAT_THE |
|
||||
* +----------------------------+
|
||||
*/
|
||||
|
||||
__attribute__((always_inline))
|
||||
|
@ -262,6 +264,10 @@ CREATE_FEATURE_FUNCS(feat_s2pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S2PIE_SHIFT,
|
|||
CREATE_FEATURE_FUNCS(feat_s1pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1PIE_SHIFT,
|
||||
ID_AA64MMFR3_EL1_S1PIE_MASK, 1U, ENABLE_FEAT_S1PIE)
|
||||
|
||||
/* FEAT_THE: Translation Hardening Extension */
|
||||
CREATE_FEATURE_FUNCS(feat_the, id_aa64pfr1_el1, ID_AA64PFR1_EL1_THE_SHIFT,
|
||||
ID_AA64PFR1_EL1_THE_MASK, THE_IMPLEMENTED, ENABLE_FEAT_THE)
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline bool is_feat_sxpie_supported(void)
|
||||
{
|
||||
|
|
|
@ -670,6 +670,10 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(gcscre0_el1, GCSCRE0_EL1)
|
|||
DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el1, GCSPR_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(gcspr_el0, GCSPR_EL0)
|
||||
|
||||
/* FEAT_THE Registers */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(rcwmask_el1, RCWMASK_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(rcwsmask_el1, RCWSMASK_EL1)
|
||||
|
||||
/* DynamIQ Control registers */
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmcr_el1, CLUSTERPMCR_EL1)
|
||||
|
|
|
@ -107,6 +107,11 @@ typedef struct el1_gcs_regs {
|
|||
uint64_t gcspr_el0;
|
||||
} el1_gcs_regs_t;
|
||||
|
||||
typedef struct el1_the_regs {
|
||||
uint64_t rcwmask_el1;
|
||||
uint64_t rcwsmask_el1;
|
||||
} el1_the_regs_t;
|
||||
|
||||
typedef struct el1_sysregs {
|
||||
|
||||
el1_common_regs_t common;
|
||||
|
@ -155,6 +160,10 @@ typedef struct el1_sysregs {
|
|||
el1_gcs_regs_t gcs;
|
||||
#endif
|
||||
|
||||
#if ENABLE_FEAT_THE
|
||||
el1_the_regs_t the;
|
||||
#endif
|
||||
|
||||
} el1_sysregs_t;
|
||||
|
||||
|
||||
|
@ -266,6 +275,16 @@ typedef struct el1_sysregs {
|
|||
#define read_el1_ctx_gcs(ctx, reg) ULL(0)
|
||||
#define write_el1_ctx_gcs(ctx, reg, val)
|
||||
#endif /* ENABLE_FEAT_GCS */
|
||||
|
||||
#if ENABLE_FEAT_THE
|
||||
#define read_el1_ctx_the(ctx, reg) (((ctx)->the).reg)
|
||||
#define write_el1_ctx_the(ctx, reg, val) ((((ctx)->the).reg) \
|
||||
= (uint64_t) (val))
|
||||
#else
|
||||
#define read_el1_ctx_the(ctx, reg) ULL(0)
|
||||
#define write_el1_ctx_the(ctx, reg, val)
|
||||
#endif /* ENABLE_FEAT_THE */
|
||||
|
||||
/******************************************************************************/
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
|
|
|
@ -260,6 +260,14 @@ static void setup_ns_context(cpu_context_t *ctx, const struct entry_point_info *
|
|||
*/
|
||||
scr_el3 |= get_scr_el3_from_routing_model(NON_SECURE);
|
||||
#endif
|
||||
|
||||
if (is_feat_the_supported()) {
|
||||
/* Set the RCWMASKEn bit in SCR_EL3 to enable access to
|
||||
* RCWMASK_EL1 and RCWSMASK_EL1 registers.
|
||||
*/
|
||||
scr_el3 |= SCR_RCWMASKEn_BIT;
|
||||
}
|
||||
|
||||
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
|
||||
|
||||
/* Initialize EL2 context registers */
|
||||
|
@ -1712,6 +1720,12 @@ static void el1_sysregs_context_save(el1_sysregs_t *ctx)
|
|||
write_el1_ctx_gcs(ctx, gcspr_el1, read_gcspr_el1());
|
||||
write_el1_ctx_gcs(ctx, gcspr_el0, read_gcspr_el0());
|
||||
}
|
||||
|
||||
if (is_feat_the_supported()) {
|
||||
write_el1_ctx_the(ctx, rcwmask_el1, read_rcwmask_el1());
|
||||
write_el1_ctx_the(ctx, rcwsmask_el1, read_rcwsmask_el1());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void el1_sysregs_context_restore(el1_sysregs_t *ctx)
|
||||
|
@ -1807,6 +1821,11 @@ static void el1_sysregs_context_restore(el1_sysregs_t *ctx)
|
|||
write_gcspr_el1(read_el1_ctx_gcs(ctx, gcspr_el1));
|
||||
write_gcspr_el0(read_el1_ctx_gcs(ctx, gcspr_el0));
|
||||
}
|
||||
|
||||
if (is_feat_the_supported()) {
|
||||
write_rcwmask_el1(read_el1_ctx_the(ctx, rcwmask_el1));
|
||||
write_rcwsmask_el1(read_el1_ctx_the(ctx, rcwsmask_el1));
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -340,6 +340,13 @@ DISABLE_MTPMU ?= 0
|
|||
# Flag to enable FEAT_FGT2 (Fine Granular Traps 2)
|
||||
ENABLE_FEAT_FGT2 ?= 0
|
||||
|
||||
#----
|
||||
# 8.8
|
||||
#----
|
||||
|
||||
# Flag to enable FEAT_THE (Translation Hardening Extension)
|
||||
ENABLE_FEAT_THE ?= 0
|
||||
|
||||
#----
|
||||
# 8.9
|
||||
#----
|
||||
|
|
|
@ -71,6 +71,7 @@ ENABLE_TRF_FOR_NS := 2
|
|||
ENABLE_FEAT_ECV := 2
|
||||
ENABLE_FEAT_FGT := 2
|
||||
ENABLE_FEAT_FGT2 := 2
|
||||
ENABLE_FEAT_THE := 2
|
||||
ENABLE_FEAT_TCR2 := 2
|
||||
ENABLE_FEAT_S2PIE := 2
|
||||
ENABLE_FEAT_S1PIE := 2
|
||||
|
|
Loading…
Add table
Reference in a new issue