Home | History | Annotate | Download | only in sys
      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