xref: /original-bsd/sys/sparc/include/psl.h (revision 3705696b)
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.1 (Berkeley) 06/11/93
17  *
18  * from: $Header: psl.h,v 1.12 92/11/26 02:04:42 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 #ifndef LOCORE
55 /*
56  * GCC pseudo-functions for manipulating PSR (primarily PIL field).
57  */
58 static __inline int getpsr() {
59 	int psr;
60 
61 	__asm __volatile("rd %%psr,%0" : "=r" (psr));
62 	return (psr);
63 }
64 
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 
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
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 */
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 /* LOCORE */
157 
158 #endif /* PSR_IMPL */
159