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