155124Storek /*
263320Sbostic * Copyright (c) 1992, 1993
363320Sbostic * The Regents of the University of California. All rights reserved.
455124Storek *
555124Storek * This software was developed by the Computer Systems Engineering group
655124Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
755124Storek * contributed to Berkeley.
855124Storek *
955501Sbostic * All advertising materials mentioning features or use of this software
1055501Sbostic * must display the following acknowledgement:
1155501Sbostic * This product includes software developed by the University of
1259210Storek * California, Lawrence Berkeley Laboratory.
1355501Sbostic *
1455124Storek * %sccs.include.redist.c%
1555124Storek *
16*64666Storek * @(#)psl.h 8.2 (Berkeley) 09/27/93
1755124Storek *
18*64666Storek * from: $Header: psl.h,v 1.13 93/09/27 01:37:25 torek Exp $
1955124Storek */
2055124Storek
2155124Storek #ifndef PSR_IMPL
2255124Storek
2355124Storek /*
2455124Storek * SPARC Process Status Register (in psl.h for hysterical raisins).
2555124Storek *
2655124Storek * The picture in the Sun manuals looks like this:
2755124Storek * 1 1
2855124Storek * 31 28 27 24 23 20 19 14 3 2 11 8 7 6 5 4 0
2955124Storek * +-------+-------+-------+-----------+-+-+-------+-+-+-+---------+
3055124Storek * | impl | ver | icc | reserved |E|E| pil |S|P|E| CWP |
3155124Storek * | | |n z v c| |C|F| | |S|T| |
3255124Storek * +-------+-------+-------+-----------+-+-+-------+-+-+-+---------+
3355124Storek */
3455124Storek
3555124Storek #define PSR_IMPL 0xf0000000 /* implementation */
3655124Storek #define PSR_VER 0x0f000000 /* version */
3755124Storek #define PSR_ICC 0x00f00000 /* integer condition codes */
3855124Storek #define PSR_N 0x00800000 /* negative */
3955124Storek #define PSR_Z 0x00400000 /* zero */
4055124Storek #define PSR_O 0x00200000 /* overflow */
4155124Storek #define PSR_C 0x00100000 /* carry */
4255124Storek #define PSR_EC 0x00002000 /* coprocessor enable */
4355124Storek #define PSR_EF 0x00001000 /* FP enable */
4455124Storek #define PSR_PIL 0x00000f00 /* interrupt level */
4555124Storek #define PSR_S 0x00000080 /* supervisor (kernel) mode */
4655124Storek #define PSR_PS 0x00000040 /* previous supervisor mode (traps) */
4755124Storek #define PSR_ET 0x00000020 /* trap enable */
4855124Storek #define PSR_CWP 0x0000001f /* current window pointer */
4955124Storek
5055124Storek #define PSR_BITS "\20\16EC\15EF\10S\7PS\6ET"
5155124Storek
5255124Storek #define PIL_CLOCK 10
5355124Storek
54*64666Storek #if defined(KERNEL) && !defined(LOCORE)
5555124Storek /*
5655124Storek * GCC pseudo-functions for manipulating PSR (primarily PIL field).
5755124Storek */
getpsr()5855124Storek static __inline int getpsr() {
5955124Storek int psr;
6055124Storek
6155124Storek __asm __volatile("rd %%psr,%0" : "=r" (psr));
6255124Storek return (psr);
6355124Storek }
6455124Storek
setpsr(int newpsr)6555124Storek static __inline void setpsr(int newpsr) {
6655124Storek __asm __volatile("wr %0,0,%%psr" : : "r" (newpsr));
6755124Storek __asm __volatile("nop");
6855124Storek __asm __volatile("nop");
6955124Storek __asm __volatile("nop");
7055124Storek }
7155124Storek
spl0()7255124Storek static __inline int spl0() {
7355124Storek int psr, oldipl;
7455124Storek
7555124Storek /*
7655124Storek * wrpsr xors two values: we choose old psr and old ipl here,
7755124Storek * which gives us the same value as the old psr but with all
7855124Storek * the old PIL bits turned off.
7955124Storek */
8055124Storek __asm __volatile("rd %%psr,%0" : "=r" (psr));
8155124Storek oldipl = psr & PSR_PIL;
8255124Storek __asm __volatile("wr %0,%1,%%psr" : : "r" (psr), "r" (oldipl));
8355124Storek
8455124Storek /*
8555124Storek * Three instructions must execute before we can depend
8655124Storek * on the bits to be changed.
8755124Storek */
8855124Storek __asm __volatile("nop; nop; nop");
8955124Storek return (oldipl);
9055124Storek }
9155124Storek
9255124Storek /*
9355124Storek * PIL 1 through 14 can use this macro.
9455124Storek * (spl0 and splhigh are special since they put all 0s or all 1s
9555124Storek * into the ipl field.)
9655124Storek */
9755124Storek #define SPL(name, newipl) \
9855124Storek static __inline int name() { \
9955124Storek int psr, oldipl; \
10055124Storek __asm __volatile("rd %%psr,%0" : "=r" (psr)); \
10155124Storek oldipl = psr & PSR_PIL; \
10255124Storek psr &= ~oldipl; \
10355124Storek __asm __volatile("wr %0,%1,%%psr" : : \
10455124Storek "r" (psr), "n" ((newipl) << 8)); \
10555124Storek __asm __volatile("nop; nop; nop"); \
10655124Storek return (oldipl); \
10755124Storek }
10855124Storek
10955124Storek SPL(splsoftint, 1)
11055124Storek #define splnet splsoftint
11155124Storek #define splsoftclock splsoftint
11255124Storek
11355124Storek /* Memory allocation (must be as high as highest network device) */
11455124Storek SPL(splimp, 5)
11555124Storek
11655124Storek /* tty input runs at software level 6 */
11755124Storek #define PIL_TTY 6
SPL(spltty,PIL_TTY)11855124Storek SPL(spltty, PIL_TTY)
11955124Storek
12055124Storek /* audio software interrupts are at software level 4 */
12155124Storek #define PIL_AUSOFT 4
12255124Storek SPL(splausoft, PIL_AUSOFT)
12355124Storek
12455124Storek SPL(splbio, 9)
12555124Storek
12655124Storek SPL(splclock, PIL_CLOCK)
12755124Storek
12855124Storek /* zs hardware interrupts are at level 12 */
12955124Storek SPL(splzs, 12)
13055124Storek
13155124Storek /* audio hardware interrupts are at level 13 */
13255124Storek SPL(splaudio, 13)
13355124Storek
13455124Storek /* second sparc timer interrupts at level 14 */
13555124Storek SPL(splstatclock, 14)
13655124Storek
13755124Storek static __inline int splhigh() {
13855124Storek int psr, oldipl;
13955124Storek
14055124Storek __asm __volatile("rd %%psr,%0" : "=r" (psr));
14155124Storek __asm __volatile("wr %0,0,%%psr" : : "r" (psr | PSR_PIL));
14255124Storek __asm __volatile("and %1,%2,%0; nop; nop" : "=r" (oldipl) : \
14355124Storek "r" (psr), "n" (PSR_PIL));
14455124Storek return (oldipl);
14555124Storek }
14655124Storek
14755124Storek /* splx does not have a return value */
splx(int newipl)14855124Storek static __inline void splx(int newipl) {
14955124Storek int psr;
15055124Storek
15155124Storek __asm __volatile("rd %%psr,%0" : "=r" (psr));
15255124Storek __asm __volatile("wr %0,%1,%%psr" : : \
15355124Storek "r" (psr & ~PSR_PIL), "rn" (newipl));
15455124Storek __asm __volatile("nop; nop; nop");
15555124Storek }
156*64666Storek #endif /* KERNEL && !LOCORE */
15755124Storek
15855124Storek #endif /* PSR_IMPL */
159