]>
Commit | Line | Data |
---|---|---|
6ada909e LM |
1 | /* Linux Kernel sigcontext definitions for AArch64 Scalable Extensions |
2 | (SVE/SME). | |
3 | ||
4 | Copyright (C) 2018-2023 Free Software Foundation, Inc. | |
17a1cc89 AH |
5 | Contributed by Arm Ltd. |
6 | ||
7 | This file is part of GDB. | |
8 | ||
9 | This program is free software; you can redistribute it and/or modify | |
10 | it under the terms of the GNU General Public License as published by | |
11 | the Free Software Foundation; either version 3 of the License, or | |
12 | (at your option) any later version. | |
13 | ||
14 | This program is distributed in the hope that it will be useful, | |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | GNU General Public License for more details. | |
18 | ||
19 | You should have received a copy of the GNU General Public License | |
20 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
21 | ||
6ada909e LM |
22 | #ifndef NAT_AARCH64_SCALABLE_LINUX_SIGCONTEXT_H |
23 | #define NAT_AARCH64_SCALABLE_LINUX_SIGCONTEXT_H | |
17a1cc89 | 24 | |
ca65640f LM |
25 | #ifndef SVE_SIG_ZREGS_SIZE |
26 | ||
17a1cc89 AH |
27 | #define SVE_MAGIC 0x53564501 |
28 | ||
ca65640f | 29 | |
17a1cc89 AH |
30 | struct sve_context { |
31 | struct _aarch64_ctx head; | |
32 | __u16 vl; | |
33 | __u16 __reserved[3]; | |
34 | }; | |
35 | ||
36 | /* | |
37 | * The SVE architecture leaves space for future expansion of the | |
38 | * vector length beyond its initial architectural limit of 2048 bits | |
39 | * (16 quadwords). | |
40 | * | |
41 | * See linux/Documentation/arm64/sve.txt for a description of the VL/VQ | |
42 | * terminology. | |
43 | */ | |
44 | #define SVE_VQ_BYTES 16 /* number of bytes per quadword */ | |
45 | ||
46 | #define SVE_VQ_MIN 1 | |
47 | #define SVE_VQ_MAX 512 | |
48 | ||
49 | #define SVE_VL_MIN (SVE_VQ_MIN * SVE_VQ_BYTES) | |
50 | #define SVE_VL_MAX (SVE_VQ_MAX * SVE_VQ_BYTES) | |
51 | ||
52 | #define SVE_NUM_ZREGS 32 | |
53 | #define SVE_NUM_PREGS 16 | |
54 | ||
55 | #define sve_vl_valid(vl) \ | |
56 | ((vl) % SVE_VQ_BYTES == 0 && (vl) >= SVE_VL_MIN && (vl) <= SVE_VL_MAX) | |
57 | ||
58 | /* | |
59 | * If the SVE registers are currently live for the thread at signal delivery, | |
60 | * sve_context.head.size >= | |
61 | * SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve_context.vl)) | |
62 | * and the register data may be accessed using the SVE_SIG_*() macros. | |
63 | * | |
64 | * If sve_context.head.size < | |
65 | * SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve_context.vl)), | |
66 | * the SVE registers were not live for the thread and no register data | |
67 | * is included: in this case, the SVE_SIG_*() macros should not be | |
68 | * used except for this check. | |
69 | * | |
70 | * The same convention applies when returning from a signal: a caller | |
71 | * will need to remove or resize the sve_context block if it wants to | |
72 | * make the SVE registers live when they were previously non-live or | |
6471e7d2 | 73 | * vice-versa. This may require the caller to allocate fresh |
17a1cc89 AH |
74 | * memory and/or move other context blocks in the signal frame. |
75 | * | |
76 | * Changing the vector length during signal return is not permitted: | |
77 | * sve_context.vl must equal the thread's current vector length when | |
78 | * doing a sigreturn. | |
79 | * | |
80 | * | |
81 | * Note: for all these macros, the "vq" argument denotes the SVE | |
82 | * vector length in quadwords (i.e., units of 128 bits). | |
83 | * | |
84 | * The correct way to obtain vq is to use sve_vq_from_vl(vl). The | |
85 | * result is valid if and only if sve_vl_valid(vl) is true. This is | |
86 | * guaranteed for a struct sve_context written by the kernel. | |
87 | * | |
88 | * | |
89 | * Additional macros describe the contents and layout of the payload. | |
90 | * For each, SVE_SIG_x_OFFSET(args) is the start offset relative to | |
91 | * the start of struct sve_context, and SVE_SIG_x_SIZE(args) is the | |
92 | * size in bytes: | |
93 | * | |
94 | * x type description | |
95 | * - ---- ----------- | |
96 | * REGS the entire SVE context | |
97 | * | |
98 | * ZREGS __uint128_t[SVE_NUM_ZREGS][vq] all Z-registers | |
99 | * ZREG __uint128_t[vq] individual Z-register Zn | |
100 | * | |
101 | * PREGS uint16_t[SVE_NUM_PREGS][vq] all P-registers | |
102 | * PREG uint16_t[vq] individual P-register Pn | |
103 | * | |
104 | * FFR uint16_t[vq] first-fault status register | |
105 | * | |
106 | * Additional data might be appended in the future. | |
107 | */ | |
108 | ||
109 | #define SVE_SIG_ZREG_SIZE(vq) ((__u32)(vq) * SVE_VQ_BYTES) | |
110 | #define SVE_SIG_PREG_SIZE(vq) ((__u32)(vq) * (SVE_VQ_BYTES / 8)) | |
111 | #define SVE_SIG_FFR_SIZE(vq) SVE_SIG_PREG_SIZE(vq) | |
112 | ||
113 | #define SVE_SIG_REGS_OFFSET \ | |
114 | ((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1)) \ | |
115 | / SVE_VQ_BYTES * SVE_VQ_BYTES) | |
116 | ||
117 | #define SVE_SIG_ZREGS_OFFSET SVE_SIG_REGS_OFFSET | |
118 | #define SVE_SIG_ZREG_OFFSET(vq, n) \ | |
119 | (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREG_SIZE(vq) * (n)) | |
120 | #define SVE_SIG_ZREGS_SIZE(vq) \ | |
121 | (SVE_SIG_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_SIG_ZREGS_OFFSET) | |
122 | ||
123 | #define SVE_SIG_PREGS_OFFSET(vq) \ | |
124 | (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREGS_SIZE(vq)) | |
125 | #define SVE_SIG_PREG_OFFSET(vq, n) \ | |
126 | (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREG_SIZE(vq) * (n)) | |
127 | #define SVE_SIG_PREGS_SIZE(vq) \ | |
128 | (SVE_SIG_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_SIG_PREGS_OFFSET(vq)) | |
129 | ||
130 | #define SVE_SIG_FFR_OFFSET(vq) \ | |
131 | (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREGS_SIZE(vq)) | |
132 | ||
133 | #define SVE_SIG_REGS_SIZE(vq) \ | |
134 | (SVE_SIG_FFR_OFFSET(vq) + SVE_SIG_FFR_SIZE(vq) - SVE_SIG_REGS_OFFSET) | |
135 | ||
136 | #define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq)) | |
137 | ||
ca65640f | 138 | /* SVE/FP/SIMD state (NT_ARM_SVE and NT_ARM_SSVE) */ |
17a1cc89 AH |
139 | |
140 | struct user_sve_header { | |
141 | __u32 size; /* total meaningful regset content in bytes */ | |
30baf67b | 142 | __u32 max_size; /* maximum possible size for this thread */ |
17a1cc89 AH |
143 | __u16 vl; /* current vector length */ |
144 | __u16 max_vl; /* maximum possible vector length */ | |
145 | __u16 flags; | |
146 | __u16 __reserved; | |
147 | }; | |
148 | ||
149 | /* Definitions for user_sve_header.flags: */ | |
150 | #define SVE_PT_REGS_MASK (1 << 0) | |
151 | ||
152 | #define SVE_PT_REGS_FPSIMD 0 | |
153 | #define SVE_PT_REGS_SVE SVE_PT_REGS_MASK | |
154 | ||
155 | /* | |
156 | * Common SVE_PT_* flags: | |
157 | * These must be kept in sync with prctl interface in <linux/ptrace.h> | |
158 | */ | |
159 | #define SVE_PT_VL_INHERIT (PR_SVE_VL_INHERIT >> 16) | |
160 | #define SVE_PT_VL_ONEXEC (PR_SVE_SET_VL_ONEXEC >> 16) | |
161 | ||
162 | ||
163 | /* | |
164 | * The remainder of the SVE state follows struct user_sve_header. The | |
165 | * total size of the SVE state (including header) depends on the | |
166 | * metadata in the header: SVE_PT_SIZE(vq, flags) gives the total size | |
167 | * of the state in bytes, including the header. | |
168 | * | |
169 | * Refer to <asm/sigcontext.h> for details of how to pass the correct | |
170 | * "vq" argument to these macros. | |
171 | */ | |
172 | ||
173 | /* Offset from the start of struct user_sve_header to the register data */ | |
174 | #define SVE_PT_REGS_OFFSET \ | |
cc308722 | 175 | ((sizeof(struct user_sve_header) + (SVE_VQ_BYTES - 1)) \ |
17a1cc89 AH |
176 | / SVE_VQ_BYTES * SVE_VQ_BYTES) |
177 | ||
178 | /* | |
179 | * The register data content and layout depends on the value of the | |
180 | * flags field. | |
181 | */ | |
182 | ||
183 | /* | |
184 | * (flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD case: | |
185 | * | |
186 | * The payload starts at offset SVE_PT_FPSIMD_OFFSET, and is of type | |
187 | * struct user_fpsimd_state. Additional data might be appended in the | |
188 | * future: use SVE_PT_FPSIMD_SIZE(vq, flags) to compute the total size. | |
189 | * SVE_PT_FPSIMD_SIZE(vq, flags) will never be less than | |
190 | * sizeof(struct user_fpsimd_state). | |
191 | */ | |
192 | ||
193 | #define SVE_PT_FPSIMD_OFFSET SVE_PT_REGS_OFFSET | |
194 | ||
195 | #define SVE_PT_FPSIMD_SIZE(vq, flags) (sizeof(struct user_fpsimd_state)) | |
196 | ||
197 | /* | |
198 | * (flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE case: | |
199 | * | |
200 | * The payload starts at offset SVE_PT_SVE_OFFSET, and is of size | |
201 | * SVE_PT_SVE_SIZE(vq, flags). | |
202 | * | |
203 | * Additional macros describe the contents and layout of the payload. | |
204 | * For each, SVE_PT_SVE_x_OFFSET(args) is the start offset relative to | |
205 | * the start of struct user_sve_header, and SVE_PT_SVE_x_SIZE(args) is | |
206 | * the size in bytes: | |
207 | * | |
208 | * x type description | |
209 | * - ---- ----------- | |
210 | * ZREGS \ | |
211 | * ZREG | | |
212 | * PREGS | refer to <asm/sigcontext.h> | |
213 | * PREG | | |
214 | * FFR / | |
215 | * | |
216 | * FPSR uint32_t FPSR | |
217 | * FPCR uint32_t FPCR | |
218 | * | |
219 | * Additional data might be appended in the future. | |
220 | */ | |
221 | ||
222 | #define SVE_PT_SVE_ZREG_SIZE(vq) SVE_SIG_ZREG_SIZE(vq) | |
223 | #define SVE_PT_SVE_PREG_SIZE(vq) SVE_SIG_PREG_SIZE(vq) | |
224 | #define SVE_PT_SVE_FFR_SIZE(vq) SVE_SIG_FFR_SIZE(vq) | |
225 | #define SVE_PT_SVE_FPSR_SIZE sizeof(__u32) | |
226 | #define SVE_PT_SVE_FPCR_SIZE sizeof(__u32) | |
227 | ||
228 | #define __SVE_SIG_TO_PT(offset) \ | |
229 | ((offset) - SVE_SIG_REGS_OFFSET + SVE_PT_REGS_OFFSET) | |
230 | ||
231 | #define SVE_PT_SVE_OFFSET SVE_PT_REGS_OFFSET | |
232 | ||
233 | #define SVE_PT_SVE_ZREGS_OFFSET \ | |
234 | __SVE_SIG_TO_PT(SVE_SIG_ZREGS_OFFSET) | |
235 | #define SVE_PT_SVE_ZREG_OFFSET(vq, n) \ | |
236 | __SVE_SIG_TO_PT(SVE_SIG_ZREG_OFFSET(vq, n)) | |
237 | #define SVE_PT_SVE_ZREGS_SIZE(vq) \ | |
238 | (SVE_PT_SVE_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_PT_SVE_ZREGS_OFFSET) | |
239 | ||
240 | #define SVE_PT_SVE_PREGS_OFFSET(vq) \ | |
241 | __SVE_SIG_TO_PT(SVE_SIG_PREGS_OFFSET(vq)) | |
242 | #define SVE_PT_SVE_PREG_OFFSET(vq, n) \ | |
243 | __SVE_SIG_TO_PT(SVE_SIG_PREG_OFFSET(vq, n)) | |
244 | #define SVE_PT_SVE_PREGS_SIZE(vq) \ | |
245 | (SVE_PT_SVE_PREG_OFFSET(vq, SVE_NUM_PREGS) - \ | |
246 | SVE_PT_SVE_PREGS_OFFSET(vq)) | |
247 | ||
ca65640f | 248 | /* For streaming mode SVE (SSVE) FFR must be read and written as zero. */ |
17a1cc89 AH |
249 | #define SVE_PT_SVE_FFR_OFFSET(vq) \ |
250 | __SVE_SIG_TO_PT(SVE_SIG_FFR_OFFSET(vq)) | |
251 | ||
252 | #define SVE_PT_SVE_FPSR_OFFSET(vq) \ | |
253 | ((SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq) + \ | |
254 | (SVE_VQ_BYTES - 1)) \ | |
255 | / SVE_VQ_BYTES * SVE_VQ_BYTES) | |
256 | #define SVE_PT_SVE_FPCR_OFFSET(vq) \ | |
257 | (SVE_PT_SVE_FPSR_OFFSET(vq) + SVE_PT_SVE_FPSR_SIZE) | |
258 | ||
259 | /* | |
260 | * Any future extension appended after FPCR must be aligned to the next | |
261 | * 128-bit boundary. | |
262 | */ | |
263 | ||
264 | #define SVE_PT_SVE_SIZE(vq, flags) \ | |
265 | ((SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE \ | |
266 | - SVE_PT_SVE_OFFSET + (SVE_VQ_BYTES - 1)) \ | |
267 | / SVE_VQ_BYTES * SVE_VQ_BYTES) | |
268 | ||
269 | #define SVE_PT_SIZE(vq, flags) \ | |
270 | (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ? \ | |
271 | SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags) \ | |
272 | : SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags)) | |
273 | ||
ca65640f LM |
274 | #endif /* SVE_SIG_ZREGS_SIZE */ |
275 | ||
276 | /* Scalable Matrix Extensions (SME) definitions. */ | |
277 | ||
278 | /* Make sure we only define these if the kernel header doesn't. */ | |
279 | #ifndef ZA_PT_SIZE | |
280 | ||
281 | /* ZA state (NT_ARM_ZA) */ | |
282 | struct user_za_header { | |
283 | __u32 size; /* total meaningful regset content in bytes */ | |
284 | __u32 max_size; /* maximum possible size for this thread */ | |
285 | __u16 vl; /* current vector length */ | |
286 | __u16 max_vl; /* maximum possible vector length */ | |
287 | __u16 flags; | |
288 | __u16 __reserved; | |
289 | }; | |
290 | ||
291 | /* The remainder of the ZA state follows struct user_za_header. The | |
292 | total size of the ZA state (including header) depends on the | |
293 | metadata in the header: ZA_PT_SIZE(vq, flags) gives the total size | |
294 | of the state in bytes, including the header. | |
295 | ||
296 | Refer to arch/arm64/include/uapi/asm/sigcontext.h from the Linux kernel | |
297 | for details of how to pass the correct "vq" argument to these macros. */ | |
298 | ||
299 | /* Offset from the start of struct user_za_header to the register data */ | |
300 | #define ZA_PT_ZA_OFFSET \ | |
301 | ((sizeof (struct user_za_header) + (__SVE_VQ_BYTES - 1)) \ | |
302 | / __SVE_VQ_BYTES * __SVE_VQ_BYTES) | |
303 | ||
304 | /* The payload starts at offset ZA_PT_ZA_OFFSET, and is of size | |
305 | ZA_PT_ZA_SIZE(vq, flags). | |
306 | ||
307 | The ZA array is stored as a sequence of horizontal vectors ZAV of SVL/8 | |
308 | bytes each, starting from vector 0. | |
309 | ||
310 | Additional data might be appended in the future. | |
311 | ||
312 | The ZA matrix is represented in memory in an endianness-invariant layout | |
313 | which differs from the layout used for the FPSIMD V-registers on big-endian | |
314 | systems: see sigcontext.h for more explanation. */ | |
315 | ||
316 | #define ZA_PT_ZAV_OFFSET(vq, n) \ | |
317 | (ZA_PT_ZA_OFFSET + ((vq * __SVE_VQ_BYTES) * n)) | |
318 | ||
319 | #define ZA_PT_ZA_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES)) | |
320 | ||
321 | #define ZA_PT_SIZE(vq) \ | |
322 | (ZA_PT_ZA_OFFSET + ZA_PT_ZA_SIZE(vq)) | |
323 | #endif /* ZA_PT_SIZE */ | |
324 | ||
6ada909e | 325 | #endif /* NAT_AARCH64_SCALABLE_LINUX_SIGCONTEXT_H */ |