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