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