mcontext.h revision 1.23 1 1.23 skrll /* $NetBSD: mcontext.h,v 1.23 2021/10/06 05:33:15 skrll Exp $ */
2 1.2 thorpej
3 1.2 thorpej /*-
4 1.2 thorpej * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
5 1.2 thorpej * All rights reserved.
6 1.2 thorpej *
7 1.2 thorpej * This code is derived from software contributed to The NetBSD Foundation
8 1.2 thorpej * by Klaus Klein and by Jason R. Thorpe of Wasabi Systems, Inc.
9 1.2 thorpej *
10 1.2 thorpej * Redistribution and use in source and binary forms, with or without
11 1.2 thorpej * modification, are permitted provided that the following conditions
12 1.2 thorpej * are met:
13 1.2 thorpej * 1. Redistributions of source code must retain the above copyright
14 1.2 thorpej * notice, this list of conditions and the following disclaimer.
15 1.2 thorpej * 2. Redistributions in binary form must reproduce the above copyright
16 1.2 thorpej * notice, this list of conditions and the following disclaimer in the
17 1.2 thorpej * documentation and/or other materials provided with the distribution.
18 1.2 thorpej *
19 1.2 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.2 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.2 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.2 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.2 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.2 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.2 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.2 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.2 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.2 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.2 thorpej * POSSIBILITY OF SUCH DAMAGE.
30 1.2 thorpej */
31 1.2 thorpej
32 1.2 thorpej #ifndef _ARM_MCONTEXT_H_
33 1.2 thorpej #define _ARM_MCONTEXT_H_
34 1.2 thorpej
35 1.14 christos #include <sys/stdint.h>
36 1.20 ryo
37 1.2 thorpej /*
38 1.2 thorpej * General register state
39 1.2 thorpej */
40 1.20 ryo #if defined(__aarch64__)
41 1.22 ryo #define _NGREG 35 /* GR0-30, SP, PC, SPSR, TPIDR */
42 1.20 ryo #define _NGREG32 17
43 1.20 ryo typedef __uint64_t __greg_t;
44 1.20 ryo typedef unsigned int __greg32_t;
45 1.20 ryo
46 1.20 ryo typedef __greg32_t __gregset32_t[_NGREG32];
47 1.20 ryo #elif defined(__arm__)
48 1.2 thorpej #define _NGREG 17
49 1.2 thorpej typedef unsigned int __greg_t;
50 1.20 ryo #endif
51 1.20 ryo
52 1.2 thorpej typedef __greg_t __gregset_t[_NGREG];
53 1.2 thorpej
54 1.2 thorpej #define _REG_R0 0
55 1.2 thorpej #define _REG_R1 1
56 1.2 thorpej #define _REG_R2 2
57 1.2 thorpej #define _REG_R3 3
58 1.2 thorpej #define _REG_R4 4
59 1.2 thorpej #define _REG_R5 5
60 1.2 thorpej #define _REG_R6 6
61 1.2 thorpej #define _REG_R7 7
62 1.2 thorpej #define _REG_R8 8
63 1.2 thorpej #define _REG_R9 9
64 1.2 thorpej #define _REG_R10 10
65 1.2 thorpej #define _REG_R11 11
66 1.2 thorpej #define _REG_R12 12
67 1.2 thorpej #define _REG_R13 13
68 1.2 thorpej #define _REG_R14 14
69 1.2 thorpej #define _REG_R15 15
70 1.2 thorpej #define _REG_CPSR 16
71 1.20 ryo
72 1.20 ryo #define _REG_X0 0
73 1.20 ryo #define _REG_X1 1
74 1.20 ryo #define _REG_X2 2
75 1.20 ryo #define _REG_X3 3
76 1.20 ryo #define _REG_X4 4
77 1.20 ryo #define _REG_X5 5
78 1.20 ryo #define _REG_X6 6
79 1.20 ryo #define _REG_X7 7
80 1.20 ryo #define _REG_X8 8
81 1.20 ryo #define _REG_X9 9
82 1.20 ryo #define _REG_X10 10
83 1.20 ryo #define _REG_X11 11
84 1.20 ryo #define _REG_X12 12
85 1.20 ryo #define _REG_X13 13
86 1.20 ryo #define _REG_X14 14
87 1.20 ryo #define _REG_X15 15
88 1.20 ryo #define _REG_X16 16
89 1.20 ryo #define _REG_X17 17
90 1.20 ryo #define _REG_X18 18
91 1.20 ryo #define _REG_X19 19
92 1.20 ryo #define _REG_X20 20
93 1.20 ryo #define _REG_X21 21
94 1.20 ryo #define _REG_X22 22
95 1.20 ryo #define _REG_X23 23
96 1.20 ryo #define _REG_X24 24
97 1.20 ryo #define _REG_X25 25
98 1.20 ryo #define _REG_X26 26
99 1.20 ryo #define _REG_X27 27
100 1.20 ryo #define _REG_X28 28
101 1.20 ryo #define _REG_X29 29
102 1.20 ryo #define _REG_X30 30
103 1.20 ryo #define _REG_X31 31
104 1.20 ryo #define _REG_ELR 32
105 1.20 ryo #define _REG_SPSR 33
106 1.20 ryo #define _REG_TPIDR 34
107 1.20 ryo
108 1.2 thorpej /* Convenience synonyms */
109 1.20 ryo
110 1.20 ryo #if defined(__aarch64__)
111 1.20 ryo #define _REG_RV _REG_X0
112 1.20 ryo #define _REG_FP _REG_X29
113 1.20 ryo #define _REG_LR _REG_X30
114 1.20 ryo #define _REG_SP _REG_X31
115 1.20 ryo #define _REG_PC _REG_ELR
116 1.20 ryo #elif defined(__arm__)
117 1.20 ryo #define _REG_RV _REG_R0
118 1.2 thorpej #define _REG_FP _REG_R11
119 1.2 thorpej #define _REG_SP _REG_R13
120 1.2 thorpej #define _REG_LR _REG_R14
121 1.2 thorpej #define _REG_PC _REG_R15
122 1.20 ryo #endif
123 1.2 thorpej
124 1.2 thorpej /*
125 1.2 thorpej * Floating point register state
126 1.2 thorpej */
127 1.20 ryo #if defined(__aarch64__)
128 1.20 ryo
129 1.20 ryo #define _NFREG 32 /* Number of SIMD registers */
130 1.20 ryo
131 1.20 ryo typedef struct {
132 1.20 ryo union __freg {
133 1.20 ryo __uint8_t __b8[16];
134 1.20 ryo __uint16_t __h16[8];
135 1.20 ryo __uint32_t __s32[4];
136 1.20 ryo __uint64_t __d64[2];
137 1.20 ryo __uint128_t __q128[1];
138 1.20 ryo } __qregs[_NFREG] __aligned(16);
139 1.20 ryo __uint32_t __fpcr; /* FPCR */
140 1.20 ryo __uint32_t __fpsr; /* FPSR */
141 1.20 ryo } __fregset_t;
142 1.20 ryo
143 1.20 ryo /* Compat structures */
144 1.20 ryo typedef struct {
145 1.21 ryo #if 1 /* __ARM_EABI__ is default on aarch64 */
146 1.20 ryo unsigned int __vfp_fpscr;
147 1.20 ryo uint64_t __vfp_fstmx[32];
148 1.20 ryo unsigned int __vfp_fpsid;
149 1.20 ryo #else
150 1.20 ryo unsigned int __vfp_fpscr;
151 1.20 ryo unsigned int __vfp_fstmx[33];
152 1.20 ryo unsigned int __vfp_fpsid;
153 1.20 ryo #endif
154 1.20 ryo } __vfpregset32_t;
155 1.20 ryo
156 1.20 ryo typedef struct {
157 1.20 ryo __gregset32_t __gregs;
158 1.20 ryo __vfpregset32_t __vfpregs;
159 1.20 ryo __greg32_t _mc_tlsbase;
160 1.20 ryo __greg32_t _mc_user_tpid;
161 1.20 ryo } mcontext32_t;
162 1.20 ryo
163 1.20 ryo typedef struct {
164 1.20 ryo __gregset_t __gregs; /* General Purpose Register set */
165 1.20 ryo __fregset_t __fregs; /* FPU/SIMD Register File */
166 1.20 ryo __greg_t __spare[8]; /* future proof */
167 1.20 ryo } mcontext_t;
168 1.20 ryo
169 1.20 ryo #elif defined(__arm__)
170 1.2 thorpej /* Note: the storage layout of this structure must be identical to ARMFPE! */
171 1.2 thorpej typedef struct {
172 1.2 thorpej unsigned int __fp_fpsr;
173 1.2 thorpej struct {
174 1.2 thorpej unsigned int __fp_exponent;
175 1.2 thorpej unsigned int __fp_mantissa_hi;
176 1.2 thorpej unsigned int __fp_mantissa_lo;
177 1.2 thorpej } __fp_fr[8];
178 1.2 thorpej } __fpregset_t;
179 1.2 thorpej
180 1.2 thorpej typedef struct {
181 1.13 matt #ifdef __ARM_EABI__
182 1.13 matt unsigned int __vfp_fpscr;
183 1.13 matt uint64_t __vfp_fstmx[32];
184 1.13 matt unsigned int __vfp_fpsid;
185 1.13 matt #else
186 1.2 thorpej unsigned int __vfp_fpscr;
187 1.2 thorpej unsigned int __vfp_fstmx[33];
188 1.2 thorpej unsigned int __vfp_fpsid;
189 1.13 matt #endif
190 1.2 thorpej } __vfpregset_t;
191 1.2 thorpej
192 1.2 thorpej typedef struct {
193 1.2 thorpej __gregset_t __gregs;
194 1.2 thorpej union {
195 1.2 thorpej __fpregset_t __fpregs;
196 1.2 thorpej __vfpregset_t __vfpregs;
197 1.2 thorpej } __fpu;
198 1.8 joerg __greg_t _mc_tlsbase;
199 1.18 matt __greg_t _mc_user_tpid;
200 1.11 matt } mcontext_t, mcontext32_t;
201 1.2 thorpej
202 1.8 joerg
203 1.18 matt #define _UC_MACHINE_PAD 1 /* Padding appended to ucontext_t */
204 1.2 thorpej
205 1.15 matt #ifdef __ARM_EABI__
206 1.15 matt #define __UCONTEXT_SIZE (256 + 144)
207 1.15 matt #else
208 1.7 joerg #define __UCONTEXT_SIZE 256
209 1.15 matt #endif
210 1.7 joerg
211 1.20 ryo #endif
212 1.20 ryo
213 1.20 ryo #if defined(_RTLD_SOURCE) || defined(_LIBC_SOURCE) || \
214 1.20 ryo defined(__LIBPTHREAD_SOURCE__)
215 1.20 ryo
216 1.20 ryo #include <sys/tls.h>
217 1.20 ryo
218 1.20 ryo #if defined(__aarch64__)
219 1.20 ryo
220 1.20 ryo __BEGIN_DECLS
221 1.20 ryo static __inline void *
222 1.20 ryo __lwp_getprivate_fast(void)
223 1.20 ryo {
224 1.20 ryo void *__tpidr;
225 1.20 ryo __asm __volatile("mrs\t%0, tpidr_el0" : "=r"(__tpidr));
226 1.20 ryo return __tpidr;
227 1.20 ryo }
228 1.20 ryo __END_DECLS
229 1.20 ryo
230 1.20 ryo #elif defined(__arm__)
231 1.20 ryo
232 1.17 joerg __BEGIN_DECLS
233 1.9 matt static __inline void *
234 1.9 matt __lwp_getprivate_fast(void)
235 1.9 matt {
236 1.16 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
237 1.10 matt extern void *_lwp_getprivate(void);
238 1.9 matt void *rv;
239 1.9 matt __asm("mrc p15, 0, %0, c13, c0, 3" : "=r"(rv));
240 1.10 matt if (__predict_true(rv))
241 1.10 matt return rv;
242 1.10 matt /*
243 1.10 matt * Some ARM cores are broken and don't raise an undefined fault when an
244 1.10 matt * unrecogized mrc instruction is encountered, but just return zero.
245 1.10 matt * To do deal with that, if we get a zero we (re-)fetch the value using
246 1.10 matt * syscall.
247 1.10 matt */
248 1.10 matt return _lwp_getprivate();
249 1.16 matt #else
250 1.16 matt extern void *__aeabi_read_tp(void);
251 1.16 matt return __aeabi_read_tp();
252 1.16 matt #endif /* !__thumb__ || _ARM_ARCH_T2 */
253 1.9 matt }
254 1.20 ryo __END_DECLS
255 1.20 ryo #endif
256 1.20 ryo
257 1.20 ryo #endif /* _RTLD_SOURCE || _LIBC_SOURCE || __LIBPTHREAD_SOURCE__ */
258 1.20 ryo
259 1.20 ryo /* Machine-dependent uc_flags */
260 1.20 ryo #define _UC_TLSBASE 0x00080000 /* see <sys/ucontext.h> */
261 1.20 ryo
262 1.20 ryo /* Machine-dependent uc_flags for arm */
263 1.20 ryo #define _UC_ARM_VFP 0x00010000 /* FPU field is VFP */
264 1.20 ryo
265 1.20 ryo /* used by signal delivery to indicate status of signal stack */
266 1.20 ryo #define _UC_SETSTACK 0x00020000
267 1.20 ryo #define _UC_CLRSTACK 0x00040000
268 1.20 ryo
269 1.20 ryo #define _UC_MACHINE_SP(uc) ((uc)->uc_mcontext.__gregs[_REG_SP])
270 1.20 ryo #define _UC_MACHINE_FP(uc) ((uc)->uc_mcontext.__gregs[_REG_FP])
271 1.20 ryo #define _UC_MACHINE_PC(uc) ((uc)->uc_mcontext.__gregs[_REG_PC])
272 1.20 ryo #define _UC_MACHINE_INTRV(uc) ((uc)->uc_mcontext.__gregs[_REG_RV])
273 1.20 ryo
274 1.20 ryo #define _UC_MACHINE_SET_PC(uc, pc) \
275 1.20 ryo _UC_MACHINE_PC(uc) = (pc)
276 1.9 matt
277 1.12 matt #if defined(_KERNEL)
278 1.20 ryo __BEGIN_DECLS
279 1.12 matt void vfp_getcontext(struct lwp *, mcontext_t *, int *);
280 1.23 skrll void vfp_setcontext(struct lwp *, const mcontext_t *);
281 1.20 ryo __END_DECLS
282 1.12 matt #endif
283 1.12 matt
284 1.2 thorpej #endif /* !_ARM_MCONTEXT_H_ */
285