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
This commit is contained in:
Madhukar Pappireddy 2024-06-17 15:17:03 -05:00
parent 841533dd53
commit 42422622f9
3 changed files with 39 additions and 7 deletions

View file

@ -1130,6 +1130,7 @@ $(eval $(call assert_booleans,\
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 @@ $(eval $(call add_defines,\
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 \

View file

@ -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 @@ typedef struct {
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 @@ CASSERT(CTX_SIMD_FPEXC32 == __builtin_offsetof(simd_regs_t, fpexc32_el2),
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 */

View file

@ -63,6 +63,9 @@ CTX_INCLUDE_AARCH32_REGS := 1
# 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