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