1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This software was developed by the Computer Systems Engineering group
6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7 * contributed to Berkeley.
8 *
9 * All advertising materials mentioning features or use of this software
10 * must display the following acknowledgement:
11 * This product includes software developed by the University of
12 * California, Lawrence Berkeley Laboratory.
13 *
14 * %sccs.include.redist.c%
15 *
16 * @(#)psl.h 8.2 (Berkeley) 09/27/93
17 *
18 * from: $Header: psl.h,v 1.13 93/09/27 01:37:25 torek Exp $
19 */
20
21 #ifndef PSR_IMPL
22
23 /*
24 * SPARC Process Status Register (in psl.h for hysterical raisins).
25 *
26 * The picture in the Sun manuals looks like this:
27 * 1 1
28 * 31 28 27 24 23 20 19 14 3 2 11 8 7 6 5 4 0
29 * +-------+-------+-------+-----------+-+-+-------+-+-+-+---------+
30 * | impl | ver | icc | reserved |E|E| pil |S|P|E| CWP |
31 * | | |n z v c| |C|F| | |S|T| |
32 * +-------+-------+-------+-----------+-+-+-------+-+-+-+---------+
33 */
34
35 #define PSR_IMPL 0xf0000000 /* implementation */
36 #define PSR_VER 0x0f000000 /* version */
37 #define PSR_ICC 0x00f00000 /* integer condition codes */
38 #define PSR_N 0x00800000 /* negative */
39 #define PSR_Z 0x00400000 /* zero */
40 #define PSR_O 0x00200000 /* overflow */
41 #define PSR_C 0x00100000 /* carry */
42 #define PSR_EC 0x00002000 /* coprocessor enable */
43 #define PSR_EF 0x00001000 /* FP enable */
44 #define PSR_PIL 0x00000f00 /* interrupt level */
45 #define PSR_S 0x00000080 /* supervisor (kernel) mode */
46 #define PSR_PS 0x00000040 /* previous supervisor mode (traps) */
47 #define PSR_ET 0x00000020 /* trap enable */
48 #define PSR_CWP 0x0000001f /* current window pointer */
49
50 #define PSR_BITS "\20\16EC\15EF\10S\7PS\6ET"
51
52 #define PIL_CLOCK 10
53
54 #if defined(KERNEL) && !defined(LOCORE)
55 /*
56 * GCC pseudo-functions for manipulating PSR (primarily PIL field).
57 */
getpsr()58 static __inline int getpsr() {
59 int psr;
60
61 __asm __volatile("rd %%psr,%0" : "=r" (psr));
62 return (psr);
63 }
64
setpsr(int newpsr)65 static __inline void setpsr(int newpsr) {
66 __asm __volatile("wr %0,0,%%psr" : : "r" (newpsr));
67 __asm __volatile("nop");
68 __asm __volatile("nop");
69 __asm __volatile("nop");
70 }
71
spl0()72 static __inline int spl0() {
73 int psr, oldipl;
74
75 /*
76 * wrpsr xors two values: we choose old psr and old ipl here,
77 * which gives us the same value as the old psr but with all
78 * the old PIL bits turned off.
79 */
80 __asm __volatile("rd %%psr,%0" : "=r" (psr));
81 oldipl = psr & PSR_PIL;
82 __asm __volatile("wr %0,%1,%%psr" : : "r" (psr), "r" (oldipl));
83
84 /*
85 * Three instructions must execute before we can depend
86 * on the bits to be changed.
87 */
88 __asm __volatile("nop; nop; nop");
89 return (oldipl);
90 }
91
92 /*
93 * PIL 1 through 14 can use this macro.
94 * (spl0 and splhigh are special since they put all 0s or all 1s
95 * into the ipl field.)
96 */
97 #define SPL(name, newipl) \
98 static __inline int name() { \
99 int psr, oldipl; \
100 __asm __volatile("rd %%psr,%0" : "=r" (psr)); \
101 oldipl = psr & PSR_PIL; \
102 psr &= ~oldipl; \
103 __asm __volatile("wr %0,%1,%%psr" : : \
104 "r" (psr), "n" ((newipl) << 8)); \
105 __asm __volatile("nop; nop; nop"); \
106 return (oldipl); \
107 }
108
109 SPL(splsoftint, 1)
110 #define splnet splsoftint
111 #define splsoftclock splsoftint
112
113 /* Memory allocation (must be as high as highest network device) */
114 SPL(splimp, 5)
115
116 /* tty input runs at software level 6 */
117 #define PIL_TTY 6
SPL(spltty,PIL_TTY)118 SPL(spltty, PIL_TTY)
119
120 /* audio software interrupts are at software level 4 */
121 #define PIL_AUSOFT 4
122 SPL(splausoft, PIL_AUSOFT)
123
124 SPL(splbio, 9)
125
126 SPL(splclock, PIL_CLOCK)
127
128 /* zs hardware interrupts are at level 12 */
129 SPL(splzs, 12)
130
131 /* audio hardware interrupts are at level 13 */
132 SPL(splaudio, 13)
133
134 /* second sparc timer interrupts at level 14 */
135 SPL(splstatclock, 14)
136
137 static __inline int splhigh() {
138 int psr, oldipl;
139
140 __asm __volatile("rd %%psr,%0" : "=r" (psr));
141 __asm __volatile("wr %0,0,%%psr" : : "r" (psr | PSR_PIL));
142 __asm __volatile("and %1,%2,%0; nop; nop" : "=r" (oldipl) : \
143 "r" (psr), "n" (PSR_PIL));
144 return (oldipl);
145 }
146
147 /* splx does not have a return value */
splx(int newipl)148 static __inline void splx(int newipl) {
149 int psr;
150
151 __asm __volatile("rd %%psr,%0" : "=r" (psr));
152 __asm __volatile("wr %0,%1,%%psr" : : \
153 "r" (psr & ~PSR_PIL), "rn" (newipl));
154 __asm __volatile("nop; nop; nop");
155 }
156 #endif /* KERNEL && !LOCORE */
157
158 #endif /* PSR_IMPL */
159