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
47extern "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)
67typedef long	greg_t;
68#else
69typedef int	greg_t;
70#endif
71
72#if defined(_SYSCALL32)
73
74typedef int32_t greg32_t;
75typedef int64_t greg64_t;
76
77#endif	/* _SYSCALL32 */
78
79typedef greg_t	gregset_t[_NGREG];
80
81#if defined(_SYSCALL32)
82
83#define	_NGREG32	19
84#define	_NGREG64	21
85
86typedef	greg32_t gregset32_t[_NGREG32];
87typedef 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
105struct _fpq {
106	unsigned int *fpq_addr;		/* address */
107	unsigned int fpq_instr;		/* instruction */
108};
109
110struct _fq {
111	union {				/* FPU inst/addr queue */
112		double whole;
113		struct _fpq fpq;
114	} FQu;
115};
116
117#if defined(_SYSCALL32)
118
119struct fpq32 {
120	caddr32_t	fpq_addr;	/* address */
121	uint32_t	fpq_instr;	/* instruction */
122};
123
124struct 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
148struct _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
163struct _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
177typedef struct _fpu	fpregset_t;
178
179#if defined(_SYSCALL32)
180
181/* Kernel view of user sparcv7/v8 fpu structure */
182
183struct 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
195typedef 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 */
204typedef 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 */
229typedef 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
238typedef	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 */
254typedef	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 */
273typedef 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
288typedef 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