feat(simd): add sve state to simd ctxt struct
This patch extends the simd data structure to hold the SVE state. A new
build flag CTX_INCLUDE_SVE_REGS is introduced in this patch to enable
SVE context management.
Necessary precautions are taken such as ensuring the field offsets are
not changed and necessary padding is added for alignment reasons.
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Signed-off-by: Okash Khawaja <okash@google.com>
Change-Id: I54f5222c7d8c68638105003f68caa511d347cd60
diff --git a/Makefile b/Makefile
index 2fc856a..d5a70ef 100644
--- a/Makefile
+++ b/Makefile
@@ -1130,6 +1130,7 @@
CREATE_KEYS \
CTX_INCLUDE_AARCH32_REGS \
CTX_INCLUDE_FPREGS \
+ CTX_INCLUDE_SVE_REGS \
CTX_INCLUDE_EL2_REGS \
CTX_INCLUDE_MPAM_REGS \
DEBUG \
@@ -1288,6 +1289,7 @@
COLD_BOOT_SINGLE_CPU \
CTX_INCLUDE_AARCH32_REGS \
CTX_INCLUDE_FPREGS \
+ CTX_INCLUDE_SVE_REGS \
CTX_INCLUDE_PAUTH_REGS \
CTX_INCLUDE_MPAM_REGS \
EL3_EXCEPTION_HANDLING \
diff --git a/include/lib/el3_runtime/simd_ctx.h b/include/lib/el3_runtime/simd_ctx.h
index c874264..fdbe24f 100644
--- a/include/lib/el3_runtime/simd_ctx.h
+++ b/include/lib/el3_runtime/simd_ctx.h
@@ -13,18 +13,30 @@
* structure at their correct offsets.
******************************************************************************/
-#if CTX_INCLUDE_FPREGS
-
+#if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS
+#if CTX_INCLUDE_SVE_REGS
+#define SIMD_VECTOR_LEN_BYTES (SVE_VECTOR_LEN / 8) /* Length of vector in bytes */
+#elif CTX_INCLUDE_FPREGS
#define SIMD_VECTOR_LEN_BYTES U(16) /* 128 bits fixed vector length for FPU */
+#endif /* CTX_INCLUDE_SVE_REGS */
#define CTX_SIMD_VECTORS U(0)
/* there are 32 vector registers, each of size SIMD_VECTOR_LEN_BYTES */
#define CTX_SIMD_FPSR (CTX_SIMD_VECTORS + (32 * SIMD_VECTOR_LEN_BYTES))
#define CTX_SIMD_FPCR (CTX_SIMD_FPSR + 8)
-#if CTX_INCLUDE_AARCH32_REGS
+#if CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS
#define CTX_SIMD_FPEXC32 (CTX_SIMD_FPCR + 8)
-#endif /* CTX_INCLUDE_AARCH32_REGS */
+#define CTX_SIMD_PREDICATES (CTX_SIMD_FPEXC32 + 16)
+#else
+#define CTX_SIMD_PREDICATES (CTX_SIMD_FPCR + 8)
+#endif /* CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS */
+
+/*
+ * Each predicate register is 1/8th the size of a vector register and there are 16
+ * predicate registers
+ */
+#define CTX_SIMD_FFR (CTX_SIMD_PREDICATES + (16 * (SIMD_VECTOR_LEN_BYTES / 8)))
#ifndef __ASSEMBLER__
@@ -41,10 +53,17 @@
uint8_t fpsr[8];
uint8_t fpcr[8];
#if CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS
- /* 16 bytes to align to next 16 byte boundary */
+ /* 16 bytes to align to next 16 byte boundary when CTX_INCLUDE_SVE_REGS is 0 */
uint8_t fpexc32_el2[16];
#endif
-} simd_regs_t __attribute__((aligned(16)));
+#if CTX_INCLUDE_SVE_REGS
+ /* FFR and each of predicates is one-eigth of the SVE vector length */
+ uint8_t predicates[16][SIMD_VECTOR_LEN_BYTES / 8];
+ uint8_t ffr[SIMD_VECTOR_LEN_BYTES / 8];
+ /* SMCCCv1.3 FID[16] hint bit state recorded on EL3 entry */
+ bool hint;
+#endif /* CTX_INCLUDE_SVE_REGS */
+} __aligned(16) simd_regs_t;
CASSERT(CTX_SIMD_VECTORS == __builtin_offsetof(simd_regs_t, vectors),
assert_vectors_mismatch);
@@ -60,11 +79,19 @@
assert_fpex32_mismtatch);
#endif
+#if CTX_INCLUDE_SVE_REGS
+CASSERT(CTX_SIMD_PREDICATES == __builtin_offsetof(simd_regs_t, predicates),
+ assert_predicates_mismatch);
+
+CASSERT(CTX_SIMD_FFR == __builtin_offsetof(simd_regs_t, ffr),
+ assert_ffr_mismatch);
+#endif
+
void simd_ctx_save(uint32_t security_state, bool hint_sve);
void simd_ctx_restore(uint32_t security_state);
#endif /* __ASSEMBLER__ */
-#endif /* CTX_INCLUDE_FPREGS */
+#endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */
#endif /* SIMD_CTX_H */
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 368d26d..1224a4a 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -63,6 +63,9 @@
# Include FP registers in cpu context
CTX_INCLUDE_FPREGS := 0
+# Include SVE registers in cpu context
+CTX_INCLUDE_SVE_REGS := 0
+
# Debug build
DEBUG := 0