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