xref: /illumos-gate/usr/src/uts/sparc/sys/mcontext.h (revision bc0e91320069f0bcaee43e80a7ea686d9efa2d08)
1*bc0e9132SGordon Ross /*
2*bc0e9132SGordon Ross  * CDDL HEADER START
3*bc0e9132SGordon Ross  *
4*bc0e9132SGordon Ross  * The contents of this file are subject to the terms of the
5*bc0e9132SGordon Ross  * Common Development and Distribution License (the "License").
6*bc0e9132SGordon Ross  * You may not use this file except in compliance with the License.
7*bc0e9132SGordon Ross  *
8*bc0e9132SGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*bc0e9132SGordon Ross  * or http://www.opensolaris.org/os/licensing.
10*bc0e9132SGordon Ross  * See the License for the specific language governing permissions
11*bc0e9132SGordon Ross  * and limitations under the License.
12*bc0e9132SGordon Ross  *
13*bc0e9132SGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
14*bc0e9132SGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*bc0e9132SGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
16*bc0e9132SGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
17*bc0e9132SGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
18*bc0e9132SGordon Ross  *
19*bc0e9132SGordon Ross  * CDDL HEADER END
20*bc0e9132SGordon Ross  */
21*bc0e9132SGordon Ross /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
22*bc0e9132SGordon Ross /*	All Rights Reserved	*/
23*bc0e9132SGordon Ross 
24*bc0e9132SGordon Ross 
25*bc0e9132SGordon Ross /*
26*bc0e9132SGordon Ross  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
27*bc0e9132SGordon Ross  * Use is subject to license terms.
28*bc0e9132SGordon Ross  *
29*bc0e9132SGordon Ross  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
30*bc0e9132SGordon Ross  */
31*bc0e9132SGordon Ross 
32*bc0e9132SGordon Ross /*
33*bc0e9132SGordon Ross  * Essential struct definitions for mcontext_t needed by ucontext.h
34*bc0e9132SGordon Ross  * These were formerly in regset.h, which now includes this file.
35*bc0e9132SGordon Ross  */
36*bc0e9132SGordon Ross 
37*bc0e9132SGordon Ross #ifndef	_SYS_MCONTEXT_H
38*bc0e9132SGordon Ross #define	_SYS_MCONTEXT_H
39*bc0e9132SGordon Ross 
40*bc0e9132SGordon Ross #include <sys/feature_tests.h>
41*bc0e9132SGordon Ross 
42*bc0e9132SGordon Ross #if !defined(_ASM)
43*bc0e9132SGordon Ross #include <sys/int_types.h>
44*bc0e9132SGordon Ross #endif
45*bc0e9132SGordon Ross 
46*bc0e9132SGordon Ross #ifdef	__cplusplus
47*bc0e9132SGordon Ross extern "C" {
48*bc0e9132SGordon Ross #endif
49*bc0e9132SGordon Ross 
50*bc0e9132SGordon Ross /*
51*bc0e9132SGordon Ross  * A gregset_t is defined as an array type for compatibility with the reference
52*bc0e9132SGordon Ross  * source. This is important due to differences in the way the C language
53*bc0e9132SGordon Ross  * treats arrays and structures as parameters.
54*bc0e9132SGordon Ross  *
55*bc0e9132SGordon Ross  * Note that NGREG is really (sizeof (struct regs) / sizeof (greg_t)),
56*bc0e9132SGordon Ross  * but that the SPARC V8 ABI defines it absolutely to be 19.
57*bc0e9132SGordon Ross  */
58*bc0e9132SGordon Ross #if defined(__sparcv9)
59*bc0e9132SGordon Ross #define	_NGREG	21
60*bc0e9132SGordon Ross #else	/* __sparcv9 */
61*bc0e9132SGordon Ross #define	_NGREG	19
62*bc0e9132SGordon Ross #endif	/* __sparcv9 */
63*bc0e9132SGordon Ross 
64*bc0e9132SGordon Ross #ifndef	_ASM
65*bc0e9132SGordon Ross 
66*bc0e9132SGordon Ross #if defined(_LP64) || defined(_I32LPx)
67*bc0e9132SGordon Ross typedef long	greg_t;
68*bc0e9132SGordon Ross #else
69*bc0e9132SGordon Ross typedef int	greg_t;
70*bc0e9132SGordon Ross #endif
71*bc0e9132SGordon Ross 
72*bc0e9132SGordon Ross #if defined(_SYSCALL32)
73*bc0e9132SGordon Ross 
74*bc0e9132SGordon Ross typedef int32_t greg32_t;
75*bc0e9132SGordon Ross typedef int64_t greg64_t;
76*bc0e9132SGordon Ross 
77*bc0e9132SGordon Ross #endif	/* _SYSCALL32 */
78*bc0e9132SGordon Ross 
79*bc0e9132SGordon Ross typedef greg_t	gregset_t[_NGREG];
80*bc0e9132SGordon Ross 
81*bc0e9132SGordon Ross #if defined(_SYSCALL32)
82*bc0e9132SGordon Ross 
83*bc0e9132SGordon Ross #define	_NGREG32	19
84*bc0e9132SGordon Ross #define	_NGREG64	21
85*bc0e9132SGordon Ross 
86*bc0e9132SGordon Ross typedef	greg32_t gregset32_t[_NGREG32];
87*bc0e9132SGordon Ross typedef greg64_t gregset64_t[_NGREG64];
88*bc0e9132SGordon Ross 
89*bc0e9132SGordon Ross #endif	/* _SYSCALL32 */
90*bc0e9132SGordon Ross 
91*bc0e9132SGordon Ross /*
92*bc0e9132SGordon Ross  * Floating point definitions.
93*bc0e9132SGordon Ross  */
94*bc0e9132SGordon Ross 
95*bc0e9132SGordon Ross #define	_MAXFPQ	16	/* max # of fpu queue entries currently supported */
96*bc0e9132SGordon Ross 
97*bc0e9132SGordon Ross /*
98*bc0e9132SGordon Ross  * struct _fq defines the minimal format of a floating point instruction queue
99*bc0e9132SGordon Ross  * entry. The size of entries in the floating point queue are implementation
100*bc0e9132SGordon Ross  * dependent. The union FQu is guarenteed to be the first field in any ABI
101*bc0e9132SGordon Ross  * conformant system implementation. Any additional fields provided by an
102*bc0e9132SGordon Ross  * implementation should not be used applications designed to be ABI conformant.
103*bc0e9132SGordon Ross  */
104*bc0e9132SGordon Ross 
105*bc0e9132SGordon Ross struct _fpq {
106*bc0e9132SGordon Ross 	unsigned int *fpq_addr;		/* address */
107*bc0e9132SGordon Ross 	unsigned int fpq_instr;		/* instruction */
108*bc0e9132SGordon Ross };
109*bc0e9132SGordon Ross 
110*bc0e9132SGordon Ross struct _fq {
111*bc0e9132SGordon Ross 	union {				/* FPU inst/addr queue */
112*bc0e9132SGordon Ross 		double whole;
113*bc0e9132SGordon Ross 		struct _fpq fpq;
114*bc0e9132SGordon Ross 	} FQu;
115*bc0e9132SGordon Ross };
116*bc0e9132SGordon Ross 
117*bc0e9132SGordon Ross #if defined(_SYSCALL32)
118*bc0e9132SGordon Ross 
119*bc0e9132SGordon Ross struct fpq32 {
120*bc0e9132SGordon Ross 	caddr32_t	fpq_addr;	/* address */
121*bc0e9132SGordon Ross 	uint32_t	fpq_instr;	/* instruction */
122*bc0e9132SGordon Ross };
123*bc0e9132SGordon Ross 
124*bc0e9132SGordon Ross struct fq32 {
125*bc0e9132SGordon Ross 	union {				/* FPU inst/addr queue */
126*bc0e9132SGordon Ross 		double whole;
127*bc0e9132SGordon Ross 		struct fpq32 fpq;
128*bc0e9132SGordon Ross 	} FQu;
129*bc0e9132SGordon Ross };
130*bc0e9132SGordon Ross 
131*bc0e9132SGordon Ross #endif	/* _SYSCALL32 */
132*bc0e9132SGordon Ross 
133*bc0e9132SGordon Ross /*
134*bc0e9132SGordon Ross  * struct fpu is the floating point processor state. struct fpu is the sum
135*bc0e9132SGordon Ross  * total of all possible floating point state which includes the state of
136*bc0e9132SGordon Ross  * external floating point hardware, fpa registers, etc..., if it exists.
137*bc0e9132SGordon Ross  *
138*bc0e9132SGordon Ross  * A floating point instuction queue may or may not be associated with
139*bc0e9132SGordon Ross  * the floating point processor state. If a queue does exist, the field
140*bc0e9132SGordon Ross  * fpu_q will point to an array of fpu_qcnt entries where each entry is
141*bc0e9132SGordon Ross  * fpu_q_entrysize long. fpu_q_entry has a lower bound of sizeof (union FQu)
142*bc0e9132SGordon Ross  * and no upper bound. If no floating point queue entries are associated
143*bc0e9132SGordon Ross  * with the processor state, fpu_qcnt will be zeo and fpu_q will be NULL.
144*bc0e9132SGordon Ross  */
145*bc0e9132SGordon Ross 
146*bc0e9132SGordon Ross #if defined(__sparcv9)
147*bc0e9132SGordon Ross 
148*bc0e9132SGordon Ross struct _fpu {
149*bc0e9132SGordon Ross 	union {					/* FPU floating point regs */
150*bc0e9132SGordon Ross 		uint32_t	fpu_regs[32];	/* 32 singles */
151*bc0e9132SGordon Ross 		double		fpu_dregs[32];	/* 32 doubles */
152*bc0e9132SGordon Ross 		long double	fpu_qregs[16];	/* 16 quads */
153*bc0e9132SGordon Ross 	} fpu_fr;
154*bc0e9132SGordon Ross 	struct _fq	*fpu_q;			/* ptr to array of FQ entries */
155*bc0e9132SGordon Ross 	uint64_t	fpu_fsr;		/* FPU status register */
156*bc0e9132SGordon Ross 	uint8_t		fpu_qcnt;		/* # of entries in saved FQ */
157*bc0e9132SGordon Ross 	uint8_t		fpu_q_entrysize;	/* # of bytes per FQ entry */
158*bc0e9132SGordon Ross 	uint8_t		fpu_en;			/* flag specifying fpu in use */
159*bc0e9132SGordon Ross };
160*bc0e9132SGordon Ross 
161*bc0e9132SGordon Ross #else	/* __sparcv9 */
162*bc0e9132SGordon Ross 
163*bc0e9132SGordon Ross struct _fpu {
164*bc0e9132SGordon Ross 	union {					/* FPU floating point regs */
165*bc0e9132SGordon Ross 		uint32_t	fpu_regs[32];	/* 32 singles */
166*bc0e9132SGordon Ross 		double		fpu_dregs[16];	/* 16 doubles */
167*bc0e9132SGordon Ross 	} fpu_fr;
168*bc0e9132SGordon Ross 	struct _fq	*fpu_q;			/* ptr to array of FQ entries */
169*bc0e9132SGordon Ross 	uint32_t	fpu_fsr;		/* FPU status register */
170*bc0e9132SGordon Ross 	uint8_t		fpu_qcnt;		/* # of entries in saved FQ */
171*bc0e9132SGordon Ross 	uint8_t		fpu_q_entrysize;	/* # of bytes per FQ entry */
172*bc0e9132SGordon Ross 	uint8_t		fpu_en;			/* flag signifying fpu in use */
173*bc0e9132SGordon Ross };
174*bc0e9132SGordon Ross 
175*bc0e9132SGordon Ross #endif	/* __sparcv9 */
176*bc0e9132SGordon Ross 
177*bc0e9132SGordon Ross typedef struct _fpu	fpregset_t;
178*bc0e9132SGordon Ross 
179*bc0e9132SGordon Ross #if defined(_SYSCALL32)
180*bc0e9132SGordon Ross 
181*bc0e9132SGordon Ross /* Kernel view of user sparcv7/v8 fpu structure */
182*bc0e9132SGordon Ross 
183*bc0e9132SGordon Ross struct fpu32 {
184*bc0e9132SGordon Ross 	union {					/* FPU floating point regs */
185*bc0e9132SGordon Ross 		uint32_t	fpu_regs[32];	/* 32 singles */
186*bc0e9132SGordon Ross 		double		fpu_dregs[16];	/* 16 doubles */
187*bc0e9132SGordon Ross 	} fpu_fr;
188*bc0e9132SGordon Ross 	caddr32_t	fpu_q;			/* ptr to array of FQ entries */
189*bc0e9132SGordon Ross 	uint32_t	fpu_fsr;		/* FPU status register */
190*bc0e9132SGordon Ross 	uint8_t		fpu_qcnt;		/* # of entries in saved FQ */
191*bc0e9132SGordon Ross 	uint8_t		fpu_q_entrysize;	/* # of bytes per FQ entry */
192*bc0e9132SGordon Ross 	uint8_t		fpu_en;			/* flag signifying fpu in use */
193*bc0e9132SGordon Ross };
194*bc0e9132SGordon Ross 
195*bc0e9132SGordon Ross typedef struct fpu32	fpregset32_t;
196*bc0e9132SGordon Ross 
197*bc0e9132SGordon Ross #endif	/* _SYSCALL32 */
198*bc0e9132SGordon Ross 
199*bc0e9132SGordon Ross #if defined(_KERNEL) || defined(_KMDB)
200*bc0e9132SGordon Ross /*
201*bc0e9132SGordon Ross  * The ABI uses struct fpu, so we use this to describe the kernel's view of the
202*bc0e9132SGordon Ross  * fpu.
203*bc0e9132SGordon Ross  */
204*bc0e9132SGordon Ross typedef struct {
205*bc0e9132SGordon Ross 	union _fpu_fr {				/* V9 FPU floating point regs */
206*bc0e9132SGordon Ross 		uint32_t	fpu_regs[32];	/* 32 singles */
207*bc0e9132SGordon Ross 		uint64_t	fpu_dregs[32];	/* 32 doubles */
208*bc0e9132SGordon Ross 		long double	fpu_qregs[16];	/* 16 quads */
209*bc0e9132SGordon Ross 	} fpu_fr;
210*bc0e9132SGordon Ross 	uint64_t	fpu_fsr;		/* FPU status register */
211*bc0e9132SGordon Ross 	uint32_t	 fpu_fprs;		/* fprs register */
212*bc0e9132SGordon Ross 	struct _fq	*fpu_q;
213*bc0e9132SGordon Ross 	uint8_t		fpu_qcnt;
214*bc0e9132SGordon Ross 	uint8_t		fpu_q_entrysize;
215*bc0e9132SGordon Ross 	uint8_t		fpu_en;			/* flag signifying fpu in use */
216*bc0e9132SGordon Ross } kfpu_t;
217*bc0e9132SGordon Ross #endif /* _KERNEL || _KMDB */
218*bc0e9132SGordon Ross 
219*bc0e9132SGordon Ross /*
220*bc0e9132SGordon Ross  * The following structure is for associating extra register state with
221*bc0e9132SGordon Ross  * the ucontext structure and is kept within the uc_mcontext filler area.
222*bc0e9132SGordon Ross  *
223*bc0e9132SGordon Ross  * If (xrs_id == XRS_ID) then the xrs_ptr field is a valid pointer to
224*bc0e9132SGordon Ross  * extra register state. The exact format of the extra register state
225*bc0e9132SGordon Ross  * pointed to by xrs_ptr is platform-dependent.
226*bc0e9132SGordon Ross  *
227*bc0e9132SGordon Ross  * Note: a platform may or may not manage extra register state.
228*bc0e9132SGordon Ross  */
229*bc0e9132SGordon Ross typedef struct {
230*bc0e9132SGordon Ross 	unsigned int	xrs_id;		/* indicates xrs_ptr validity */
231*bc0e9132SGordon Ross 	caddr_t		xrs_ptr;	/* ptr to extra reg state */
232*bc0e9132SGordon Ross } xrs_t;
233*bc0e9132SGordon Ross 
234*bc0e9132SGordon Ross #define	_XRS_ID			0x78727300	/* the string "xrs" */
235*bc0e9132SGordon Ross 
236*bc0e9132SGordon Ross #if defined(_SYSCALL32)
237*bc0e9132SGordon Ross 
238*bc0e9132SGordon Ross typedef	struct {
239*bc0e9132SGordon Ross 	uint32_t	xrs_id;		/* indicates xrs_ptr validity */
240*bc0e9132SGordon Ross 	caddr32_t	xrs_ptr;	/* ptr to extra reg state */
241*bc0e9132SGordon Ross } xrs32_t;
242*bc0e9132SGordon Ross 
243*bc0e9132SGordon Ross #endif	/* _SYSCALL32 */
244*bc0e9132SGordon Ross 
245*bc0e9132SGordon Ross #if defined(__sparcv9)
246*bc0e9132SGordon Ross 
247*bc0e9132SGordon Ross /*
248*bc0e9132SGordon Ross  * Ancillary State Registers
249*bc0e9132SGordon Ross  *
250*bc0e9132SGordon Ross  * The SPARC V9 architecture defines 25 ASRs, numbered from 7 through 31.
251*bc0e9132SGordon Ross  * ASRs 16 through 31 are available to user programs, though the meaning
252*bc0e9132SGordon Ross  * and content of these registers is implementation dependent.
253*bc0e9132SGordon Ross  */
254*bc0e9132SGordon Ross typedef	int64_t	asrset_t[16];	/* %asr16 - > %asr31 */
255*bc0e9132SGordon Ross 
256*bc0e9132SGordon Ross #endif	/* __sparcv9 */
257*bc0e9132SGordon Ross 
258*bc0e9132SGordon Ross /*
259*bc0e9132SGordon Ross  * Structure mcontext defines the complete hardware machine state. If
260*bc0e9132SGordon Ross  * the field `gwins' is non NULL, it points to a save area for register
261*bc0e9132SGordon Ross  * window frames. If `gwins' is NULL, the register windows were saved
262*bc0e9132SGordon Ross  * on the user's stack.
263*bc0e9132SGordon Ross  *
264*bc0e9132SGordon Ross  * The filler of 21 longs is historical (now filler[19] plus the xrs_t
265*bc0e9132SGordon Ross  * field). The value was selected to provide binary compatibility with
266*bc0e9132SGordon Ross  * statically linked ICL binaries. It is in the ABI (do not change). It
267*bc0e9132SGordon Ross  * actually appears in the ABI as a single filler of 44 is in the field
268*bc0e9132SGordon Ross  * uc_filler of struct ucontext. It is split here so that ucontext.h can
269*bc0e9132SGordon Ross  * (hopefully) remain architecture independent.
270*bc0e9132SGordon Ross  *
271*bc0e9132SGordon Ross  * Note that 2 longs of the filler are used to hold extra register state info.
272*bc0e9132SGordon Ross  */
273*bc0e9132SGordon Ross typedef struct {
274*bc0e9132SGordon Ross 	gregset_t	gregs;	/* general register set */
275*bc0e9132SGordon Ross 	struct _gwindows *gwins; /* POSSIBLE pointer to register windows */
276*bc0e9132SGordon Ross 	fpregset_t	fpregs;	/* floating point register set */
277*bc0e9132SGordon Ross 	xrs_t		xrs;	/* POSSIBLE extra register state association */
278*bc0e9132SGordon Ross #if defined(__sparcv9)
279*bc0e9132SGordon Ross 	asrset_t	asrs;		/* ancillary registers */
280*bc0e9132SGordon Ross 	long		filler[4];	/* room for expansion */
281*bc0e9132SGordon Ross #else	/* __sparcv9 */
282*bc0e9132SGordon Ross 	long		filler[19];
283*bc0e9132SGordon Ross #endif	/* __sparcv9 */
284*bc0e9132SGordon Ross } mcontext_t;
285*bc0e9132SGordon Ross 
286*bc0e9132SGordon Ross #if defined(_SYSCALL32)
287*bc0e9132SGordon Ross 
288*bc0e9132SGordon Ross typedef struct {
289*bc0e9132SGordon Ross 	gregset32_t	gregs;	/* general register set */
290*bc0e9132SGordon Ross 	caddr32_t	gwins;	/* POSSIBLE pointer to register windows */
291*bc0e9132SGordon Ross 	fpregset32_t	fpregs;	/* floating point register set */
292*bc0e9132SGordon Ross 	xrs32_t		xrs;	/* POSSIBLE extra register state association */
293*bc0e9132SGordon Ross 	int32_t		filler[19];
294*bc0e9132SGordon Ross } mcontext32_t;
295*bc0e9132SGordon Ross 
296*bc0e9132SGordon Ross #endif /* _SYSCALL32 */
297*bc0e9132SGordon Ross 
298*bc0e9132SGordon Ross #endif	/* _ASM */
299*bc0e9132SGordon Ross 
300*bc0e9132SGordon Ross #ifdef	__cplusplus
301*bc0e9132SGordon Ross }
302*bc0e9132SGordon Ross #endif
303*bc0e9132SGordon Ross 
304*bc0e9132SGordon Ross #endif	/* _SYS_MCONTEXT_H */
305