xref: /csrg-svn/sys/sparc/include/psl.h (revision 63320)
155124Storek /*
2*63320Sbostic  * Copyright (c) 1992, 1993
3*63320Sbostic  *	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*63320Sbostic  *	@(#)psl.h	8.1 (Berkeley) 06/11/93
1755124Storek  *
1859210Storek  * from: $Header: psl.h,v 1.12 92/11/26 02:04:42 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 
5455124Storek #ifndef LOCORE
5555124Storek /*
5655124Storek  * GCC pseudo-functions for manipulating PSR (primarily PIL field).
5755124Storek  */
5855124Storek static __inline int getpsr() {
5955124Storek 	int psr;
6055124Storek 
6155124Storek 	__asm __volatile("rd %%psr,%0" : "=r" (psr));
6255124Storek 	return (psr);
6355124Storek }
6455124Storek 
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 
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
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 */
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 }
15655124Storek #endif /* LOCORE */
15755124Storek 
15855124Storek #endif /* PSR_IMPL */
159