1 /* 2 * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. 3 * Copyright (c) 2022, Google LLC. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #ifndef SIMD_CTX_H 9 #define SIMD_CTX_H 10 11 /******************************************************************************* 12 * Constants that allow assembler code to access members of and the 'simd_context' 13 * structure at their correct offsets. 14 ******************************************************************************/ 15 16 #if CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS 17 #if CTX_INCLUDE_SVE_REGS 18 #define SIMD_VECTOR_LEN_BYTES (SVE_VECTOR_LEN / 8) /* Length of vector in bytes */ 19 #elif CTX_INCLUDE_FPREGS 20 #define SIMD_VECTOR_LEN_BYTES U(16) /* 128 bits fixed vector length for FPU */ 21 #endif /* CTX_INCLUDE_SVE_REGS */ 22 23 #define CTX_SIMD_VECTORS U(0) 24 /* there are 32 vector registers, each of size SIMD_VECTOR_LEN_BYTES */ 25 #define CTX_SIMD_FPSR (CTX_SIMD_VECTORS + (32 * SIMD_VECTOR_LEN_BYTES)) 26 #define CTX_SIMD_FPCR (CTX_SIMD_FPSR + 8) 27 28 #if CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS 29 #define CTX_SIMD_FPEXC32 (CTX_SIMD_FPCR + 8) 30 #define CTX_SIMD_PREDICATES (CTX_SIMD_FPEXC32 + 16) 31 #else 32 #define CTX_SIMD_PREDICATES (CTX_SIMD_FPCR + 8) 33 #endif /* CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS */ 34 35 /* 36 * Each predicate register is 1/8th the size of a vector register and there are 16 37 * predicate registers 38 */ 39 #define CTX_SIMD_FFR (CTX_SIMD_PREDICATES + (16 * (SIMD_VECTOR_LEN_BYTES / 8))) 40 41 #ifndef __ASSEMBLER__ 42 43 #include <stdint.h> 44 #include <lib/cassert.h> 45 46 /* 47 * Please don't change order of fields in this struct as that may violate 48 * alignment requirements and affect how assembly code accesses members of this 49 * struct. 50 */ 51 typedef struct { 52 uint8_t vectors[32][SIMD_VECTOR_LEN_BYTES]; 53 uint8_t fpsr[8]; 54 uint8_t fpcr[8]; 55 #if CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS 56 /* 16 bytes to align to next 16 byte boundary when CTX_INCLUDE_SVE_REGS is 0 */ 57 uint8_t fpexc32_el2[16]; 58 #endif 59 #if CTX_INCLUDE_SVE_REGS 60 /* FFR and each of predicates is one-eigth of the SVE vector length */ 61 uint8_t predicates[16][SIMD_VECTOR_LEN_BYTES / 8]; 62 uint8_t ffr[SIMD_VECTOR_LEN_BYTES / 8]; 63 /* SMCCCv1.3 FID[16] hint bit state recorded on EL3 entry */ 64 bool hint; 65 #endif /* CTX_INCLUDE_SVE_REGS */ 66 } __aligned(16) simd_regs_t; 67 68 CASSERT(CTX_SIMD_VECTORS == __builtin_offsetof(simd_regs_t, vectors), 69 assert_vectors_mismatch); 70 71 CASSERT(CTX_SIMD_FPSR == __builtin_offsetof(simd_regs_t, fpsr), 72 assert_fpsr_mismatch); 73 74 CASSERT(CTX_SIMD_FPCR == __builtin_offsetof(simd_regs_t, fpcr), 75 assert_fpcr_mismatch); 76 77 #if CTX_INCLUDE_FPREGS && CTX_INCLUDE_AARCH32_REGS 78 CASSERT(CTX_SIMD_FPEXC32 == __builtin_offsetof(simd_regs_t, fpexc32_el2), 79 assert_fpex32_mismtatch); 80 #endif 81 82 #if CTX_INCLUDE_SVE_REGS 83 CASSERT(CTX_SIMD_PREDICATES == __builtin_offsetof(simd_regs_t, predicates), 84 assert_predicates_mismatch); 85 86 CASSERT(CTX_SIMD_FFR == __builtin_offsetof(simd_regs_t, ffr), 87 assert_ffr_mismatch); 88 #endif 89 90 void simd_ctx_save(uint32_t security_state, bool hint_sve); 91 void simd_ctx_restore(uint32_t security_state); 92 93 #endif /* __ASSEMBLER__ */ 94 95 #endif /* CTX_INCLUDE_FPREGS || CTX_INCLUDE_SVE_REGS */ 96 97 #endif /* SIMD_CTX_H */ 98