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 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ 28 29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 30 /* All Rights Reserved */ 31 32 #ifndef _SYS_REGSET_H 33 #define _SYS_REGSET_H 34 35 #pragma ident "%Z%%M% %I% %E% SMI" 36 37 #include <sys/feature_tests.h> 38 39 #if !defined(_ASM) 40 #include <sys/types.h> 41 #endif 42 43 #ifdef __cplusplus 44 extern "C" { 45 #endif 46 47 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 48 49 /* 50 * The names and offsets defined here should be specified by the 51 * AMD64 ABI suppl. 52 * 53 * We make fsbase and gsbase part of the lwp context (since they're 54 * the only way to access the full 64-bit address range via the segment 55 * registers) and thus belong here too. However we treat them as 56 * read-only; if %fs or %gs are updated, the results of the descriptor 57 * table lookup that those updates implicitly cause will be reflected 58 * in the corresponding fsbase and/or gsbase values the next time the 59 * context can be inspected. However it is NOT possible to override 60 * the fsbase/gsbase settings via this interface. 61 * 62 * Direct modification of the base registers (thus overriding the 63 * descriptor table base address) can be achieved with _lwp_setprivate. 64 */ 65 66 #define REG_GSBASE 27 67 #define REG_FSBASE 26 68 #define REG_DS 25 69 #define REG_ES 24 70 71 #define REG_GS 23 72 #define REG_FS 22 73 #define REG_SS 21 74 #define REG_RSP 20 75 #define REG_RFL 19 76 #define REG_CS 18 77 #define REG_RIP 17 78 #define REG_ERR 16 79 #define REG_TRAPNO 15 80 #define REG_RAX 14 81 #define REG_RCX 13 82 #define REG_RDX 12 83 #define REG_RBX 11 84 #define REG_RBP 10 85 #define REG_RSI 9 86 #define REG_RDI 8 87 #define REG_R8 7 88 #define REG_R9 6 89 #define REG_R10 5 90 #define REG_R11 4 91 #define REG_R12 3 92 #define REG_R13 2 93 #define REG_R14 1 94 #define REG_R15 0 95 96 /* 97 * The names and offsets defined here are specified by i386 ABI suppl. 98 */ 99 100 #define SS 18 /* only stored on a privilege transition */ 101 #define UESP 17 /* only stored on a privilege transition */ 102 #define EFL 16 103 #define CS 15 104 #define EIP 14 105 #define ERR 13 106 #define TRAPNO 12 107 #define EAX 11 108 #define ECX 10 109 #define EDX 9 110 #define EBX 8 111 #define ESP 7 112 #define EBP 6 113 #define ESI 5 114 #define EDI 4 115 #define DS 3 116 #define ES 2 117 #define FS 1 118 #define GS 0 119 120 /* aliases for portability */ 121 122 #if defined(__amd64) 123 124 #define REG_PC REG_RIP 125 #define REG_FP REG_RBP 126 #define REG_SP REG_RSP 127 #define REG_PS REG_RFL 128 #define REG_R0 REG_RAX 129 #define REG_R1 REG_RDX 130 131 #else /* __i386 */ 132 133 #define REG_PC EIP 134 #define REG_FP EBP 135 #define REG_SP UESP 136 #define REG_PS EFL 137 #define REG_R0 EAX 138 #define REG_R1 EDX 139 140 #endif /* __i386 */ 141 142 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ 143 144 /* 145 * A gregset_t is defined as an array type for compatibility with the reference 146 * source. This is important due to differences in the way the C language 147 * treats arrays and structures as parameters. 148 */ 149 #if defined(__amd64) 150 #define _NGREG 28 151 #else 152 #define _NGREG 19 153 #endif 154 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 155 #define NGREG _NGREG 156 #endif 157 158 #if !defined(_ASM) 159 160 #if defined(_LP64) || defined(_I32LPx) 161 typedef long greg_t; 162 #else 163 typedef int greg_t; 164 #endif 165 166 #if defined(_SYSCALL32) 167 168 typedef int32_t greg32_t; 169 typedef int64_t greg64_t; 170 171 #endif /* _SYSCALL32 */ 172 173 typedef greg_t gregset_t[_NGREG]; 174 175 #if defined(_SYSCALL32) 176 177 #define _NGREG32 19 178 #define _NGREG64 28 179 180 typedef greg32_t gregset32_t[_NGREG32]; 181 typedef greg64_t gregset64_t[_NGREG64]; 182 183 #endif /* _SYSCALL32 */ 184 185 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 186 187 /* 188 * Floating point definitions. 189 */ 190 191 /* 192 * This structure is written to memory by an 'fnsave' instruction 193 */ 194 struct fnsave_state { 195 uint16_t f_fcw; 196 uint16_t __f_ign0; 197 uint16_t f_fsw; 198 uint16_t __f_ign1; 199 uint16_t f_ftw; 200 uint16_t __f_ign2; 201 uint32_t f_eip; 202 uint16_t f_cs; 203 uint16_t f_fop; 204 uint32_t f_dp; 205 uint16_t f_ds; 206 uint16_t __f_ign3; 207 union { 208 uint16_t fpr_16[5]; /* 80-bits of x87 state */ 209 } f_st[8]; 210 }; /* 108 bytes */ 211 212 /* 213 * This structure is written to memory by an 'fxsave' instruction 214 * Note the variant behaviour of this instruction between long mode 215 * and legacy environments! 216 */ 217 struct fxsave_state { 218 uint16_t fx_fcw; 219 uint16_t fx_fsw; 220 uint16_t fx_fctw; /* compressed tag word */ 221 uint16_t fx_fop; 222 #if defined(__amd64) 223 uint64_t fx_rip; 224 uint64_t fx_rdp; 225 #else 226 uint32_t fx_eip; 227 uint16_t fx_cs; 228 uint16_t __fx_ign0; 229 uint32_t fx_dp; 230 uint16_t fx_ds; 231 uint16_t __fx_ign1; 232 #endif 233 uint32_t fx_mxcsr; 234 uint32_t fx_mxcsr_mask; 235 union { 236 uint16_t fpr_16[5]; /* 80-bits of x87 state */ 237 u_longlong_t fpr_mmx; /* 64-bit mmx register */ 238 uint32_t __fpr_pad[4]; /* (pad out to 128-bits) */ 239 } fx_st[8]; 240 #if defined(__amd64) 241 upad128_t fx_xmm[16]; /* 128-bit registers */ 242 upad128_t __fx_ign2[6]; 243 #else 244 upad128_t fx_xmm[8]; /* 128-bit registers */ 245 upad128_t __fx_ign2[14]; 246 #endif 247 }; /* 512 bytes */ 248 249 #if defined(__amd64) 250 251 typedef struct fpu { 252 union { 253 struct fpchip_state { 254 uint16_t cw; 255 uint16_t sw; 256 uint8_t fctw; 257 uint8_t __fx_rsvd; 258 uint16_t fop; 259 uint64_t rip; 260 uint64_t rdp; 261 uint32_t mxcsr; 262 uint32_t mxcsr_mask; 263 union { 264 uint16_t fpr_16[5]; 265 upad128_t __fpr_pad; 266 } st[8]; 267 upad128_t xmm[16]; 268 upad128_t __fx_ign2[6]; 269 uint32_t status; /* sw at exception */ 270 uint32_t xstatus; /* mxcsr at exception */ 271 } fpchip_state; 272 uint32_t f_fpregs[130]; 273 } fp_reg_set; 274 } fpregset_t; 275 276 #else /* __i386 */ 277 278 /* 279 * This definition of the floating point structure is binary 280 * compatible with the Intel386 psABI definition, and source 281 * compatible with that specification for x87-style floating point. 282 * It also allows SSE/SSE2 state to be accessed on machines that 283 * possess such hardware capabilities. 284 */ 285 typedef struct fpu { 286 union { 287 struct fpchip_state { 288 uint32_t state[27]; /* 287/387 saved state */ 289 uint32_t status; /* saved at exception */ 290 uint32_t mxcsr; /* SSE control and status */ 291 uint32_t xstatus; /* SSE mxcsr at exception */ 292 uint32_t __pad[2]; /* align to 128-bits */ 293 upad128_t xmm[8]; /* %xmm0-%xmm7 */ 294 } fpchip_state; 295 struct fp_emul_space { /* for emulator(s) */ 296 uint8_t fp_emul[246]; 297 uint8_t fp_epad[2]; 298 } fp_emul_space; 299 uint32_t f_fpregs[95]; /* union of the above */ 300 } fp_reg_set; 301 } fpregset_t; 302 303 /* 304 * (This structure definition is specified in the i386 ABI supplement) 305 */ 306 typedef struct __old_fpu { 307 union { 308 struct __old_fpchip_state /* fp extension state */ 309 { 310 int state[27]; /* 287/387 saved state */ 311 int status; /* status word saved at */ 312 /* exception */ 313 } fpchip_state; 314 struct __old_fp_emul_space /* for emulator(s) */ 315 { 316 char fp_emul[246]; 317 char fp_epad[2]; 318 } fp_emul_space; 319 int f_fpregs[62]; /* union of the above */ 320 } fp_reg_set; 321 long f_wregs[33]; /* saved weitek state */ 322 } __old_fpregset_t; 323 324 #endif /* __i386 */ 325 326 #if defined(_SYSCALL32) 327 328 /* Kernel view of user i386 fpu structure */ 329 330 typedef struct fpu32 { 331 union { 332 struct fpchip32_state { 333 uint32_t state[27]; /* 287/387 saved state */ 334 uint32_t status; /* saved at exception */ 335 uint32_t mxcsr; /* SSE control and status */ 336 uint32_t xstatus; /* SSE mxcsr at exception */ 337 uint32_t __pad[2]; /* align to 128-bits */ 338 uint32_t xmm[8][4]; /* %xmm0-%xmm7 */ 339 } fpchip_state; 340 uint32_t f_fpregs[95]; /* union of the above */ 341 } fp_reg_set; 342 } fpregset32_t; 343 344 #endif /* _SYSCALL32 */ 345 346 /* 347 * Kernel's FPU save area 348 */ 349 typedef struct { 350 union _kfpu_u { 351 struct fxsave_state kfpu_fx; 352 #if defined(__i386) 353 struct fnsave_state kfpu_fn; 354 #endif 355 } kfpu_u; 356 uint32_t kfpu_status; /* saved at #mf exception */ 357 uint32_t kfpu_xstatus; /* saved at #xm exception */ 358 } kfpu_t; 359 360 #if defined(__amd64) 361 #define NDEBUGREG 16 362 #else 363 #define NDEBUGREG 8 364 #endif 365 366 typedef struct dbregset { 367 unsigned long debugreg[NDEBUGREG]; 368 } dbregset_t; 369 370 /* 371 * Structure mcontext defines the complete hardware machine state. 372 * (This structure is specified in the i386 ABI suppl.) 373 */ 374 typedef struct { 375 gregset_t gregs; /* general register set */ 376 fpregset_t fpregs; /* floating point register set */ 377 } mcontext_t; 378 379 #if defined(_SYSCALL32) 380 381 typedef struct { 382 gregset32_t gregs; /* general register set */ 383 fpregset32_t fpregs; /* floating point register set */ 384 } mcontext32_t; 385 386 #endif /* _SYSCALL32 */ 387 388 #endif /* _ASM */ 389 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ 390 391 /* 392 * The version of privregs.h that is used on implementations that run on 393 * processors that support the AMD64 instruction set is deliberately not 394 * imported here. 395 * 396 * The amd64 'struct regs' definition may -not- compatible with either 397 * 32-bit or 64-bit core file contents, nor with the ucontext. As a result, 398 * the 'regs' structure cannot be used portably by applications, and should 399 * only be used by the kernel implementation. 400 * 401 * The inclusion of the i386 version of privregs.h allows for some limited 402 * source compatibility with 32-bit applications who expect to use 403 * 'struct regs' to match the context of a 32-bit core file, or a ucontext_t. 404 * 405 * Note that the ucontext_t actually describes the general register in terms 406 * of the gregset_t data type, as described in this file. Note also 407 * that the core file content is defined by core(4) in terms of data types 408 * defined by procfs -- see proc(4). 409 */ 410 #if defined(__i386) && \ 411 (!defined(_KERNEL) && !defined(_XPG4_2) || defined(__EXTENSIONS__)) 412 #include <sys/privregs.h> 413 #endif /* __i386 (!_KERNEL && !_XPG4_2 || __EXTENSIONS__) */ 414 415 /* 416 * The following is here for XPG4.2 standards compliance. 417 * regset.h is included in ucontext.h for the definition of 418 * mcontext_t, all of which breaks XPG4.2 namespace. 419 */ 420 421 #if defined(_XPG4_2) && !defined(__EXTENSIONS__) && !defined(_ASM) 422 423 /* 424 * The following is here for UNIX 95 compliance (XPG Issue 4, Version 2 425 * System Interfaces and Headers). The structures included here are identical 426 * to those visible elsewhere in this header except that the structure 427 * element names have been changed in accordance with the X/Open namespace 428 * rules. Specifically, depending on the name and scope, the names have 429 * been prepended with a single or double underscore (_ or __). See the 430 * structure definitions in the non-X/Open namespace for more detailed 431 * comments describing each of these structures. 432 */ 433 434 #if defined(__amd64) 435 436 typedef struct __fpu { 437 union { 438 struct __fpchip_state { 439 uint16_t __fx_cw; 440 uint16_t __fx_sw; 441 uint16_t __fx_ctw; 442 uint16_t __fx_op; 443 uint64_t __fx_rip; 444 uint64_t __fx_rdp; 445 uint32_t __fx_mxcsr; 446 uint32_t __fx_mxcsr_mask; 447 union { 448 uint16_t __fpr_16[5]; 449 upad128_t __fpr_pad; 450 } __fx_st[8]; 451 upad128_t __fx_xmm[16]; 452 upad128_t __fx_ign2[6]; 453 uint32_t __status; 454 uint32_t __xstatus; 455 } __fpchip_state; 456 uint32_t __f_fpregs[130]; 457 } __fp_reg_set; 458 } fpregset_t; 459 460 #else /* __i386 */ 461 462 typedef struct __fpu { 463 union { 464 struct __fpchip_state { 465 uint32_t __state[27]; /* 287/387 saved state */ 466 uint32_t __status; /* saved at exception */ 467 uint32_t __mxcsr; /* SSE control and status */ 468 uint32_t __xstatus; /* SSE mxcsr at exception */ 469 uint32_t __pad[2]; /* align to 128-bits */ 470 upad128_t __xmm[8]; /* %xmm0-%xmm7 */ 471 } __fpchip_state; 472 struct __fp_emul_space { /* for emulator(s) */ 473 uint8_t __fp_emul[246]; 474 uint8_t __fp_epad[2]; 475 } __fp_emul_space; 476 uint32_t __f_fpregs[95]; /* union of the above */ 477 } __fp_reg_set; 478 } fpregset_t; 479 480 #endif /* __i386 */ 481 482 typedef struct { 483 gregset_t __gregs; /* general register set */ 484 fpregset_t __fpregs; /* floating point register set */ 485 } mcontext_t; 486 487 #endif /* _XPG4_2 && !__EXTENSIONS__ && !_ASM */ 488 489 #ifdef __cplusplus 490 } 491 #endif 492 493 #endif /* _SYS_REGSET_H */ 494