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