xref: /rk3399_ARM-atf/include/lib/el3_runtime/simd_ctx.h (revision 46aff6fc60a62ea9b27301f40a835c97c7c6e657)
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