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