xref: /illumos-gate/usr/src/uts/sparc/sys/regset.h (revision 61679b0b6826b0ae7e3f751acd91412fcfa45d1e)
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 
30 #ifndef	_SYS_REGSET_H
31 #define	_SYS_REGSET_H
32 
33 #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.1	*/
34 
35 #include <sys/feature_tests.h>
36 
37 #if !defined(_ASM)
38 #include <sys/int_types.h>
39 #endif
40 
41 #ifdef	__cplusplus
42 extern "C" {
43 #endif
44 
45 /*
46  * Location of the users' stored registers relative to R0.
47  * Usage is as an index into a gregset_t array or as u.u_ar0[XX].
48  */
49 #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
50 
51 #if defined(__sparcv9)
52 #define	REG_CCR (0)
53 #if defined(_SYSCALL32)
54 #define	REG_PSR (0)
55 #endif /* _SYSCALL32 */
56 #else
57 #define	REG_PSR (0)
58 #endif  /* __sparcv9 */
59 
60 #define	REG_PC	(1)
61 #define	REG_nPC	(2)
62 #define	REG_Y	(3)
63 #define	REG_G1	(4)
64 #define	REG_G2	(5)
65 #define	REG_G3	(6)
66 #define	REG_G4	(7)
67 #define	REG_G5	(8)
68 #define	REG_G6	(9)
69 #define	REG_G7	(10)
70 #define	REG_O0	(11)
71 #define	REG_O1	(12)
72 #define	REG_O2	(13)
73 #define	REG_O3	(14)
74 #define	REG_O4	(15)
75 #define	REG_O5	(16)
76 #define	REG_O6	(17)
77 #define	REG_O7	(18)
78 #if defined(__sparcv9)
79 #define	REG_ASI	(19)
80 #define	REG_FPRS (20)
81 #endif	/* __sparcv9 */
82 
83 /* the following defines are for portability */
84 #if !defined(__sparcv9)
85 #define	REG_PS	REG_PSR
86 #endif	/* __sparcv9 */
87 #define	REG_SP	REG_O6
88 #define	REG_R0	REG_O0
89 #define	REG_R1	REG_O1
90 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
91 
92 /*
93  * A gregset_t is defined as an array type for compatibility with the reference
94  * source. This is important due to differences in the way the C language
95  * treats arrays and structures as parameters.
96  *
97  * Note that NGREG is really (sizeof (struct regs) / sizeof (greg_t)),
98  * but that the SPARC V8 ABI defines it absolutely to be 19.
99  */
100 #if defined(__sparcv9)
101 #define	_NGREG	21
102 #else	/* __sparcv9 */
103 #define	_NGREG	19
104 #endif	/* __sparcv9 */
105 #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
106 #define	NGREG	_NGREG
107 #endif
108 
109 #ifndef	_ASM
110 
111 #if defined(_LP64) || defined(_I32LPx)
112 typedef long	greg_t;
113 #else
114 typedef int	greg_t;
115 #endif
116 
117 #if defined(_SYSCALL32)
118 
119 typedef int32_t greg32_t;
120 typedef int64_t greg64_t;
121 
122 #endif	/* _SYSCALL32 */
123 
124 typedef greg_t	gregset_t[_NGREG];
125 
126 #if defined(_SYSCALL32)
127 
128 #define	_NGREG32	19
129 #define	_NGREG64	21
130 
131 typedef	greg32_t gregset32_t[_NGREG32];
132 typedef greg64_t gregset64_t[_NGREG64];
133 
134 #endif	/* _SYSCALL32 */
135 
136 #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
137 /*
138  * The following structures define how a register window can appear on the
139  * stack. This structure is available (when required) through the `gwins'
140  * field of an mcontext (nested within ucontext). SPARC_MAXWINDOW is the
141  * maximum number of outstanding regiters window defined in the SPARC
142  * architecture (*not* implementation).
143  */
144 #define	SPARC_MAXREGWINDOW	31	/* max windows in SPARC arch. */
145 
146 struct rwindow {
147 	greg_t	rw_local[8];		/* locals */
148 	greg_t	rw_in[8];		/* ins */
149 };
150 
151 #if defined(_SYSCALL32)
152 
153 struct rwindow32 {
154 	greg32_t rw_local[8];		/* locals */
155 	greg32_t rw_in[8];		/* ins */
156 };
157 
158 struct rwindow64 {
159 	greg64_t rw_local[8];		/* locals */
160 	greg64_t rw_in[8];		/* ins */
161 };
162 
163 #if defined(_KERNEL)
164 extern	void	rwindow_nto32(struct rwindow *, struct rwindow32 *);
165 extern	void	rwindow_32ton(struct rwindow32 *, struct rwindow *);
166 #endif
167 
168 #endif	/* _SYSCALL32 */
169 
170 #define	rw_fp	rw_in[6]		/* frame pointer */
171 #define	rw_rtn	rw_in[7]		/* return address */
172 
173 typedef struct gwindows {
174 	int		wbcnt;
175 	greg_t		*spbuf[SPARC_MAXREGWINDOW];
176 	struct rwindow	wbuf[SPARC_MAXREGWINDOW];
177 } gwindows_t;
178 
179 #if defined(_SYSCALL32)
180 
181 typedef struct gwindows32 {
182 	int32_t		wbcnt;
183 	caddr32_t	spbuf[SPARC_MAXREGWINDOW];
184 	struct rwindow32 wbuf[SPARC_MAXREGWINDOW];
185 } gwindows32_t;
186 
187 typedef struct gwindows64 {
188 	int		wbcnt;
189 	greg64_t	*spbuf[SPARC_MAXREGWINDOW];
190 	struct rwindow64 wbuf[SPARC_MAXREGWINDOW];
191 } gwindows64_t;
192 
193 #endif	/* _SYSCALL32 */
194 
195 
196 /*
197  * Floating point definitions.
198  */
199 
200 #define	MAXFPQ	16	/* max # of fpu queue entries currently supported */
201 
202 /*
203  * struct fq defines the minimal format of a floating point instruction queue
204  * entry. The size of entries in the floating point queue are implementation
205  * dependent. The union FQu is guarenteed to be the first field in any ABI
206  * conformant system implementation. Any additional fields provided by an
207  * implementation should not be used applications designed to be ABI conformant.
208  */
209 
210 struct fpq {
211 	unsigned int *fpq_addr;		/* address */
212 	unsigned int fpq_instr;		/* instruction */
213 };
214 
215 struct fq {
216 	union {				/* FPU inst/addr queue */
217 		double whole;
218 		struct fpq fpq;
219 	} FQu;
220 };
221 
222 #if defined(_SYSCALL32)
223 
224 struct fpq32 {
225 	caddr32_t	fpq_addr;	/* address */
226 	uint32_t	fpq_instr;	/* instruction */
227 };
228 
229 struct fq32 {
230 	union {				/* FPU inst/addr queue */
231 		double whole;
232 		struct fpq32 fpq;
233 	} FQu;
234 };
235 
236 #endif	/* _SYSCALL32 */
237 
238 /*
239  * struct fpu is the floating point processor state. struct fpu is the sum
240  * total of all possible floating point state which includes the state of
241  * external floating point hardware, fpa registers, etc..., if it exists.
242  *
243  * A floating point instuction queue may or may not be associated with
244  * the floating point processor state. If a queue does exist, the field
245  * fpu_q will point to an array of fpu_qcnt entries where each entry is
246  * fpu_q_entrysize long. fpu_q_entry has a lower bound of sizeof (union FQu)
247  * and no upper bound. If no floating point queue entries are associated
248  * with the processor state, fpu_qcnt will be zeo and fpu_q will be NULL.
249  */
250 
251 /*
252  * The following #define's are obsolete and may be removed in a future release.
253  * The corresponding integer types should be used instead (i.e. uint64_t).
254  */
255 #define	FPU_REGS_TYPE		uint32_t
256 #define	FPU_DREGS_TYPE		uint64_t
257 #define	V7_FPU_FSR_TYPE		uint32_t
258 #define	V9_FPU_FSR_TYPE		uint64_t
259 #define	V9_FPU_FPRS_TYPE	uint32_t
260 
261 #if defined(__sparcv9)
262 
263 struct fpu {
264 	union {					/* FPU floating point regs */
265 		uint32_t	fpu_regs[32];	/* 32 singles */
266 		double		fpu_dregs[32];	/* 32 doubles */
267 		long double	fpu_qregs[16];	/* 16 quads */
268 	} fpu_fr;
269 	struct fq	*fpu_q;			/* ptr to array of FQ entries */
270 	uint64_t	fpu_fsr;		/* FPU status register */
271 	uint8_t		fpu_qcnt;		/* # of entries in saved FQ */
272 	uint8_t		fpu_q_entrysize;	/* # of bytes per FQ entry */
273 	uint8_t		fpu_en;			/* flag specifying fpu in use */
274 };
275 
276 #else	/* __sparcv9 */
277 
278 struct fpu {
279 	union {					/* FPU floating point regs */
280 		uint32_t	fpu_regs[32];	/* 32 singles */
281 		double		fpu_dregs[16];	/* 16 doubles */
282 	} fpu_fr;
283 	struct fq	*fpu_q;			/* ptr to array of FQ entries */
284 	uint32_t	fpu_fsr;		/* FPU status register */
285 	uint8_t		fpu_qcnt;		/* # of entries in saved FQ */
286 	uint8_t		fpu_q_entrysize;	/* # of bytes per FQ entry */
287 	uint8_t		fpu_en;			/* flag signifying fpu in use */
288 };
289 
290 #endif	/* __sparcv9 */
291 
292 typedef struct fpu	fpregset_t;
293 
294 #if defined(_SYSCALL32)
295 
296 /* Kernel view of user sparcv7/v8 fpu structure */
297 
298 struct fpu32 {
299 	union {					/* FPU floating point regs */
300 		uint32_t	fpu_regs[32];	/* 32 singles */
301 		double		fpu_dregs[16];	/* 16 doubles */
302 	} fpu_fr;
303 	caddr32_t	fpu_q;			/* ptr to array of FQ entries */
304 	uint32_t	fpu_fsr;		/* FPU status register */
305 	uint8_t		fpu_qcnt;		/* # of entries in saved FQ */
306 	uint8_t		fpu_q_entrysize;	/* # of bytes per FQ entry */
307 	uint8_t		fpu_en;			/* flag signifying fpu in use */
308 };
309 
310 typedef struct fpu32	fpregset32_t;
311 
312 #endif	/* _SYSCALL32 */
313 
314 #if defined(_KERNEL) || defined(_KMDB)
315 /*
316  * The ABI uses struct fpu, so we use this to describe the kernel's view of the
317  * fpu.
318  */
319 typedef struct {
320 	union _fpu_fr {				/* V9 FPU floating point regs */
321 		uint32_t	fpu_regs[32];	/* 32 singles */
322 		uint64_t	fpu_dregs[32];	/* 32 doubles */
323 		long double	fpu_qregs[16];	/* 16 quads */
324 	} fpu_fr;
325 	uint64_t	fpu_fsr;		/* FPU status register */
326 	uint32_t	 fpu_fprs;		/* fprs register */
327 	struct fq	*fpu_q;
328 	uint8_t		fpu_qcnt;
329 	uint8_t		fpu_q_entrysize;
330 	uint8_t		fpu_en;			/* flag signifying fpu in use */
331 } kfpu_t;
332 #endif /* _KERNEL || _KMDB */
333 
334 /*
335  * The following structure is for associating extra register state with
336  * the ucontext structure and is kept within the uc_mcontext filler area.
337  *
338  * If (xrs_id == XRS_ID) then the xrs_ptr field is a valid pointer to
339  * extra register state. The exact format of the extra register state
340  * pointed to by xrs_ptr is platform-dependent.
341  *
342  * Note: a platform may or may not manage extra register state.
343  */
344 typedef struct {
345 	unsigned int	xrs_id;		/* indicates xrs_ptr validity */
346 	caddr_t		xrs_ptr;	/* ptr to extra reg state */
347 } xrs_t;
348 
349 #define	XRS_ID			0x78727300	/* the string "xrs" */
350 
351 #if defined(_SYSCALL32)
352 
353 typedef	struct {
354 	uint32_t	xrs_id;		/* indicates xrs_ptr validity */
355 	caddr32_t	xrs_ptr;	/* ptr to extra reg state */
356 } xrs32_t;
357 
358 #endif	/* _SYSCALL32 */
359 
360 #if defined(__sparcv9)
361 
362 /*
363  * Ancillary State Registers
364  *
365  * The SPARC V9 architecture defines 25 ASRs, numbered from 7 through 31.
366  * ASRs 16 through 31 are available to user programs, though the meaning
367  * and content of these registers is implementation dependent.
368  */
369 typedef	int64_t	asrset_t[16];	/* %asr16 - > %asr31 */
370 
371 #endif	/* __sparcv9 */
372 
373 /*
374  * Structure mcontext defines the complete hardware machine state. If
375  * the field `gwins' is non NULL, it points to a save area for register
376  * window frames. If `gwins' is NULL, the register windows were saved
377  * on the user's stack.
378  *
379  * The filler of 21 longs is historical (now filler[19] plus the xrs_t
380  * field). The value was selected to provide binary compatibility with
381  * statically linked ICL binaries. It is in the ABI (do not change). It
382  * actually appears in the ABI as a single filler of 44 is in the field
383  * uc_filler of struct ucontext. It is split here so that ucontext.h can
384  * (hopefully) remain architecture independent.
385  *
386  * Note that 2 longs of the filler are used to hold extra register state info.
387  */
388 typedef struct {
389 	gregset_t	gregs;	/* general register set */
390 	gwindows_t	*gwins;	/* POSSIBLE pointer to register windows */
391 	fpregset_t	fpregs;	/* floating point register set */
392 	xrs_t		xrs;	/* POSSIBLE extra register state association */
393 #if defined(__sparcv9)
394 	asrset_t	asrs;		/* ancillary registers */
395 	long		filler[4];	/* room for expansion */
396 #else	/* __sparcv9 */
397 	long		filler[19];
398 #endif	/* __sparcv9 */
399 } mcontext_t;
400 
401 #if defined(_SYSCALL32)
402 
403 typedef struct {
404 	gregset32_t	gregs;	/* general register set */
405 	caddr32_t	gwins;	/* POSSIBLE pointer to register windows */
406 	fpregset32_t	fpregs;	/* floating point register set */
407 	xrs32_t		xrs;	/* POSSIBLE extra register state association */
408 	int32_t		filler[19];
409 } mcontext32_t;
410 
411 #endif /* _SYSCALL32 */
412 
413 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
414 #endif	/* _ASM */
415 
416 /*
417  * The version of privregs.h that is used on implementations that run
418  * on processors that support the V9 instruction set is deliberately not
419  * imported here.
420  *
421  * The V9 'struct regs' definition is -not- compatible with either 32-bit
422  * or 64-bit core file contents, nor with the ucontext.  As a result, the
423  * 'regs' structure cannot be used portably by applications, and should
424  * only be used by the kernel implementation.
425  *
426  * The inclusion of the SPARC V7 version of privregs.h allows for some
427  * limited source compatibility with 32-bit applications who expect to use
428  * 'struct regs' to match the content of a 32-bit core file, or a ucontext_t.
429  *
430  * Note that the ucontext_t actually describes the general registers in
431  * terms of the gregset_t data type, as described in this file.  Note also
432  * that the core file content is defined by core(4) in terms of data types
433  * defined by procfs -- see proc(4).
434  */
435 #if !defined(__sparcv9)
436 #if !defined(_KERNEL) && !defined(_XPG4_2) || defined(__EXTENSIONS__)
437 #include <v7/sys/privregs.h>
438 #endif	/* !_KERNEL && !_XPG4_2 || __EXTENSIONS__ */
439 #endif	/* __sparcv9 */
440 
441 /*
442  * The following is here for XPG4.2 standards compliance.
443  * regset.h is included in ucontext.h for the definition of
444  * mcontext_t, all of which breaks XPG4.2 namespace.
445  */
446 
447 #if defined(_XPG4_2) && !defined(__EXTENSIONS__)
448 /*
449  * The following is here for UNIX 95 compliance (XPG Issue 4, Version 2
450  * System Interfaces and Headers. The structures included here are identical
451  * to those visible elsewhere in this header except that the structure
452  * element names have been changed in accordance with the X/Open namespace
453  * rules.  Specifically, depending on the name and scope, the names have
454  * been prepended with a single or double underscore (_ or __).  See the
455  * structure definitions in the non-X/Open namespace for more detailed
456  * comments describing each of these structures.
457  */
458 
459 #ifndef	_ASM
460 
461 /*
462  * The following structures define how a register window can appear on the
463  * stack.
464  */
465 #define	_SPARC_MAXREGWINDOW	31		/* max windows in SPARC arch. */
466 
467 struct	__rwindow {
468 	greg_t	__rw_local[8];		/* locals */
469 	greg_t	__rw_in[8];		/* ins */
470 };
471 
472 #define	__rw_fp		__rw_in[6]		/* frame pointer */
473 #define	__rw_rtn	__rw_in[7]		/* return address */
474 
475 struct __gwindows {
476 	int		__wbcnt;
477 	greg_t		*__spbuf[_SPARC_MAXREGWINDOW];
478 	struct __rwindow	__wbuf[_SPARC_MAXREGWINDOW];
479 };
480 
481 typedef struct __gwindows	gwindows_t;
482 
483 /*
484  * The fq structure defines the minimal format of a floating point
485  * instruction queue entry.
486  */
487 
488 struct __fpq {
489 	unsigned int *__fpq_addr;	/* address */
490 	unsigned int __fpq_instr;	/* instruction */
491 };
492 
493 struct __fq {
494 	union {				/* FPU inst/addr queue */
495 		double __whole;
496 		struct __fpq __fpq;
497 	} _FQu;
498 };
499 
500 /*
501  * The fpu structure is the floating point processor state.
502  */
503 
504 /*
505  * The following #define's are obsolete and may be removed in a future release.
506  * The corresponding integer types should be used instead (i.e. uint64_t).
507  */
508 #define	_FPU_REGS_TYPE		uint32_t
509 #define	_FPU_DREGS_TYPE		uint64_t
510 #define	_V7_FPU_FSR_TYPE	uint32_t
511 #define	_V9_FPU_FSR_TYPE	uint64_t
512 #define	_V9_FPU_FPRS_TYPE	uint32_t
513 
514 #if defined(__sparcv9)
515 
516 /*
517  * SPARC Version 9 floating point
518  */
519 
520 struct __fpu {
521 	union {					/* FPU floating point regs */
522 		uint32_t	__fpu_regs[32];		/* 32 singles */
523 		double		__fpu_dregs[32];	/* 32 doubles */
524 		long double	__fpu_qregs[16];	/* 16 quads */
525 	} __fpu_fr;
526 	struct __fq	*__fpu_q;		/* ptr to array of FQ entries */
527 	uint64_t	__fpu_fsr;	/* FPU status register */
528 	uint8_t		__fpu_qcnt;		/* # of entries in saved FQ */
529 	uint8_t		__fpu_q_entrysize;	/* # of bytes per FQ entry */
530 	uint8_t		__fpu_en;		/* flag signifying fpu in use */
531 };
532 
533 #else	/* __sparcv9 */
534 
535 /*
536  * SPARC Version 7 and 8 floating point
537  */
538 
539 struct __fpu {
540 	union {					/* FPU floating point regs */
541 		uint32_t	__fpu_regs[32];		/* 32 singles */
542 		double		__fpu_dregs[16];	/* 16 doubles */
543 	} __fpu_fr;
544 	struct __fq	*__fpu_q;		/* ptr to array of FQ entries */
545 	uint32_t	__fpu_fsr;	/* FPU status register */
546 	uint8_t		__fpu_qcnt;		/* # of entries in saved FQ */
547 	uint8_t		__fpu_q_entrysize;	/* # of bytes per FQ entry */
548 	uint8_t		__fpu_en;		/* flag signifying fpu in use */
549 };
550 
551 #endif	/* __sparcv9 */
552 
553 typedef struct __fpu	fpregset_t;
554 
555 /*
556  * The xrs_t structure is for associating extra register state with
557  * the ucontext structure and is kept within the uc_mcontext filler area.
558  */
559 typedef struct {
560 	unsigned int	__xrs_id;	/* indicates xrs_ptr validity */
561 	caddr_t		__xrs_ptr;	/* ptr to extra reg state */
562 } xrs_t;
563 
564 #define	_XRS_ID			0x78727300	/* the string "xrs" */
565 
566 #if defined(__sparcv9)
567 
568 /*
569  * Ancillary State Registers
570  *
571  * The SPARC V9 architecture defines 25 ASRs, numbered from 7 through 31.
572  * ASRs 16 through 31 are available to user programs, though the meaning
573  * and content of these registers is implementation dependent.
574  */
575 typedef	int64_t	asrset_t[16];	/* %asr16 - > %asr31 */
576 
577 #endif	/* __sparcv9 */
578 
579 /*
580  * Structure mcontext defines the complete hardware machine state.
581  */
582 typedef struct {
583 	gregset_t	__gregs; /* general register set */
584 	gwindows_t	*__gwins; /* POSSIBLE pointer to register windows */
585 	fpregset_t	__fpregs; /* floating point register set */
586 	xrs_t		__xrs;	/* POSSIBLE extra register state association */
587 #if defined(__sparcv9)
588 	asrset_t	__asrs;		/* ancillary registers */
589 	long		__filler[4];	/* room for expansion */
590 #else	/* __sparcv9 */
591 	long		__filler[19];
592 #endif	/* __sparcv9 */
593 } mcontext_t;
594 
595 #endif	/* _ASM */
596 #endif /* defined(_XPG4_2) && !defined(__EXTENSIONS__) */
597 
598 
599 #ifdef	__cplusplus
600 }
601 #endif
602 
603 #endif	/* _SYS_REGSET_H */
604