refactor(cpufeat): enable FEAT_CSV2_2 for FEAT_STATE_CHECKED
At the moment we only support FEAT_CSV2_2 to be either unconditionally
compiled in, or to be not supported at all.
Add support for runtime detection (ENABLE_FEAT_CSV2_2=2), by splitting
is_armv8_0_feat_csv2_2_present() into an ID register reading function
and a second function to report the support status. That function
considers both build time settings and runtime information (if needed),
and is used before we access the SCXTNUM_EL2 system register.
Also move the context saving code from assembly to C, and use the new
is_feat_csv2_2_supported() function to guard its execution.
Change the FVP platform default to the now supported dynamic option (=2),
so the right decision can be made by the code at runtime.
Change-Id: I89c7bc883e6a65727fdbdd36eb3bfbffb2196da7
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 2f64deb..bdadde1 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -60,16 +60,6 @@
}
}
-/******************************************************
- * Feature : FEAT_CSV2_2 (Cache Speculation Variant 2)
- *****************************************************/
-static void read_feat_csv2_2(void)
-{
-#if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS)
- feat_detect_panic(is_armv8_0_feat_csv2_2_present(), "CSV2_2");
-#endif
-}
-
/*******************************************************************************
* Feature : FEAT_RAS (Reliability, Availability, and Serviceability Extension)
******************************************************************************/
@@ -224,7 +214,8 @@
/* v8.0 features */
check_feature(ENABLE_FEAT_SB, read_feat_sb_id_field(), "SB", 1, 1);
- read_feat_csv2_2();
+ check_feature(ENABLE_FEAT_CSV2_2, read_feat_csv2_id_field(),
+ "CSV2_2", 2, 3);
/* v8.1 features */
check_feature(ENABLE_FEAT_PAN, read_feat_pan_id_field(), "PAN", 1, 3);
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 029cdd1..0342d2f 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -301,10 +301,22 @@
/*********************************************************************************
* Function to identify the presence of FEAT_CSV2_2 (Cache Speculation Variant 2)
********************************************************************************/
-static inline bool is_armv8_0_feat_csv2_2_present(void)
+static inline unsigned int read_feat_csv2_id_field(void)
+{
+ return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_CSV2);
+}
+
+static inline bool is_feat_csv2_2_supported(void)
{
- return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_CSV2_SHIFT) &
- ID_AA64PFR0_CSV2_MASK) == ID_AA64PFR0_CSV2_2_SUPPORTED);
+ if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_DISABLED) {
+ return false;
+ }
+
+ if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS) {
+ return true;
+ }
+
+ return read_feat_csv2_id_field() >= ID_AA64PFR0_CSV2_2_SUPPORTED;
}
/**********************************************************************************
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 720f6f3..35027ca 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -540,6 +540,8 @@
DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1)
DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el2, SCXTNUM_EL2)
+
/* Armv8.1 VHE Registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(contextidr_el2, CONTEXTIDR_EL2)
DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2)
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 7d7fb52..e70ff99 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -525,10 +525,6 @@
void el2_sysregs_context_save_nv2(el2_sysregs_t *regs);
void el2_sysregs_context_restore_nv2(el2_sysregs_t *regs);
#endif /* CTX_INCLUDE_NEVE_REGS */
-#if ENABLE_FEAT_CSV2_2
-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 */
#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 baabd3b..7154064 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -25,10 +25,6 @@
.global el2_sysregs_context_save_nv2
.global el2_sysregs_context_restore_nv2
#endif /* CTX_INCLUDE_NEVE_REGS */
-#if ENABLE_FEAT_CSV2_2
- .global el2_sysregs_context_save_csv2
- .global el2_sysregs_context_restore_csv2
-#endif /* ENABLE_FEAT_CSV2_2 */
#endif /* CTX_INCLUDE_EL2_REGS */
.global el1_sysregs_context_save
@@ -262,26 +258,6 @@
endfunc el2_sysregs_context_restore_nv2
#endif /* CTX_INCLUDE_NEVE_REGS */
-#if ENABLE_FEAT_CSV2_2
-func el2_sysregs_context_save_csv2
- /*
- * SCXTNUM_EL2 register is saved only when FEAT_CSV2_2 is supported.
- */
- mrs x13, scxtnum_el2
- str x13, [x0, #CTX_SCXTNUM_EL2]
- ret
-endfunc el2_sysregs_context_save_csv2
-
-func el2_sysregs_context_restore_csv2
- /*
- * SCXTNUM_EL2 register is restored only when FEAT_CSV2_2 is supported.
- */
- ldr x13, [x0, #CTX_SCXTNUM_EL2]
- msr scxtnum_el2, x13
- ret
-endfunc el2_sysregs_context_restore_csv2
-#endif /* ENABLE_FEAT_CSV2_2 */
-
#endif /* CTX_INCLUDE_EL2_REGS */
/* ------------------------------------------------------------------
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index cf4bb30..8430c06 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -171,10 +171,10 @@
scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT;
-#if ENABLE_FEAT_CSV2_2
- /* Enable access to the SCXTNUM_ELx registers. */
- scr_el3 |= SCR_EnSCXT_BIT;
-#endif
+ if (is_feat_csv2_2_supported()) {
+ /* Enable access to the SCXTNUM_ELx registers. */
+ scr_el3 |= SCR_EnSCXT_BIT;
+ }
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
}
@@ -227,10 +227,10 @@
scr_el3 |= SCR_TERR_BIT;
#endif
-#if ENABLE_FEAT_CSV2_2
- /* Enable access to the SCXTNUM_ELx registers. */
- scr_el3 |= SCR_EnSCXT_BIT;
-#endif
+ if (is_feat_csv2_2_supported()) {
+ /* Enable access to the SCXTNUM_ELx registers. */
+ scr_el3 |= SCR_EnSCXT_BIT;
+ }
#ifdef IMAGE_BL31
/*
@@ -976,9 +976,12 @@
if (is_feat_trf_supported()) {
write_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2, read_trfcr_el2());
}
-#if ENABLE_FEAT_CSV2_2
- el2_sysregs_context_save_csv2(el2_sysregs_ctx);
-#endif
+
+ if (is_feat_csv2_2_supported()) {
+ write_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2,
+ read_scxtnum_el2());
+ }
+
if (is_feat_hcx_supported()) {
write_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2, read_hcrx_el2());
}
@@ -1039,9 +1042,12 @@
if (is_feat_trf_supported()) {
write_trfcr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2));
}
-#if ENABLE_FEAT_CSV2_2
- el2_sysregs_context_restore_csv2(el2_sysregs_ctx);
-#endif
+
+ if (is_feat_csv2_2_supported()) {
+ write_scxtnum_el2(read_ctx_reg(el2_sysregs_ctx,
+ CTX_SCXTNUM_EL2));
+ }
+
if (is_feat_hcx_supported()) {
write_hcrx_el2(read_ctx_reg(el2_sysregs_ctx, CTX_HCRX_EL2));
}
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 683234f..03fe9cc 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -470,6 +470,7 @@
ENABLE_FEAT_HCX := 2
ENABLE_FEAT_TCR2 := 2
+ENABLE_FEAT_CSV2_2 := 2
ENABLE_FEAT_ECV := 2
ENABLE_FEAT_PAN := 2
ENABLE_FEAT_VHE := 2