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