feat(sctlr2): add support for FEAT_SCTLR2
Arm v8.9 introduces FEAT_SCTLR2, adding SCTLR2_ELx registers.
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: I0c4cba86917b6b065a7e8dd6af7daf64ee18dcda
Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
Signed-off-by: Govindraj Raja <govindraj.raja@arm.com>
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 65247ec..8145616 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -406,6 +406,10 @@
#define ID_AA64MMFR3_EL1_S1PIE_SHIFT U(8)
#define ID_AA64MMFR3_EL1_S1PIE_MASK ULL(0xf)
+#define ID_AA64MMFR3_EL1_SCTLR2_SHIFT U(4)
+#define ID_AA64MMFR3_EL1_SCTLR2_MASK ULL(0xf)
+#define SCTLR2_IMPLEMENTED ULL(1)
+
#define ID_AA64MMFR3_EL1_TCRX_SHIFT U(0)
#define ID_AA64MMFR3_EL1_TCRX_MASK ULL(0xf)
@@ -593,6 +597,7 @@
#define SCR_TWEDEL_SHIFT U(30)
#define SCR_TWEDEL_MASK ULL(0xf)
#define SCR_PIEN_BIT (UL(1) << 45)
+#define SCR_SCTLR2En_BIT (UL(1) << 44)
#define SCR_TCR2EN_BIT (UL(1) << 43)
#define SCR_RCWMASKEn_BIT (UL(1) << 42)
#define SCR_TRNDR_BIT (UL(1) << 40)
@@ -1484,6 +1489,12 @@
#define RCWSMASK_EL1 S3_0_C13_C0_3
/*******************************************************************************
+ * FEAT_SCTLR2 - Extension to SCTLR_ELx Registers
+ ******************************************************************************/
+#define SCTLR2_EL2 S3_4_C1_C0_3
+#define SCTLR2_EL1 S3_0_C1_C0_3
+
+/*******************************************************************************
* Definitions for DynamicIQ Shared Unit registers
******************************************************************************/
#define CLUSTERPWRDN_EL1 S3_0_c15_c3_6
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index fcd0ee6..de21fea 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -136,6 +136,8 @@
* +----------------------------+
* | FEAT_THE |
* +----------------------------+
+ * | FEAT_SCTLR2 |
+ * +----------------------------+
*/
__attribute__((always_inline))
@@ -268,6 +270,11 @@
CREATE_FEATURE_FUNCS(feat_the, id_aa64pfr1_el1, ID_AA64PFR1_EL1_THE_SHIFT,
ID_AA64PFR1_EL1_THE_MASK, THE_IMPLEMENTED, ENABLE_FEAT_THE)
+/* FEAT_SCTLR2 */
+CREATE_FEATURE_FUNCS(feat_sctlr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_SCTLR2_SHIFT,
+ ID_AA64MMFR3_EL1_SCTLR2_MASK, SCTLR2_IMPLEMENTED,
+ ENABLE_FEAT_SCTLR2)
+
__attribute__((always_inline))
static inline bool is_feat_sxpie_supported(void)
{
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 49f1345..acaa1b8 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -674,6 +674,10 @@
DEFINE_RENAME_SYSREG_RW_FUNCS(rcwmask_el1, RCWMASK_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(rcwsmask_el1, RCWSMASK_EL1)
+/* FEAT_SCTLR2 Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el1, SCTLR2_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el2, SCTLR2_EL2)
+
/* DynamIQ Control registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpmcr_el1, CLUSTERPMCR_EL1)
diff --git a/include/lib/el3_runtime/context_el1.h b/include/lib/el3_runtime/context_el1.h
index ab3be63..94af210 100644
--- a/include/lib/el3_runtime/context_el1.h
+++ b/include/lib/el3_runtime/context_el1.h
@@ -112,6 +112,10 @@
uint64_t rcwsmask_el1;
} el1_the_regs_t;
+typedef struct el1_sctlr2_regs {
+ uint64_t sctlr2_el1;
+} el1_sctlr2_regs_t;
+
typedef struct el1_sysregs {
el1_common_regs_t common;
@@ -164,6 +168,10 @@
el1_the_regs_t the;
#endif
+#if ENABLE_FEAT_SCTLR2
+ el1_sctlr2_regs_t sctlr2;
+#endif
+
} el1_sysregs_t;
@@ -285,6 +293,15 @@
#define write_el1_ctx_the(ctx, reg, val)
#endif /* ENABLE_FEAT_THE */
+#if ENABLE_FEAT_SCTLR2
+#define read_el1_ctx_sctlr2(ctx, reg) (((ctx)->sctlr2).reg)
+#define write_el1_ctx_sctlr2(ctx, reg, val) ((((ctx)->sctlr2).reg) \
+ = (uint64_t) (val))
+#else
+#define read_el1_ctx_sctlr2(ctx, reg) ULL(0)
+#define write_el1_ctx_sctlr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_SCTLR2 */
+
/******************************************************************************/
#endif /* __ASSEMBLER__ */
diff --git a/include/lib/el3_runtime/context_el2.h b/include/lib/el3_runtime/context_el2.h
index 14c1fb6..ad0b68f 100644
--- a/include/lib/el3_runtime/context_el2.h
+++ b/include/lib/el3_runtime/context_el2.h
@@ -135,6 +135,10 @@
uint64_t mpamvpmv_el2;
} el2_mpam_regs_t;
+typedef struct el2_sctlr2_regs {
+ uint64_t sctlr2_el2;
+} el2_sctlr2_regs_t;
+
typedef struct el2_sysregs {
el2_common_regs_t common;
@@ -203,6 +207,10 @@
el2_mpam_regs_t mpam;
#endif
+#if ENABLE_FEAT_SCTLR2
+ el2_sctlr2_regs_t sctlr2;
+#endif
+
} el2_sysregs_t;
/*
@@ -358,6 +366,15 @@
#define write_el2_ctx_mpam(ctx, reg, val)
#endif /* CTX_INCLUDE_MPAM_REGS */
+#if ENABLE_FEAT_SCTLR2
+#define read_el2_ctx_sctlr2(ctx, reg) (((ctx)->sctlr2).reg)
+#define write_el2_ctx_sctlr2(ctx, reg, val) ((((ctx)->sctlr2).reg) \
+ = (uint64_t) (val))
+#else
+#define read_el2_ctx_sctlr2(ctx, reg) ULL(0)
+#define write_el2_ctx_sctlr2(ctx, reg, val)
+#endif /* ENABLE_FEAT_SCTLR2 */
+
/******************************************************************************/
#endif /* __ASSEMBLER__ */