feat(sve): enable SVE for the secure world
Enables SVE support for the secure world via ENABLE_SVE_FOR_SWD.
ENABLE_SVE_FOR_SWD defaults to 0 and has to be explicitly set by the
platform. SVE is configured during initial setup and then uses EL3
context save/restore routine to switch between SVE configurations for
different contexts.
Reset value of CPTR_EL3 changed to be most restrictive by default.
Signed-off-by: Max Shvetsov <maksims.svecovs@arm.com>
Change-Id: I889fbbc2e435435d66779b73a2d90d1188bf4116
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 0ec9ffd..d610fd4 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -901,6 +901,29 @@
msr spsr_el3, x16
msr elr_el3, x17
+#if IMAGE_BL31
+ /* ----------------------------------------------------------
+ * Restore CPTR_EL3, ZCR_EL3 for SVE support.
+ * If SVE is not supported - skip the restoration.
+ * ZCR is only restored if SVE is supported and enabled.
+ * Synchronization is required before zcr_el3 is addressed.
+ * ----------------------------------------------------------
+ */
+ mrs x17, id_aa64pfr0_el1
+ ubfx x17, x17, ID_AA64PFR0_SVE_SHIFT, ID_AA64PFR0_SVE_LENGTH
+ cbz x17, sve_not_enabled
+
+ ldp x19, x20, [sp, #CTX_EL3STATE_OFFSET + CTX_CPTR_EL3]
+ msr cptr_el3, x19
+
+ ands x19, x19, #CPTR_EZ_BIT
+ beq sve_not_enabled
+
+ isb
+ msr S3_6_C1_C2_0, x20 /* zcr_el3 */
+sve_not_enabled:
+#endif
+
#if IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639
/* ----------------------------------------------------------
* Restore mitigation state as it was on entry to EL3
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 96023b6..7a25151 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -178,6 +178,18 @@
* indicated by the interrupt routing model for BL31.
*/
scr_el3 |= get_scr_el3_from_routing_model(security_state);
+
+#if ENABLE_SVE_FOR_NS
+ if (security_state == NON_SECURE) {
+ sve_enable(ctx);
+ }
+#endif
+#if ENABLE_SVE_FOR_SWD
+ if (security_state == SECURE) {
+ sve_enable(ctx);
+ }
+#endif
+
#endif
/*
@@ -334,10 +346,6 @@
amu_enable(el2_unused);
#endif
-#if ENABLE_SVE_FOR_NS
- sve_enable(el2_unused);
-#endif
-
#if ENABLE_MPAM_FOR_LOWER_ELS
mpam_enable(el2_unused);
#endif