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