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