Annotation of sys/arch/sparc64/include/psl.h, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: psl.h,v 1.23 2007/05/16 19:37:06 thib Exp $ */
! 2: /* $NetBSD: psl.h,v 1.20 2001/04/13 23:30:05 thorpej Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1992, 1993
! 6: * The Regents of the University of California. All rights reserved.
! 7: *
! 8: * This software was developed by the Computer Systems Engineering group
! 9: * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
! 10: * contributed to Berkeley.
! 11: *
! 12: * All advertising materials mentioning features or use of this software
! 13: * must display the following acknowledgement:
! 14: * This product includes software developed by the University of
! 15: * California, Lawrence Berkeley Laboratory.
! 16: *
! 17: * Redistribution and use in source and binary forms, with or without
! 18: * modification, are permitted provided that the following conditions
! 19: * are met:
! 20: * 1. Redistributions of source code must retain the above copyright
! 21: * notice, this list of conditions and the following disclaimer.
! 22: * 2. Redistributions in binary form must reproduce the above copyright
! 23: * notice, this list of conditions and the following disclaimer in the
! 24: * documentation and/or other materials provided with the distribution.
! 25: * 3. Neither the name of the University nor the names of its contributors
! 26: * may be used to endorse or promote products derived from this software
! 27: * without specific prior written permission.
! 28: *
! 29: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 30: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 31: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 32: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 33: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 34: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 35: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 36: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 37: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 38: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 39: * SUCH DAMAGE.
! 40: *
! 41: * @(#)psl.h 8.1 (Berkeley) 6/11/93
! 42: */
! 43:
! 44: #ifndef _SPARC64_PSL_
! 45: #define _SPARC64_PSL_
! 46:
! 47: /* Interesting spl()s */
! 48: #define PIL_SCSI 3
! 49: #define PIL_FDSOFT 4
! 50: #define PIL_AUSOFT 4
! 51: #define PIL_BIO 5
! 52: #define PIL_VIDEO 5
! 53: #define PIL_TTY 6
! 54: #define PIL_LPT 6
! 55: #define PIL_NET 6
! 56: #define PIL_VM 7
! 57: #define PIL_AUD 8
! 58: #define PIL_CLOCK 10
! 59: #define PIL_FD 11
! 60: #define PIL_SER 12
! 61: #define PIL_STATCLOCK 14
! 62: #define PIL_HIGH 15
! 63: #define PIL_SCHED PIL_STATCLOCK
! 64: #define PIL_LOCK PIL_HIGH
! 65:
! 66: /*
! 67: * SPARC V9 CCR register
! 68: */
! 69:
! 70: #define ICC_C 0x01L
! 71: #define ICC_V 0x02L
! 72: #define ICC_Z 0x04L
! 73: #define ICC_N 0x08L
! 74: #define XCC_SHIFT 4
! 75: #define XCC_C (ICC_C<<XCC_SHIFT)
! 76: #define XCC_V (ICC_V<<XCC_SHIFT)
! 77: #define XCC_Z (ICC_Z<<XCC_SHIFT)
! 78: #define XCC_N (ICC_N<<XCC_SHIFT)
! 79:
! 80:
! 81: /*
! 82: * SPARC V9 PSTATE register (what replaces the PSR in V9)
! 83: *
! 84: * Here's the layout:
! 85: *
! 86: * 11 10 9 8 7 6 5 4 3 2 1 0
! 87: * +------------------------------------------------------------+
! 88: * | IG | MG | CLE | TLE | MM | RED | PEF | AM | PRIV | IE | AG |
! 89: * +------------------------------------------------------------+
! 90: */
! 91:
! 92: #define PSTATE_IG 0x800 /* enable spitfire interrupt globals */
! 93: #define PSTATE_MG 0x400 /* enable spitfire MMU globals */
! 94: #define PSTATE_CLE 0x200 /* current little endian */
! 95: #define PSTATE_TLE 0x100 /* traps little endian */
! 96: #define PSTATE_MM 0x0c0 /* memory model */
! 97: #define PSTATE_MM_TSO 0x000 /* total store order */
! 98: #define PSTATE_MM_PSO 0x040 /* partial store order */
! 99: #define PSTATE_MM_RMO 0x080 /* Relaxed memory order */
! 100: #define PSTATE_RED 0x020 /* RED state */
! 101: #define PSTATE_PEF 0x010 /* enable floating point */
! 102: #define PSTATE_AM 0x008 /* 32-bit address masking */
! 103: #define PSTATE_PRIV 0x004 /* privileged mode */
! 104: #define PSTATE_IE 0x002 /* interrupt enable */
! 105: #define PSTATE_AG 0x001 /* enable alternate globals */
! 106:
! 107: #define PSTATE_BITS "\20\14IG\13MG\12CLE\11TLE\10\7MM\6RED\5PEF\4AM\3PRIV\2IE\1AG"
! 108:
! 109:
! 110: /*
! 111: * 32-bit code requires TSO or at best PSO since that's what's supported on
! 112: * SPARC V8 and earlier machines.
! 113: *
! 114: * 64-bit code sets the memory model in the ELF header.
! 115: *
! 116: * We're running kernel code in TSO for the moment so we don't need to worry
! 117: * about possible memory barrier bugs.
! 118: */
! 119:
! 120: #define PSTATE_PROM (PSTATE_MM_TSO|PSTATE_PRIV)
! 121: #define PSTATE_NUCLEUS (PSTATE_MM_TSO|PSTATE_PRIV|PSTATE_AG)
! 122: #define PSTATE_KERN (PSTATE_MM_TSO|PSTATE_PRIV)
! 123: #define PSTATE_INTR (PSTATE_KERN|PSTATE_IE)
! 124: #define PSTATE_USER32 (PSTATE_MM_TSO|PSTATE_AM|PSTATE_IE)
! 125: #define PSTATE_USER (PSTATE_MM_RMO|PSTATE_IE)
! 126:
! 127:
! 128: /*
! 129: * SPARC V9 TSTATE register
! 130: *
! 131: * 39 32 31 24 23 18 17 8 7 5 4 0
! 132: * +-----+-----+-----+--------+---+-----+
! 133: * | CCR | ASI | - | PSTATE | - | CWP |
! 134: * +-----+-----+-----+--------+---+-----+
! 135: */
! 136:
! 137: #define TSTATE_CWP 0x01f
! 138: #define TSTATE_PSTATE 0x6ff00
! 139: #define TSTATE_PSTATE_SHIFT 8
! 140: #define TSTATE_ASI 0xff000000LL
! 141: #define TSTATE_ASI_SHIFT 24
! 142: #define TSTATE_CCR 0xff00000000LL
! 143: #define TSTATE_CCR_SHIFT 32
! 144:
! 145: /* Leftover SPARC V8 PSTATE stuff */
! 146: #define PSR_ICC 0x00f00000
! 147: #define PSRCC_TO_TSTATE(x) (((int64_t)(x)&PSR_ICC)<<(TSTATE_CCR_SHIFT-19))
! 148: #define TSTATECCR_TO_PSR(x) (((x)&TSTATE_CCR)>>(TSTATE_CCR_SHIFT-19))
! 149:
! 150: /*
! 151: * These are here to simplify life.
! 152: */
! 153: #define TSTATE_IG (PSTATE_IG<<TSTATE_PSTATE_SHIFT)
! 154: #define TSTATE_MG (PSTATE_MG<<TSTATE_PSTATE_SHIFT)
! 155: #define TSTATE_CLE (PSTATE_CLE<<TSTATE_PSTATE_SHIFT)
! 156: #define TSTATE_TLE (PSTATE_TLE<<TSTATE_PSTATE_SHIFT)
! 157: #define TSTATE_MM (PSTATE_MM<<TSTATE_PSTATE_SHIFT)
! 158: #define TSTATE_MM_TSO (PSTATE_MM_TSO<<TSTATE_PSTATE_SHIFT)
! 159: #define TSTATE_MM_PSO (PSTATE_MM_PSO<<TSTATE_PSTATE_SHIFT)
! 160: #define TSTATE_MM_RMO (PSTATE_MM_RMO<<TSTATE_PSTATE_SHIFT)
! 161: #define TSTATE_RED (PSTATE_RED<<TSTATE_PSTATE_SHIFT)
! 162: #define TSTATE_PEF (PSTATE_PEF<<TSTATE_PSTATE_SHIFT)
! 163: #define TSTATE_AM (PSTATE_AM<<TSTATE_PSTATE_SHIFT)
! 164: #define TSTATE_PRIV (PSTATE_PRIV<<TSTATE_PSTATE_SHIFT)
! 165: #define TSTATE_IE (PSTATE_IE<<TSTATE_PSTATE_SHIFT)
! 166: #define TSTATE_AG (PSTATE_AG<<TSTATE_PSTATE_SHIFT)
! 167:
! 168: #define TSTATE_BITS "\20\14IG\13MG\12CLE\11TLE\10\7MM\6RED\5PEF\4AM\3PRIV\2IE\1AG"
! 169:
! 170: #define TSTATE_KERN ((PSTATE_KERN)<<TSTATE_PSTATE_SHIFT)
! 171: #define TSTATE_USER ((PSTATE_USER)<<TSTATE_PSTATE_SHIFT)
! 172: /*
! 173: * SPARC V9 VER version register.
! 174: *
! 175: * 63 48 47 32 31 24 23 16 15 8 7 5 4 0
! 176: * +-------+------+------+-----+-------+---+--------+
! 177: * | manuf | impl | mask | - | maxtl | - | maxwin |
! 178: * +-------+------+------+-----+-------+---+--------+
! 179: *
! 180: */
! 181:
! 182: #define VER_MANUF 0xffff000000000000ULL
! 183: #define VER_MANUF_SHIFT 48
! 184: #define VER_IMPL 0x0000ffff00000000ULL
! 185: #define VER_IMPL_SHIFT 32
! 186: #define VER_MASK 0x00000000ff000000ULL
! 187: #define VER_MASK_SHIFT 24
! 188: #define VER_MAXTL 0x000000000000ff00ULL
! 189: #define VER_MAXTL_SHIFT 8
! 190: #define VER_MAXWIN 0x000000000000001fULL
! 191:
! 192: #define IMPL_SPARC64 0x01 /* SPARC64 */
! 193: #define IMPL_SPARC64_II 0x02 /* SPARC64-II */
! 194: #define IMPL_SPARC64_III 0x03 /* SPARC64-III */
! 195: #define IMPL_SPITFIRE 0x10 /* UltraSPARC */
! 196: #define IMPL_BLACKBIRD 0x11 /* UltraSPARC-II */
! 197: #define IMPL_SABRE 0x12 /* UltraSPARC-IIi */
! 198: #define IMPL_HUMMINGBIRD 0x13 /* UltraSPARC-IIe */
! 199: #define IMPL_CHEETAH 0x14 /* UltraSPARC-III */
! 200: #define IMPL_CHEETAH_PLUS 0x15 /* UltraSPARC-III+ */
! 201: #define IMPL_JALAPENO 0x16 /* UltraSPARC-IIIi */
! 202: #define IMPL_JAGUAR 0x18 /* UltraSPARC-IV */
! 203: #define IMPL_PANTHER 0x19 /* UltraSPARC-IV+ */
! 204: #define IMPL_SERRANO 0x22 /* UltraSPARC-IIIi+ */
! 205:
! 206: /*
! 207: * Here are a few things to help us transition between user and kernel mode:
! 208: */
! 209:
! 210: /* Memory models */
! 211: #define KERN_MM PSTATE_MM_TSO
! 212: #define USER_MM PSTATE_MM_RMO
! 213:
! 214: /*
! 215: * Register window handlers. These point to generic routines that check the
! 216: * stack pointer and then vector to the real handler. We could optimize this
! 217: * if we could guarantee only 32-bit or 64-bit stacks.
! 218: */
! 219: #define WSTATE_KERN 026
! 220: #define WSTATE_USER 022
! 221:
! 222: #define CWP 0x01f
! 223:
! 224: /* 64-byte alignment -- this seems the best place to put this. */
! 225: #define BLOCK_SIZE 64
! 226: #define BLOCK_ALIGN 0x3f
! 227:
! 228: #if defined(_KERNEL) && !defined(_LOCORE)
! 229:
! 230: extern u_int64_t ver; /* Copy of v9 version register. We need to read this only once, in locore.s. */
! 231: #ifndef SPLDEBUG
! 232: extern __inline void splx(int);
! 233: #endif
! 234:
! 235: #ifdef DIAGNOSTIC
! 236: /*
! 237: * Although this function is implemented in MI code, it must be in this MD
! 238: * header because we don't want this header to include MI includes.
! 239: */
! 240: void splassert_fail(int, int, const char *);
! 241: extern int splassert_ctl;
! 242: void splassert_check(int, const char *);
! 243: #define splassert(__wantipl) do { \
! 244: if (splassert_ctl > 0) { \
! 245: splassert_check(__wantipl, __func__); \
! 246: } \
! 247: } while (0)
! 248: #else
! 249: #define splassert(wantipl) do { /* nada */ } while (0)
! 250: #endif
! 251:
! 252: /*
! 253: * GCC pseudo-functions for manipulating privileged registers
! 254: */
! 255: extern __inline u_int64_t getpstate(void);
! 256: extern __inline
! 257: u_int64_t getpstate()
! 258: {
! 259: return (sparc_rdpr(pstate));
! 260: }
! 261:
! 262: extern __inline void setpstate(u_int64_t);
! 263: extern __inline void setpstate(u_int64_t newpstate)
! 264: {
! 265: sparc_wrpr(pstate, newpstate, 0);
! 266: }
! 267:
! 268: extern __inline int getcwp(void);
! 269: extern __inline
! 270: int getcwp()
! 271: {
! 272: return (sparc_rdpr(cwp));
! 273: }
! 274:
! 275: extern __inline void setcwp(u_int64_t);
! 276: extern __inline void
! 277: setcwp(u_int64_t newcwp)
! 278: {
! 279: sparc_wrpr(cwp, newcwp, 0);
! 280: }
! 281:
! 282: extern __inline u_int64_t getver(void);
! 283: extern __inline
! 284: u_int64_t getver()
! 285: {
! 286: return (sparc_rdpr(ver));
! 287: }
! 288:
! 289: extern __inline u_int64_t intr_disable(void);
! 290: extern __inline u_int64_t
! 291: intr_disable()
! 292: {
! 293: u_int64_t s;
! 294:
! 295: s = sparc_rdpr(pstate);
! 296: sparc_wrpr(pstate, s & ~PSTATE_IE, 0);
! 297: return (s);
! 298: }
! 299:
! 300: extern __inline void intr_restore(u_int64_t);
! 301: extern __inline void
! 302: intr_restore(u_int64_t s)
! 303: {
! 304: sparc_wrpr(pstate, s, 0);
! 305: }
! 306:
! 307: extern __inline void stxa_sync(u_int64_t, u_int64_t, u_int64_t);
! 308: extern __inline void
! 309: stxa_sync(u_int64_t va, u_int64_t asi, u_int64_t val)
! 310: {
! 311: u_int64_t s = intr_disable();
! 312: stxa_nc(va, asi, val);
! 313: membar(Sync);
! 314: intr_restore(s);
! 315: }
! 316:
! 317: /*
! 318: * GCC pseudo-functions for manipulating PIL
! 319: */
! 320:
! 321: #ifdef SPLDEBUG
! 322: void prom_printf(const char *fmt, ...);
! 323: extern int printspl;
! 324: #define SPLPRINT(x) if(printspl) { int i=10000000; prom_printf x ; while(i--); }
! 325: #define SPL(name, newpil) \
! 326: extern __inline int name##X(const char *, int); \
! 327: extern __inline int name##X(const char *file, int line) \
! 328: { \
! 329: u_int64_t oldpil = sparc_rdpr(pil); \
! 330: SPLPRINT(("{%s:%d %d=>%d}", file, line, oldpil, newpil)); \
! 331: sparc_wrpr(pil, newpil, 0); \
! 332: return (oldpil); \
! 333: }
! 334: /* A non-priority-decreasing version of SPL */
! 335: #define SPLHOLD(name, newpil) \
! 336: extern __inline int name##X(const char *, int); \
! 337: extern __inline int name##X(const char * file, int line) \
! 338: { \
! 339: int oldpil = sparc_rdpr(pil); \
! 340: if (__predict_false((u_int64_t)newpil <= oldpil)) \
! 341: return (oldpil); \
! 342: SPLPRINT(("{%s:%d %d->!d}", file, line, oldpil, newpil)); \
! 343: sparc_wrpr(pil, newpil, 0); \
! 344: return (oldpil); \
! 345: }
! 346:
! 347: #else
! 348: #define SPLPRINT(x)
! 349: #define SPL(name, newpil) \
! 350: extern __inline int name(void); \
! 351: extern __inline int name() \
! 352: { \
! 353: int oldpil; \
! 354: __asm __volatile(" rdpr %%pil, %0 \n" \
! 355: " wrpr %%g0, %1, %%pil \n" \
! 356: : "=&r" (oldpil) \
! 357: : "n" (newpil) \
! 358: : "%g0"); \
! 359: __asm __volatile("" : : : "memory"); \
! 360: return (oldpil); \
! 361: }
! 362: /* A non-priority-decreasing version of SPL */
! 363: #define SPLHOLD(name, newpil) \
! 364: extern __inline int name(void); \
! 365: extern __inline int name() \
! 366: { \
! 367: int oldpil; \
! 368: \
! 369: if (newpil <= 1) { \
! 370: __asm __volatile(" rdpr %%pil, %0 \n" \
! 371: " brnz,pn %0, 1f \n" \
! 372: " nop \n" \
! 373: " wrpr %%g0, %1, %%pil \n" \
! 374: "1: \n" \
! 375: : "=&r" (oldpil) \
! 376: : "I" (newpil) \
! 377: : "%g0"); \
! 378: } else { \
! 379: __asm __volatile(" rdpr %%pil, %0 \n" \
! 380: " cmp %0, %1 - 1 \n" \
! 381: " bgu,pn %%xcc, 1f \n" \
! 382: " nop \n" \
! 383: " wrpr %%g0, %1, %%pil \n" \
! 384: "1: \n" \
! 385: : "=&r" (oldpil) \
! 386: : "I" (newpil) \
! 387: : "cc"); \
! 388: } \
! 389: __asm __volatile("" : : : "memory"); \
! 390: return (oldpil); \
! 391: }
! 392: #endif
! 393:
! 394: SPL(spl0, 0)
! 395:
! 396: SPLHOLD(splsoftint, 1)
! 397: #define splsoftclock splsoftint
! 398: #define splsoftnet splsoftint
! 399:
! 400: /* audio software interrupts are at software level 4 */
! 401: SPLHOLD(splausoft, PIL_AUSOFT)
! 402:
! 403: /* floppy software interrupts are at software level 4 too */
! 404: SPLHOLD(splfdsoft, PIL_FDSOFT)
! 405:
! 406: /* Block devices */
! 407: SPLHOLD(splbio, PIL_BIO)
! 408:
! 409: /* network hardware interrupts are at level 6 */
! 410: SPLHOLD(splnet, PIL_NET)
! 411:
! 412: /* tty input runs at software level 6 */
! 413: SPLHOLD(spltty, PIL_TTY)
! 414:
! 415: /* parallel port runs at software level 6 */
! 416: SPLHOLD(spllpt, PIL_LPT)
! 417:
! 418: /*
! 419: * Memory allocation (must be as high as highest network, tty, or disk device)
! 420: */
! 421: SPLHOLD(splvm, PIL_VM)
! 422:
! 423: SPLHOLD(splclock, PIL_CLOCK)
! 424:
! 425: /* fd hardware interrupts are at level 11 */
! 426: SPLHOLD(splfd, PIL_FD)
! 427:
! 428: /* zs hardware interrupts are at level 12 */
! 429: SPLHOLD(splzs, PIL_SER)
! 430: SPLHOLD(splserial, PIL_SER)
! 431:
! 432: /* audio hardware interrupts are at level 13 */
! 433: SPLHOLD(splaudio, PIL_AUD)
! 434:
! 435: /* second sparc timer interrupts at level 14 */
! 436: SPLHOLD(splstatclock, PIL_STATCLOCK)
! 437:
! 438: SPLHOLD(splsched, PIL_SCHED)
! 439: SPLHOLD(spllock, PIL_LOCK)
! 440:
! 441: SPLHOLD(splhigh, PIL_HIGH)
! 442:
! 443: /* splx does not have a return value */
! 444: #ifdef SPLDEBUG
! 445:
! 446: #define spl0() spl0X(__FILE__, __LINE__)
! 447: #define splsoftint() splsoftintX(__FILE__, __LINE__)
! 448: #define splausoft() splausoftX(__FILE__, __LINE__)
! 449: #define splfdsoft() splfdsoftX(__FILE__, __LINE__)
! 450: #define splbio() splbioX(__FILE__, __LINE__)
! 451: #define splnet() splnetX(__FILE__, __LINE__)
! 452: #define spltty() splttyX(__FILE__, __LINE__)
! 453: #define spllpt() spllptX(__FILE__, __LINE__)
! 454: #define splvm() splvmX(__FILE__, __LINE__)
! 455: #define splclock() splclockX(__FILE__, __LINE__)
! 456: #define splfd() splfdX(__FILE__, __LINE__)
! 457: #define splzs() splzsX(__FILE__, __LINE__)
! 458: #define splserial() splzerialX(__FILE__, __LINE__)
! 459: #define splaudio() splaudioX(__FILE__, __LINE__)
! 460: #define splstatclock() splstatclockX(__FILE__, __LINE__)
! 461: #define splsched() splschedX(__FILE__, __LINE__)
! 462: #define spllock() spllockX(__FILE__, __LINE__)
! 463: #define splhigh() splhighX(__FILE__, __LINE__)
! 464: #define splx(x) splxX((x),__FILE__, __LINE__)
! 465:
! 466: extern __inline void splxX(u_int64_t, const char *, int);
! 467: extern __inline void
! 468: splxX(u_int64_t newpil, const char *file, int line)
! 469: #else
! 470: extern __inline void splx(int newpil)
! 471: #endif
! 472: {
! 473: #ifdef SPLDEBUG
! 474: u_int64_t oldpil = sparc_rdpr(pil);
! 475: SPLPRINT(("{%d->%d}", oldpil, newpil));
! 476: #endif
! 477: sparc_wrpr(pil, newpil, 0);
! 478: }
! 479: #endif /* KERNEL && !_LOCORE */
! 480:
! 481: #endif /* _SPARC64_PSL_ */
CVSweb