feat(cpufeat): add ENABLE_FEAT_LS64_ACCDATA
Armv8.6 introduced the FEAT_LS64 extension, which provides a 64 *byte*
store instruction. A related instruction is ST64BV0, which will replace
the lowest 32 bits of the data with a value taken from the ACCDATA_EL1
system register (so that EL0 cannot alter them).
Using that ST64BV0 instruction and accessing the ACCDATA_EL1 system
register is guarded by two SCR_EL3 bits, which we should set to avoid a
trap into EL3, when lower ELs use one of those.
Add the required bits and pieces to make this feature usable:
- Add the ENABLE_FEAT_LS64_ACCDATA build option (defaulting to 0).
- Add the CPUID and SCR_EL3 bit definitions associated with FEAT_LS64.
- Add a feature check to check for the existing four variants of the
LS64 feature and detect future extensions.
- Add code to save and restore the ACCDATA_EL1 register on
secure/non-secure context switches.
- Enable the feature with runtime detection for FVP and Arm FPGA.
Please note that the *basic* FEAT_LS64 feature does not feature any trap
bits, it's only the addition of the ACCDATA_EL1 system register that
adds these traps and the SCR_EL3 bits.
Change-Id: Ie3e2ca2d9c4fbbd45c0cc6089accbb825579138a
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 8aa2ccc..4ae1306 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -427,6 +427,15 @@
}
/*
+ * If FEAT_LS64_ACCDATA is enabled, enable access to ACCDATA_EL1 by
+ * setting SCR_EL3.ADEn and allow the ST64BV0 instruction by setting
+ * SCR_EL3.EnAS0.
+ */
+ if (is_feat_ls64_accdata_supported()) {
+ scr_el3 |= SCR_ADEn_BIT | SCR_EnAS0_BIT;
+ }
+
+ /*
* If FEAT_RNG_TRAP is enabled, all reads of the RNDR and RNDRRS
* registers are trapped to EL3.
*/
@@ -1759,6 +1768,9 @@
write_el1_ctx_sctlr2(ctx, sctlr2_el1, read_sctlr2_el1());
}
+ if (is_feat_ls64_accdata_supported()) {
+ write_el1_ctx_ls64(ctx, accdata_el1, read_accdata_el1());
+ }
}
static void el1_sysregs_context_restore(el1_sysregs_t *ctx)
@@ -1864,6 +1876,9 @@
write_sctlr2_el1(read_el1_ctx_sctlr2(ctx, sctlr2_el1));
}
+ if (is_feat_ls64_accdata_supported()) {
+ write_accdata_el1(read_el1_ctx_ls64(ctx, accdata_el1));
+ }
}
/*******************************************************************************