Annotation of src/sys/arch/sparc64/include/psl.h, Revision 1.57
1.57 ! nakayama 1: /* $NetBSD: psl.h,v 1.56 2014/12/25 14:02:03 nakayama Exp $ */
1.1 eeh 2:
3: /*
4: * Copyright (c) 1992, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * This software was developed by the Computer Systems Engineering group
8: * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9: * contributed to Berkeley.
10: *
11: * All advertising materials mentioning features or use of this software
12: * must display the following acknowledgement:
13: * This product includes software developed by the University of
14: * California, Lawrence Berkeley Laboratory.
15: *
16: * Redistribution and use in source and binary forms, with or without
17: * modification, are permitted provided that the following conditions
18: * are met:
19: * 1. Redistributions of source code must retain the above copyright
20: * notice, this list of conditions and the following disclaimer.
21: * 2. Redistributions in binary form must reproduce the above copyright
22: * notice, this list of conditions and the following disclaimer in the
23: * documentation and/or other materials provided with the distribution.
1.23 agc 24: * 3. Neither the name of the University nor the names of its contributors
1.1 eeh 25: * may be used to endorse or promote products derived from this software
26: * without specific prior written permission.
27: *
28: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38: * SUCH DAMAGE.
39: *
40: * @(#)psl.h 8.1 (Berkeley) 6/11/93
41: */
42:
43: #ifndef PSR_IMPL
44:
45: /*
1.19 mrg 46: * SPARC Process Status Register (in psl.h for hysterical raisins). This
47: * doesn't exist on the V9.
1.1 eeh 48: *
49: * The picture in the Sun manuals looks like this:
50: * 1 1
51: * 31 28 27 24 23 20 19 14 3 2 11 8 7 6 5 4 0
52: * +-------+-------+-------+-----------+-+-+-------+-+-+-+---------+
53: * | impl | ver | icc | reserved |E|E| pil |S|P|E| CWP |
54: * | | |n z v c| |C|F| | |S|T| |
55: * +-------+-------+-------+-----------+-+-+-------+-+-+-+---------+
56: */
57:
1.19 mrg 58: #define PSR_IMPL 0xf0000000 /* implementation */
59: #define PSR_VER 0x0f000000 /* version */
60: #define PSR_ICC 0x00f00000 /* integer condition codes */
61: #define PSR_N 0x00800000 /* negative */
62: #define PSR_Z 0x00400000 /* zero */
63: #define PSR_O 0x00200000 /* overflow */
64: #define PSR_C 0x00100000 /* carry */
65: #define PSR_EC 0x00002000 /* coprocessor enable */
66: #define PSR_EF 0x00001000 /* FP enable */
67: #define PSR_PIL 0x00000f00 /* interrupt level */
68: #define PSR_S 0x00000080 /* supervisor (kernel) mode */
69: #define PSR_PS 0x00000040 /* previous supervisor mode (traps) */
70: #define PSR_ET 0x00000020 /* trap enable */
71: #define PSR_CWP 0x0000001f /* current window pointer */
1.1 eeh 72:
1.19 mrg 73: #define PSR_BITS "\20\16EC\15EF\10S\7PS\6ET"
1.1 eeh 74:
75: /* Interesting spl()s */
76: #define PIL_SCSI 3
77: #define PIL_FDSOFT 4
1.19 mrg 78: #define PIL_AUSOFT 4
1.1 eeh 79: #define PIL_BIO 5
80: #define PIL_VIDEO 5
1.19 mrg 81: #define PIL_TTY 6
82: #define PIL_LPT 6
83: #define PIL_NET 6
1.33 yamt 84: #define PIL_VM 7
1.24 petrov 85: #define PIL_AUD 8
1.19 mrg 86: #define PIL_CLOCK 10
1.1 eeh 87: #define PIL_FD 11
88: #define PIL_SER 12
1.33 yamt 89: #define PIL_STATCLOCK 14
1.19 mrg 90: #define PIL_HIGH 15
91: #define PIL_SCHED PIL_CLOCK
92: #define PIL_LOCK PIL_HIGH
1.1 eeh 93:
94: /*
95: * SPARC V9 CCR register
96: */
97:
1.5 eeh 98: #define ICC_C 0x01L
99: #define ICC_V 0x02L
100: #define ICC_Z 0x04L
101: #define ICC_N 0x08L
1.1 eeh 102: #define XCC_SHIFT 4
103: #define XCC_C (ICC_C<<XCC_SHIFT)
104: #define XCC_V (ICC_V<<XCC_SHIFT)
105: #define XCC_Z (ICC_Z<<XCC_SHIFT)
106: #define XCC_N (ICC_N<<XCC_SHIFT)
107:
108:
109: /*
110: * SPARC V9 PSTATE register (what replaces the PSR in V9)
111: *
112: * Here's the layout:
113: *
114: * 11 10 9 8 7 6 5 4 3 2 1 0
115: * +------------------------------------------------------------+
116: * | IG | MG | CLE | TLE | MM | RED | PEF | AM | PRIV | IE | AG |
117: * +------------------------------------------------------------+
118: */
119:
120: #define PSTATE_IG 0x800 /* enable spitfire interrupt globals */
121: #define PSTATE_MG 0x400 /* enable spitfire MMU globals */
122: #define PSTATE_CLE 0x200 /* current little endian */
123: #define PSTATE_TLE 0x100 /* traps little endian */
124: #define PSTATE_MM 0x0c0 /* memory model */
125: #define PSTATE_MM_TSO 0x000 /* total store order */
126: #define PSTATE_MM_PSO 0x040 /* partial store order */
127: #define PSTATE_MM_RMO 0x080 /* Relaxed memory order */
128: #define PSTATE_RED 0x020 /* RED state */
129: #define PSTATE_PEF 0x010 /* enable floating point */
130: #define PSTATE_AM 0x008 /* 32-bit address masking */
131: #define PSTATE_PRIV 0x004 /* privileged mode */
132: #define PSTATE_IE 0x002 /* interrupt enable */
133: #define PSTATE_AG 0x001 /* enable alternate globals */
134:
1.19 mrg 135: #define PSTATE_BITS "\20\14IG\13MG\12CLE\11TLE\10\7MM\6RED\5PEF\4AM\3PRIV\2IE\1AG"
1.1 eeh 136:
1.12 eeh 137:
138: /*
139: * 32-bit code requires TSO or at best PSO since that's what's supported on
140: * SPARC V8 and earlier machines.
141: *
142: * 64-bit code sets the memory model in the ELF header.
143: *
144: * We're running kernel code in TSO for the moment so we don't need to worry
145: * about possible memory barrier bugs.
146: */
147:
1.6 mrg 148: #ifdef __arch64__
1.4 eeh 149: #define PSTATE_PROM (PSTATE_MM_TSO|PSTATE_PRIV)
150: #define PSTATE_NUCLEUS (PSTATE_MM_TSO|PSTATE_PRIV|PSTATE_AG)
151: #define PSTATE_KERN (PSTATE_MM_TSO|PSTATE_PRIV)
152: #define PSTATE_INTR (PSTATE_KERN|PSTATE_IE)
1.12 eeh 153: #define PSTATE_USER32 (PSTATE_MM_TSO|PSTATE_AM|PSTATE_IE)
1.13 eeh 154: #define PSTATE_USER (PSTATE_MM_RMO|PSTATE_IE)
1.4 eeh 155: #else
1.1 eeh 156: #define PSTATE_PROM (PSTATE_MM_TSO|PSTATE_PRIV)
157: #define PSTATE_NUCLEUS (PSTATE_MM_TSO|PSTATE_AM|PSTATE_PRIV|PSTATE_AG)
158: #define PSTATE_KERN (PSTATE_MM_TSO|PSTATE_AM|PSTATE_PRIV)
159: #define PSTATE_INTR (PSTATE_KERN|PSTATE_IE)
1.12 eeh 160: #define PSTATE_USER32 (PSTATE_MM_TSO|PSTATE_AM|PSTATE_IE)
161: #define PSTATE_USER (PSTATE_MM_TSO|PSTATE_AM|PSTATE_IE)
1.1 eeh 162: #endif
163:
1.19 mrg 164:
1.1 eeh 165: /*
166: * SPARC V9 TSTATE register
167: *
1.57 ! nakayama 168: * 39 32 31 24 23 20 19 8 7 5 4 0
1.1 eeh 169: * +-----+-----+-----+--------+---+-----+
170: * | CCR | ASI | - | PSTATE | - | CWP |
171: * +-----+-----+-----+--------+---+-----+
1.19 mrg 172: */
1.1 eeh 173:
174: #define TSTATE_CWP 0x01f
1.57 ! nakayama 175: #define TSTATE_PSTATE 0xfff00
1.1 eeh 176: #define TSTATE_PSTATE_SHIFT 8
177: #define TSTATE_ASI 0xff000000LL
178: #define TSTATE_ASI_SHIFT 24
179: #define TSTATE_CCR 0xff00000000LL
180: #define TSTATE_CCR_SHIFT 32
181:
1.39 nakayama 182: #define PSRCC_TO_TSTATE(x) (((int64_t)(x)&PSR_ICC)<<(TSTATE_CCR_SHIFT-20))
183: #define TSTATECCR_TO_PSR(x) (((x)&TSTATE_CCR)>>(TSTATE_CCR_SHIFT-20))
1.1 eeh 184:
185: /*
186: * These are here to simplify life.
187: */
188: #define TSTATE_IG (PSTATE_IG<<TSTATE_PSTATE_SHIFT)
189: #define TSTATE_MG (PSTATE_MG<<TSTATE_PSTATE_SHIFT)
190: #define TSTATE_CLE (PSTATE_CLE<<TSTATE_PSTATE_SHIFT)
191: #define TSTATE_TLE (PSTATE_TLE<<TSTATE_PSTATE_SHIFT)
192: #define TSTATE_MM (PSTATE_MM<<TSTATE_PSTATE_SHIFT)
193: #define TSTATE_MM_TSO (PSTATE_MM_TSO<<TSTATE_PSTATE_SHIFT)
194: #define TSTATE_MM_PSO (PSTATE_MM_PSO<<TSTATE_PSTATE_SHIFT)
195: #define TSTATE_MM_RMO (PSTATE_MM_RMO<<TSTATE_PSTATE_SHIFT)
196: #define TSTATE_RED (PSTATE_RED<<TSTATE_PSTATE_SHIFT)
197: #define TSTATE_PEF (PSTATE_PEF<<TSTATE_PSTATE_SHIFT)
198: #define TSTATE_AM (PSTATE_AM<<TSTATE_PSTATE_SHIFT)
199: #define TSTATE_PRIV (PSTATE_PRIV<<TSTATE_PSTATE_SHIFT)
200: #define TSTATE_IE (PSTATE_IE<<TSTATE_PSTATE_SHIFT)
201: #define TSTATE_AG (PSTATE_AG<<TSTATE_PSTATE_SHIFT)
202:
1.19 mrg 203: #define TSTATE_BITS "\20\14IG\13MG\12CLE\11TLE\10\7MM\6RED\5PEF\4AM\3PRIV\2IE\1AG"
1.1 eeh 204:
1.40 nakayama 205: #define TSTATE_KERN ((PSTATE_KERN)<<TSTATE_PSTATE_SHIFT)
206: #define TSTATE_USER ((PSTATE_USER)<<TSTATE_PSTATE_SHIFT)
1.1 eeh 207: /*
208: * SPARC V9 VER version register.
209: *
210: * 63 48 47 32 31 24 23 16 15 8 7 5 4 0
211: * +-------+------+------+-----+-------+---+--------+
212: * | manuf | impl | mask | - | maxtl | - | maxwin |
213: * +-------+------+------+-----+-------+---+--------+
214: *
215: */
216:
217: #define VER_MANUF 0xffff000000000000LL
218: #define VER_MANUF_SHIFT 48
219: #define VER_IMPL 0x0000ffff00000000LL
220: #define VER_IMPL_SHIFT 32
221: #define VER_MASK 0x00000000ff000000LL
222: #define VER_MASK_SHIFT 24
223: #define VER_MAXTL 0x000000000000ff00LL
224: #define VER_MAXTL_SHIFT 8
225: #define VER_MAXWIN 0x000000000000001fLL
226:
1.48 mrg 227: #define MANUF_FUJITSU 0x04 /* Fujitsu SPARC64 */
228: #define MANUF_SUN 0x17 /* Sun UltraSPARC */
229:
1.47 mrg 230: #define IMPL_SPARC64 0x01 /* SPARC64 */
231: #define IMPL_SPARC64_II 0x02 /* SPARC64-II */
232: #define IMPL_SPARC64_III 0x03 /* SPARC64-III */
233: #define IMPL_SPARC64_IV 0x04 /* SPARC64-IV */
234: #define IMPL_ZEUS 0x05 /* SPARC64-V */
235: #define IMPL_OLYMPUS_C 0x06 /* SPARC64-VI */
236: #define IMPL_JUPITER 0x07 /* SPARC64-VII */
237:
1.45 nakayama 238: #define IMPL_SPITFIRE 0x10 /* UltraSPARC-I */
239: #define IMPL_BLACKBIRD 0x11 /* UltraSPARC-II */
240: #define IMPL_SABRE 0x12 /* UltraSPARC-IIi */
241: #define IMPL_HUMMINGBIRD 0x13 /* UltraSPARC-IIe */
242: #define IMPL_CHEETAH 0x14 /* UltraSPARC-III */
243: #define IMPL_CHEETAH_PLUS 0x15 /* UltraSPARC-III+ */
244: #define IMPL_JALAPENO 0x16 /* UltraSPARC-IIIi */
245: #define IMPL_JAGUAR 0x18 /* UltraSPARC-IV */
246: #define IMPL_PANTHER 0x19 /* UltraSPARC-IV+ */
247: #define IMPL_SERRANO 0x22 /* UltraSPARC-IIIi+ */
248:
1.1 eeh 249: /*
250: * Here are a few things to help us transition between user and kernel mode:
251: */
252:
253: /* Memory models */
254: #define KERN_MM PSTATE_MM_TSO
255: #define USER_MM PSTATE_MM_RMO
256:
1.4 eeh 257: /*
258: * Register window handlers. These point to generic routines that check the
259: * stack pointer and then vector to the real handler. We could optimize this
260: * if we could guarantee only 32-bit or 64-bit stacks.
261: */
1.1 eeh 262: #define WSTATE_KERN 026
263: #define WSTATE_USER 022
264:
265: #define CWP 0x01f
266:
1.51 nakayama 267: /*
268: * UltraSPARC Ancillary State Registers
269: */
270: #define SET_SOFTINT %asr20 /* Set Software Interrupt register bits */
271: #define CLEAR_SOFTINT %asr21 /* Clear Software Interrupt register bits */
272: #define SOFTINT %asr22 /* Software Interrupt register */
273: #define TICK_CMPR %asr23 /* TICK Compare register */
274: #define STICK %asr24 /* STICK register */
275: #define STICK_CMPR %asr25 /* STICK Compare register */
276:
277: /* SOFTINT bit descriptions */
278: #define TICK_INT 0x01 /* CPU clock timer interrupt */
279: #define STICK_INT (0x1<<16) /* system clock timer interrupt */
280:
1.1 eeh 281: /* 64-byte alignment -- this seems the best place to put this. */
1.49 mrg 282: #define SPARC64_BLOCK_SIZE 64
283: #define SPARC64_BLOCK_ALIGN 0x3f
1.1 eeh 284:
285: #if defined(_KERNEL) && !defined(_LOCORE)
286:
1.56 nakayama 287: #if defined(_KERNEL_OPT)
288: #include "opt_sparc_arch.h"
289: #endif
290:
291: /*
292: * Put "memory" to asm inline on sun4v to avoid issuing rdpr %ver
293: * before checking cputyp as a result of code moving by compiler
294: * optimization.
295: */
296: #ifdef SUN4V
297: #define constasm_clobbers "memory"
298: #else
299: #define constasm_clobbers
300: #endif
301:
1.1 eeh 302: /*
1.52 nakayama 303: * Inlines for manipulating privileged and ancillary state registers
1.1 eeh 304: */
1.54 nakayama 305: #define SPARC64_RDCONST_DEF(rd, name, reg, type) \
306: static __inline __constfunc type get##name(void) \
307: { \
308: type _val; \
1.56 nakayama 309: __asm(#rd " %" #reg ",%0" : "=r" (_val) : : constasm_clobbers); \
1.54 nakayama 310: return _val; \
311: }
1.52 nakayama 312: #define SPARC64_RD_DEF(rd, name, reg, type) \
313: static __inline type get##name(void) \
1.43 nakayama 314: { \
1.52 nakayama 315: type _val; \
316: __asm volatile(#rd " %" #reg ",%0" : "=r" (_val)); \
317: return _val; \
1.43 nakayama 318: }
1.52 nakayama 319: #define SPARC64_WR_DEF(wr, name, reg, type) \
320: static __inline void set##name(type _val) \
1.43 nakayama 321: { \
1.52 nakayama 322: __asm volatile(#wr " %0,0,%" #reg : : "r" (_val) : "memory"); \
1.41 nakayama 323: }
324:
325: #ifdef __arch64__
1.54 nakayama 326: #define SPARC64_RDCONST64_DEF(rd, name, reg) \
327: SPARC64_RDCONST_DEF(rd, name, reg, uint64_t)
1.52 nakayama 328: #define SPARC64_RD64_DEF(rd, name, reg) SPARC64_RD_DEF(rd, name, reg, uint64_t)
329: #define SPARC64_WR64_DEF(wr, name, reg) SPARC64_WR_DEF(wr, name, reg, uint64_t)
1.41 nakayama 330: #else
1.54 nakayama 331: #define SPARC64_RDCONST64_DEF(rd, name, reg) \
332: static __inline __constfunc uint64_t get##name(void) \
333: { \
334: uint32_t _hi, _lo; \
335: __asm(#rd " %" #reg ",%0; srl %0,0,%1; srlx %0,32,%0" \
1.56 nakayama 336: : "=r" (_hi), "=r" (_lo) : : constasm_clobbers); \
1.54 nakayama 337: return ((uint64_t)_hi << 32) | _lo; \
338: }
1.52 nakayama 339: #define SPARC64_RD64_DEF(rd, name, reg) \
340: static __inline uint64_t get##name(void) \
1.43 nakayama 341: { \
342: uint32_t _hi, _lo; \
1.52 nakayama 343: __asm volatile(#rd " %" #reg ",%0; srl %0,0,%1; srlx %0,32,%0" \
1.43 nakayama 344: : "=r" (_hi), "=r" (_lo)); \
345: return ((uint64_t)_hi << 32) | _lo; \
346: }
1.52 nakayama 347: #define SPARC64_WR64_DEF(wr, name, reg) \
348: static __inline void set##name(uint64_t _val) \
1.43 nakayama 349: { \
1.52 nakayama 350: uint32_t _hi = _val >> 32, _lo = _val; \
351: __asm volatile("sllx %1,32,%0; or %0,%2,%0; " #wr " %0,0,%" #reg\
1.43 nakayama 352: : "=&r" (_hi) /* scratch register */ \
353: : "r" (_hi), "r" (_lo) : "memory"); \
354: }
1.41 nakayama 355: #endif
356:
1.52 nakayama 357: #define SPARC64_RDPR_DEF(name, reg, type) SPARC64_RD_DEF(rdpr, name, reg, type)
358: #define SPARC64_WRPR_DEF(name, reg, type) SPARC64_WR_DEF(wrpr, name, reg, type)
359: #define SPARC64_RDPR64_DEF(name, reg) SPARC64_RD64_DEF(rdpr, name, reg)
360: #define SPARC64_WRPR64_DEF(name, reg) SPARC64_WR64_DEF(wrpr, name, reg)
361: #define SPARC64_RDASR64_DEF(name, reg) SPARC64_RD64_DEF(rd, name, reg)
362: #define SPARC64_WRASR64_DEF(name, reg) SPARC64_WR64_DEF(wr, name, reg)
363:
1.43 nakayama 364: /* Tick Register (PR 4) */
1.52 nakayama 365: SPARC64_RDPR64_DEF(tick, %tick) /* gettick() */
366: SPARC64_WRPR64_DEF(tick, %tick) /* settick() */
1.43 nakayama 367:
368: /* Processor State Register (PR 6) */
1.52 nakayama 369: SPARC64_RDPR_DEF(pstate, %pstate, int) /* getpstate() */
370: SPARC64_WRPR_DEF(pstate, %pstate, int) /* setpstate() */
1.43 nakayama 371:
372: /* Trap Level Register (PR 7) */
1.52 nakayama 373: SPARC64_RDPR_DEF(tl, %tl, int) /* gettl() */
1.43 nakayama 374:
375: /* Current Window Pointer Register (PR 9) */
1.52 nakayama 376: SPARC64_RDPR_DEF(cwp, %cwp, int) /* getcwp() */
377: SPARC64_WRPR_DEF(cwp, %cwp, int) /* setcwp() */
1.1 eeh 378:
1.43 nakayama 379: /* Version Register (PR 31) */
1.54 nakayama 380: SPARC64_RDCONST64_DEF(rdpr, ver, %ver) /* getver() */
1.52 nakayama 381:
382: /* System Tick Register (ASR 24) */
383: SPARC64_RDASR64_DEF(stick, STICK) /* getstick() */
384: SPARC64_WRASR64_DEF(stick, STICK) /* setstick() */
1.1 eeh 385:
1.46 mrg 386: /* Some simple macros to check the cpu type. */
1.55 nakayama 387: #define GETVER_CPU_MASK() ((getver() & VER_MASK) >> VER_MASK_SHIFT)
1.46 mrg 388: #define GETVER_CPU_IMPL() ((getver() & VER_IMPL) >> VER_IMPL_SHIFT)
1.47 mrg 389: #define GETVER_CPU_MANUF() ((getver() & VER_MANUF) >> VER_MANUF_SHIFT)
390: #define CPU_IS_SPITFIRE() (GETVER_CPU_IMPL() == IMPL_SPITFIRE)
1.50 macallan 391: #define CPU_IS_HUMMINGBIRD() (GETVER_CPU_IMPL() == IMPL_HUMMINGBIRD)
1.47 mrg 392: #define CPU_IS_USIIIi() ((GETVER_CPU_IMPL() == IMPL_JALAPENO) || \
393: (GETVER_CPU_IMPL() == IMPL_SERRANO))
1.46 mrg 394: #define CPU_IS_USIII_UP() (GETVER_CPU_IMPL() >= IMPL_CHEETAH)
1.47 mrg 395: #define CPU_IS_SPARC64_V_UP() (GETVER_CPU_MANUF() == MANUF_FUJITSU && \
396: GETVER_CPU_IMPL() >= IMPL_ZEUS)
1.46 mrg 397:
1.31 perry 398: static __inline int
1.26 chs 399: intr_disable(void)
400: {
401: int pstate = getpstate();
402:
403: setpstate(pstate & ~PSTATE_IE);
1.41 nakayama 404: return pstate;
1.26 chs 405: }
406:
1.31 perry 407: static __inline void
1.26 chs 408: intr_restore(int pstate)
409: {
410: setpstate(pstate);
411: }
412:
1.1 eeh 413: /*
414: * GCC pseudo-functions for manipulating PIL
415: */
416:
417: #ifdef SPLDEBUG
1.32 cdi 418: void prom_printf(const char *fmt, ...);
1.1 eeh 419: extern int printspl;
1.21 chs 420: #define SPLPRINT(x) \
421: { \
422: if (printspl) { \
423: int i = 10000000; \
424: prom_printf x ; \
425: while (i--) \
426: ; \
427: } \
428: }
1.1 eeh 429: #define SPL(name, newpil) \
1.31 perry 430: static __inline int name##X(const char* file, int line) \
1.1 eeh 431: { \
432: int oldpil; \
1.30 perry 433: __asm volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
1.1 eeh 434: SPLPRINT(("{%s:%d %d=>%d}", file, line, oldpil, newpil)); \
1.38 martin 435: __asm volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil) : "memory"); \
1.1 eeh 436: return (oldpil); \
437: }
438: /* A non-priority-decreasing version of SPL */
439: #define SPLHOLD(name, newpil) \
1.31 perry 440: static __inline int name##X(const char* file, int line) \
1.1 eeh 441: { \
442: int oldpil; \
1.30 perry 443: __asm volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
1.1 eeh 444: if (newpil <= oldpil) \
445: return oldpil; \
446: SPLPRINT(("{%s:%d %d->!d}", file, line, oldpil, newpil)); \
1.38 martin 447: __asm volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil) : "memory"); \
1.1 eeh 448: return (oldpil); \
449: }
450:
451: #else
452: #define SPLPRINT(x)
453: #define SPL(name, newpil) \
1.31 perry 454: static __inline int name(void) \
1.1 eeh 455: { \
456: int oldpil; \
1.30 perry 457: __asm volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
1.38 martin 458: __asm volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil) : "memory"); \
1.1 eeh 459: return (oldpil); \
460: }
461: /* A non-priority-decreasing version of SPL */
462: #define SPLHOLD(name, newpil) \
1.31 perry 463: static __inline int name(void) \
1.1 eeh 464: { \
465: int oldpil; \
1.30 perry 466: __asm volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
1.1 eeh 467: if (newpil <= oldpil) \
468: return oldpil; \
1.38 martin 469: __asm volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil) : "memory"); \
1.1 eeh 470: return (oldpil); \
471: }
472: #endif
473:
1.35 ad 474: typedef uint8_t ipl_t;
1.34 yamt 475: typedef struct {
476: ipl_t _ipl;
477: } ipl_cookie_t;
478:
1.43 nakayama 479: static __inline ipl_cookie_t
1.34 yamt 480: makeiplcookie(ipl_t ipl)
481: {
482:
483: return (ipl_cookie_t){._ipl = ipl};
484: }
485:
1.33 yamt 486: static __inline int __attribute__((__unused__))
1.34 yamt 487: splraiseipl(ipl_cookie_t icookie)
1.33 yamt 488: {
1.34 yamt 489: int newpil = icookie._ipl;
1.33 yamt 490: int oldpil;
491:
492: /*
493: * NetBSD/sparc64's IPL_* constants equate directly to the
494: * corresponding PIL_* names; no need to map them here.
495: */
1.41 nakayama 496: __asm volatile("rdpr %%pil,%0" : "=r" (oldpil));
1.33 yamt 497: if (newpil <= oldpil)
498: return (oldpil);
1.41 nakayama 499: __asm volatile("wrpr %0,0,%%pil" : : "r" (newpil) : "memory");
1.33 yamt 500: return (oldpil);
501: }
502:
1.1 eeh 503: SPL(spl0, 0)
504:
1.11 thorpej 505: SPLHOLD(splsoftint, 1)
506: #define splsoftclock splsoftint
1.1 eeh 507: #define splsoftnet splsoftint
508:
1.22 nakayama 509: SPLHOLD(splsoftserial, 4)
510:
1.1 eeh 511: /* audio software interrupts are at software level 4 */
512: SPLHOLD(splausoft, PIL_AUSOFT)
513:
514: /* floppy software interrupts are at software level 4 too */
515: SPLHOLD(splfdsoft, PIL_FDSOFT)
516:
517: /*
518: * Memory allocation (must be as high as highest network, tty, or disk device)
519: */
1.33 yamt 520: SPLHOLD(splvm, PIL_VM)
1.1 eeh 521:
1.16 eeh 522: SPLHOLD(splsched, PIL_SCHED)
1.14 thorpej 523:
1.16 eeh 524: SPLHOLD(splhigh, PIL_HIGH)
1.1 eeh 525:
526: /* splx does not have a return value */
527: #ifdef SPLDEBUG
528: #define spl0() spl0X(__FILE__, __LINE__)
529: #define splsoftint() splsoftintX(__FILE__, __LINE__)
1.22 nakayama 530: #define splsoftserial() splsoftserialX(__FILE__, __LINE__)
1.1 eeh 531: #define splausoft() splausoftX(__FILE__, __LINE__)
532: #define splfdsoft() splfdsoftX(__FILE__, __LINE__)
1.18 thorpej 533: #define splvm() splvmX(__FILE__, __LINE__)
1.1 eeh 534: #define splclock() splclockX(__FILE__, __LINE__)
535: #define splfd() splfdX(__FILE__, __LINE__)
536: #define splzs() splzsX(__FILE__, __LINE__)
1.7 eeh 537: #define splserial() splzerialX(__FILE__, __LINE__)
1.1 eeh 538: #define splaudio() splaudioX(__FILE__, __LINE__)
539: #define splstatclock() splstatclockX(__FILE__, __LINE__)
1.16 eeh 540: #define splsched() splschedX(__FILE__, __LINE__)
541: #define spllock() spllockX(__FILE__, __LINE__)
1.1 eeh 542: #define splhigh() splhighX(__FILE__, __LINE__)
543: #define splx(x) splxX((x),__FILE__, __LINE__)
544:
1.31 perry 545: static __inline void splxX(int newpil, const char *file, int line)
1.1 eeh 546: #else
1.31 perry 547: static __inline void splx(int newpil)
1.1 eeh 548: #endif
549: {
1.21 chs 550: #ifdef SPLDEBUG
1.1 eeh 551: int pil;
552:
1.30 perry 553: __asm volatile("rdpr %%pil,%0" : "=r" (pil));
1.21 chs 554: SPLPRINT(("{%d->%d}", pil, newpil));
555: #endif
1.38 martin 556: __asm volatile("wrpr %%g0,%0,%%pil" : : "rn" (newpil) : "memory");
1.1 eeh 557: }
558: #endif /* KERNEL && !_LOCORE */
559:
560: #endif /* PSR_IMPL */
CVSweb <webmaster@jp.NetBSD.org>