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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #ifndef _SYS_REGSET_H 32 #define _SYS_REGSET_H 33 34 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.1 */ 35 36 #include <sys/feature_tests.h> 37 38 #if !defined(_ASM) 39 #include <sys/int_types.h> 40 #endif 41 42 #ifdef __cplusplus 43 extern "C" { 44 #endif 45 46 /* 47 * Location of the users' stored registers relative to R0. 48 * Usage is as an index into a gregset_t array or as u.u_ar0[XX]. 49 */ 50 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 51 52 #if defined(__sparcv9) 53 #define REG_CCR (0) 54 #if defined(_SYSCALL32) 55 #define REG_PSR (0) 56 #endif /* _SYSCALL32 */ 57 #else 58 #define REG_PSR (0) 59 #endif /* __sparcv9 */ 60 61 #define REG_PC (1) 62 #define REG_nPC (2) 63 #define REG_Y (3) 64 #define REG_G1 (4) 65 #define REG_G2 (5) 66 #define REG_G3 (6) 67 #define REG_G4 (7) 68 #define REG_G5 (8) 69 #define REG_G6 (9) 70 #define REG_G7 (10) 71 #define REG_O0 (11) 72 #define REG_O1 (12) 73 #define REG_O2 (13) 74 #define REG_O3 (14) 75 #define REG_O4 (15) 76 #define REG_O5 (16) 77 #define REG_O6 (17) 78 #define REG_O7 (18) 79 #if defined(__sparcv9) 80 #define REG_ASI (19) 81 #define REG_FPRS (20) 82 #endif /* __sparcv9 */ 83 84 /* the following defines are for portability */ 85 #if !defined(__sparcv9) 86 #define REG_PS REG_PSR 87 #endif /* __sparcv9 */ 88 #define REG_SP REG_O6 89 #define REG_R0 REG_O0 90 #define REG_R1 REG_O1 91 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ 92 93 /* 94 * A gregset_t is defined as an array type for compatibility with the reference 95 * source. This is important due to differences in the way the C language 96 * treats arrays and structures as parameters. 97 * 98 * Note that NGREG is really (sizeof (struct regs) / sizeof (greg_t)), 99 * but that the SPARC V8 ABI defines it absolutely to be 19. 100 */ 101 #if defined(__sparcv9) 102 #define _NGREG 21 103 #else /* __sparcv9 */ 104 #define _NGREG 19 105 #endif /* __sparcv9 */ 106 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 107 #define NGREG _NGREG 108 #endif 109 110 #ifndef _ASM 111 112 #if defined(_LP64) || defined(_I32LPx) 113 typedef long greg_t; 114 #else 115 typedef int greg_t; 116 #endif 117 118 #if defined(_SYSCALL32) 119 120 typedef int32_t greg32_t; 121 typedef int64_t greg64_t; 122 123 #endif /* _SYSCALL32 */ 124 125 typedef greg_t gregset_t[_NGREG]; 126 127 #if defined(_SYSCALL32) 128 129 #define _NGREG32 19 130 #define _NGREG64 21 131 132 typedef greg32_t gregset32_t[_NGREG32]; 133 typedef greg64_t gregset64_t[_NGREG64]; 134 135 #endif /* _SYSCALL32 */ 136 137 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 138 /* 139 * The following structures define how a register window can appear on the 140 * stack. This structure is available (when required) through the `gwins' 141 * field of an mcontext (nested within ucontext). SPARC_MAXWINDOW is the 142 * maximum number of outstanding regiters window defined in the SPARC 143 * architecture (*not* implementation). 144 */ 145 #define SPARC_MAXREGWINDOW 31 /* max windows in SPARC arch. */ 146 147 struct rwindow { 148 greg_t rw_local[8]; /* locals */ 149 greg_t rw_in[8]; /* ins */ 150 }; 151 152 #if defined(_SYSCALL32) 153 154 struct rwindow32 { 155 greg32_t rw_local[8]; /* locals */ 156 greg32_t rw_in[8]; /* ins */ 157 }; 158 159 struct rwindow64 { 160 greg64_t rw_local[8]; /* locals */ 161 greg64_t rw_in[8]; /* ins */ 162 }; 163 164 #if defined(_KERNEL) 165 extern void rwindow_nto32(struct rwindow *, struct rwindow32 *); 166 extern void rwindow_32ton(struct rwindow32 *, struct rwindow *); 167 #endif 168 169 #endif /* _SYSCALL32 */ 170 171 #define rw_fp rw_in[6] /* frame pointer */ 172 #define rw_rtn rw_in[7] /* return address */ 173 174 typedef struct gwindows { 175 int wbcnt; 176 greg_t *spbuf[SPARC_MAXREGWINDOW]; 177 struct rwindow wbuf[SPARC_MAXREGWINDOW]; 178 } gwindows_t; 179 180 #if defined(_SYSCALL32) 181 182 typedef struct gwindows32 { 183 int32_t wbcnt; 184 caddr32_t spbuf[SPARC_MAXREGWINDOW]; 185 struct rwindow32 wbuf[SPARC_MAXREGWINDOW]; 186 } gwindows32_t; 187 188 typedef struct gwindows64 { 189 int wbcnt; 190 greg64_t *spbuf[SPARC_MAXREGWINDOW]; 191 struct rwindow64 wbuf[SPARC_MAXREGWINDOW]; 192 } gwindows64_t; 193 194 #endif /* _SYSCALL32 */ 195 196 197 /* 198 * Floating point definitions. 199 */ 200 201 #define MAXFPQ 16 /* max # of fpu queue entries currently supported */ 202 203 /* 204 * struct fq defines the minimal format of a floating point instruction queue 205 * entry. The size of entries in the floating point queue are implementation 206 * dependent. The union FQu is guarenteed to be the first field in any ABI 207 * conformant system implementation. Any additional fields provided by an 208 * implementation should not be used applications designed to be ABI conformant. 209 */ 210 211 struct fpq { 212 unsigned int *fpq_addr; /* address */ 213 unsigned int fpq_instr; /* instruction */ 214 }; 215 216 struct fq { 217 union { /* FPU inst/addr queue */ 218 double whole; 219 struct fpq fpq; 220 } FQu; 221 }; 222 223 #if defined(_SYSCALL32) 224 225 struct fpq32 { 226 caddr32_t fpq_addr; /* address */ 227 uint32_t fpq_instr; /* instruction */ 228 }; 229 230 struct fq32 { 231 union { /* FPU inst/addr queue */ 232 double whole; 233 struct fpq32 fpq; 234 } FQu; 235 }; 236 237 #endif /* _SYSCALL32 */ 238 239 /* 240 * struct fpu is the floating point processor state. struct fpu is the sum 241 * total of all possible floating point state which includes the state of 242 * external floating point hardware, fpa registers, etc..., if it exists. 243 * 244 * A floating point instuction queue may or may not be associated with 245 * the floating point processor state. If a queue does exist, the field 246 * fpu_q will point to an array of fpu_qcnt entries where each entry is 247 * fpu_q_entrysize long. fpu_q_entry has a lower bound of sizeof (union FQu) 248 * and no upper bound. If no floating point queue entries are associated 249 * with the processor state, fpu_qcnt will be zeo and fpu_q will be NULL. 250 */ 251 252 /* 253 * The following #define's are obsolete and may be removed in a future release. 254 * The corresponding integer types should be used instead (i.e. uint64_t). 255 */ 256 #define FPU_REGS_TYPE uint32_t 257 #define FPU_DREGS_TYPE uint64_t 258 #define V7_FPU_FSR_TYPE uint32_t 259 #define V9_FPU_FSR_TYPE uint64_t 260 #define V9_FPU_FPRS_TYPE uint32_t 261 262 #if defined(__sparcv9) 263 264 struct fpu { 265 union { /* FPU floating point regs */ 266 uint32_t fpu_regs[32]; /* 32 singles */ 267 double fpu_dregs[32]; /* 32 doubles */ 268 long double fpu_qregs[16]; /* 16 quads */ 269 } fpu_fr; 270 struct fq *fpu_q; /* ptr to array of FQ entries */ 271 uint64_t fpu_fsr; /* FPU status register */ 272 uint8_t fpu_qcnt; /* # of entries in saved FQ */ 273 uint8_t fpu_q_entrysize; /* # of bytes per FQ entry */ 274 uint8_t fpu_en; /* flag specifying fpu in use */ 275 }; 276 277 #else /* __sparcv9 */ 278 279 struct fpu { 280 union { /* FPU floating point regs */ 281 uint32_t fpu_regs[32]; /* 32 singles */ 282 double fpu_dregs[16]; /* 16 doubles */ 283 } fpu_fr; 284 struct fq *fpu_q; /* ptr to array of FQ entries */ 285 uint32_t fpu_fsr; /* FPU status register */ 286 uint8_t fpu_qcnt; /* # of entries in saved FQ */ 287 uint8_t fpu_q_entrysize; /* # of bytes per FQ entry */ 288 uint8_t fpu_en; /* flag signifying fpu in use */ 289 }; 290 291 #endif /* __sparcv9 */ 292 293 typedef struct fpu fpregset_t; 294 295 #if defined(_SYSCALL32) 296 297 /* Kernel view of user sparcv7/v8 fpu structure */ 298 299 struct fpu32 { 300 union { /* FPU floating point regs */ 301 uint32_t fpu_regs[32]; /* 32 singles */ 302 double fpu_dregs[16]; /* 16 doubles */ 303 } fpu_fr; 304 caddr32_t fpu_q; /* ptr to array of FQ entries */ 305 uint32_t fpu_fsr; /* FPU status register */ 306 uint8_t fpu_qcnt; /* # of entries in saved FQ */ 307 uint8_t fpu_q_entrysize; /* # of bytes per FQ entry */ 308 uint8_t fpu_en; /* flag signifying fpu in use */ 309 }; 310 311 typedef struct fpu32 fpregset32_t; 312 313 #endif /* _SYSCALL32 */ 314 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 333 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ 334 335 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 336 /* 337 * The following structure is for associating extra register state with 338 * the ucontext structure and is kept within the uc_mcontext filler area. 339 * 340 * If (xrs_id == XRS_ID) then the xrs_ptr field is a valid pointer to 341 * extra register state. The exact format of the extra register state 342 * pointed to by xrs_ptr is platform-dependent. 343 * 344 * Note: a platform may or may not manage extra register state. 345 */ 346 typedef struct { 347 unsigned int xrs_id; /* indicates xrs_ptr validity */ 348 caddr_t xrs_ptr; /* ptr to extra reg state */ 349 } xrs_t; 350 351 #define XRS_ID 0x78727300 /* the string "xrs" */ 352 353 #if defined(_SYSCALL32) 354 355 typedef struct { 356 uint32_t xrs_id; /* indicates xrs_ptr validity */ 357 caddr32_t xrs_ptr; /* ptr to extra reg state */ 358 } xrs32_t; 359 360 #endif /* _SYSCALL32 */ 361 362 #if defined(__sparcv9) 363 364 /* 365 * Ancillary State Registers 366 * 367 * The SPARC V9 architecture defines 25 ASRs, numbered from 7 through 31. 368 * ASRs 16 through 31 are available to user programs, though the meaning 369 * and content of these registers is implementation dependent. 370 */ 371 typedef int64_t asrset_t[16]; /* %asr16 - > %asr31 */ 372 373 #endif /* __sparcv9 */ 374 375 /* 376 * Structure mcontext defines the complete hardware machine state. If 377 * the field `gwins' is non NULL, it points to a save area for register 378 * window frames. If `gwins' is NULL, the register windows were saved 379 * on the user's stack. 380 * 381 * The filler of 21 longs is historical (now filler[19] plus the xrs_t 382 * field). The value was selected to provide binary compatibility with 383 * statically linked ICL binaries. It is in the ABI (do not change). It 384 * actually appears in the ABI as a single filler of 44 is in the field 385 * uc_filler of struct ucontext. It is split here so that ucontext.h can 386 * (hopefully) remain architecture independent. 387 * 388 * Note that 2 longs of the filler are used to hold extra register state info. 389 */ 390 typedef struct { 391 gregset_t gregs; /* general register set */ 392 gwindows_t *gwins; /* POSSIBLE pointer to register windows */ 393 fpregset_t fpregs; /* floating point register set */ 394 xrs_t xrs; /* POSSIBLE extra register state association */ 395 #if defined(__sparcv9) 396 asrset_t asrs; /* ancillary registers */ 397 long filler[4]; /* room for expansion */ 398 #else /* __sparcv9 */ 399 long filler[19]; 400 #endif /* __sparcv9 */ 401 } mcontext_t; 402 403 #if defined(_SYSCALL32) 404 405 typedef struct { 406 gregset32_t gregs; /* general register set */ 407 caddr32_t gwins; /* POSSIBLE pointer to register windows */ 408 fpregset32_t fpregs; /* floating point register set */ 409 xrs32_t xrs; /* POSSIBLE extra register state association */ 410 int32_t filler[19]; 411 } mcontext32_t; 412 413 #endif /* _SYSCALL32 */ 414 415 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ 416 #endif /* _ASM */ 417 418 /* 419 * The version of privregs.h that is used on implementations that run 420 * on processors that support the V9 instruction set is deliberately not 421 * imported here. 422 * 423 * The V9 'struct regs' definition is -not- compatible with either 32-bit 424 * or 64-bit core file contents, nor with the ucontext. As a result, the 425 * 'regs' structure cannot be used portably by applications, and should 426 * only be used by the kernel implementation. 427 * 428 * The inclusion of the SPARC V7 version of privregs.h allows for some 429 * limited source compatibility with 32-bit applications who expect to use 430 * 'struct regs' to match the content of a 32-bit core file, or a ucontext_t. 431 * 432 * Note that the ucontext_t actually describes the general registers in 433 * terms of the gregset_t data type, as described in this file. Note also 434 * that the core file content is defined by core(4) in terms of data types 435 * defined by procfs -- see proc(4). 436 */ 437 #if !defined(__sparcv9) 438 #if !defined(_KERNEL) && !defined(_XPG4_2) || defined(__EXTENSIONS__) 439 #include <v7/sys/privregs.h> 440 #endif /* !_KERNEL && !_XPG4_2 || __EXTENSIONS__ */ 441 #endif /* __sparcv9 */ 442 443 /* 444 * The following is here for XPG4.2 standards compliance. 445 * regset.h is included in ucontext.h for the definition of 446 * mcontext_t, all of which breaks XPG4.2 namespace. 447 */ 448 449 #if defined(_XPG4_2) && !defined(__EXTENSIONS__) 450 /* 451 * The following is here for UNIX 95 compliance (XPG Issue 4, Version 2 452 * System Interfaces and Headers. The structures included here are identical 453 * to those visible elsewhere in this header except that the structure 454 * element names have been changed in accordance with the X/Open namespace 455 * rules. Specifically, depending on the name and scope, the names have 456 * been prepended with a single or double underscore (_ or __). See the 457 * structure definitions in the non-X/Open namespace for more detailed 458 * comments describing each of these structures. 459 */ 460 461 #ifndef _ASM 462 463 /* 464 * The following structures define how a register window can appear on the 465 * stack. 466 */ 467 #define _SPARC_MAXREGWINDOW 31 /* max windows in SPARC arch. */ 468 469 struct __rwindow { 470 greg_t __rw_local[8]; /* locals */ 471 greg_t __rw_in[8]; /* ins */ 472 }; 473 474 #define __rw_fp __rw_in[6] /* frame pointer */ 475 #define __rw_rtn __rw_in[7] /* return address */ 476 477 struct __gwindows { 478 int __wbcnt; 479 greg_t *__spbuf[_SPARC_MAXREGWINDOW]; 480 struct __rwindow __wbuf[_SPARC_MAXREGWINDOW]; 481 }; 482 483 typedef struct __gwindows gwindows_t; 484 485 /* 486 * The fq structure defines the minimal format of a floating point 487 * instruction queue entry. 488 */ 489 490 struct __fpq { 491 unsigned int *__fpq_addr; /* address */ 492 unsigned int __fpq_instr; /* instruction */ 493 }; 494 495 struct __fq { 496 union { /* FPU inst/addr queue */ 497 double __whole; 498 struct __fpq __fpq; 499 } _FQu; 500 }; 501 502 /* 503 * The fpu structure is the floating point processor state. 504 */ 505 506 /* 507 * The following #define's are obsolete and may be removed in a future release. 508 * The corresponding integer types should be used instead (i.e. uint64_t). 509 */ 510 #define _FPU_REGS_TYPE uint32_t 511 #define _FPU_DREGS_TYPE uint64_t 512 #define _V7_FPU_FSR_TYPE uint32_t 513 #define _V9_FPU_FSR_TYPE uint64_t 514 #define _V9_FPU_FPRS_TYPE uint32_t 515 516 #if defined(__sparcv9) 517 518 /* 519 * SPARC Version 9 floating point 520 */ 521 522 struct __fpu { 523 union { /* FPU floating point regs */ 524 uint32_t __fpu_regs[32]; /* 32 singles */ 525 double __fpu_dregs[32]; /* 32 doubles */ 526 long double __fpu_qregs[16]; /* 16 quads */ 527 } __fpu_fr; 528 struct __fq *__fpu_q; /* ptr to array of FQ entries */ 529 uint64_t __fpu_fsr; /* FPU status register */ 530 uint8_t __fpu_qcnt; /* # of entries in saved FQ */ 531 uint8_t __fpu_q_entrysize; /* # of bytes per FQ entry */ 532 uint8_t __fpu_en; /* flag signifying fpu in use */ 533 }; 534 535 #else /* __sparcv9 */ 536 537 /* 538 * SPARC Version 7 and 8 floating point 539 */ 540 541 struct __fpu { 542 union { /* FPU floating point regs */ 543 uint32_t __fpu_regs[32]; /* 32 singles */ 544 double __fpu_dregs[16]; /* 16 doubles */ 545 } __fpu_fr; 546 struct __fq *__fpu_q; /* ptr to array of FQ entries */ 547 uint32_t __fpu_fsr; /* FPU status register */ 548 uint8_t __fpu_qcnt; /* # of entries in saved FQ */ 549 uint8_t __fpu_q_entrysize; /* # of bytes per FQ entry */ 550 uint8_t __fpu_en; /* flag signifying fpu in use */ 551 }; 552 553 #endif /* __sparcv9 */ 554 555 typedef struct __fpu fpregset_t; 556 557 /* 558 * The xrs_t structure is for associating extra register state with 559 * the ucontext structure and is kept within the uc_mcontext filler area. 560 */ 561 typedef struct { 562 unsigned int __xrs_id; /* indicates xrs_ptr validity */ 563 caddr_t __xrs_ptr; /* ptr to extra reg state */ 564 } xrs_t; 565 566 #define _XRS_ID 0x78727300 /* the string "xrs" */ 567 568 #if defined(__sparcv9) 569 570 /* 571 * Ancillary State Registers 572 * 573 * The SPARC V9 architecture defines 25 ASRs, numbered from 7 through 31. 574 * ASRs 16 through 31 are available to user programs, though the meaning 575 * and content of these registers is implementation dependent. 576 */ 577 typedef int64_t asrset_t[16]; /* %asr16 - > %asr31 */ 578 579 #endif /* __sparcv9 */ 580 581 /* 582 * Structure mcontext defines the complete hardware machine state. 583 */ 584 typedef struct { 585 gregset_t __gregs; /* general register set */ 586 gwindows_t *__gwins; /* POSSIBLE pointer to register windows */ 587 fpregset_t __fpregs; /* floating point register set */ 588 xrs_t __xrs; /* POSSIBLE extra register state association */ 589 #if defined(__sparcv9) 590 asrset_t __asrs; /* ancillary registers */ 591 long __filler[4]; /* room for expansion */ 592 #else /* __sparcv9 */ 593 long __filler[19]; 594 #endif /* __sparcv9 */ 595 } mcontext_t; 596 597 #endif /* _ASM */ 598 #endif /* defined(_XPG4_2) && !defined(__EXTENSIONS__) */ 599 600 601 #ifdef __cplusplus 602 } 603 #endif 604 605 #endif /* _SYS_REGSET_H */ 606