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