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