intr.h revision 1.8
1/* $OpenBSD: intr.h,v 1.8 2001/11/12 20:28:20 niklas Exp $ */ 2/* $NetBSD: intr.h,v 1.5 1996/05/13 06:11:28 mycroft Exp $ */ 3 4/* 5 * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Charles M. Hannum. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#ifndef _I386_INTR_H_ 34#define _I386_INTR_H_ 35 36/* 37 * Intel APICs (advanced programmable interrupt controllers) have 38 * bytesized priority registers where the upper nibble is the actual 39 * interrupt priority level (a.k.a. IPL). Interrupt vectors are 40 * closely tied to these levels as interrupts whose vectors' upper 41 * nibble is lower than or equal to the current level are blocked. 42 * Not all 256 possible vectors are available for interrupts in 43 * APIC systems, only 44 * 45 * For systems where instead the older ICU (interrupt controlling 46 * unit, a.k.a. PIC or 82C59) is used, the IPL is not directly useful, 47 * since the interrupt blocking is handled via interrupt masks instead 48 * of levels. However the IPL is easily used as an offset into arrays 49 * of masks. 50 */ 51#define IPLSHIFT 4 /* The upper nibble of vectors is the IPL. */ 52#define NIPL 16 /* Four bits of information gives as much. */ 53#define IPL(level) ((level) >> IPLSHIFT) /* Extract the IPL. */ 54/* XXX Maybe this IDTVECOFF definition should be elsewhere? */ 55#define IDTVECOFF 0x20 /* The lower 32 IDT vectors are reserved. */ 56 57/* 58 * This macro is only defined for 0 <= x < 14, i.e. there are fourteen 59 * distinct priority levels available for interrupts. 60 */ 61#define MAKEIPL(priority) (IDTVECOFF + ((priority) << IPLSHIFT)) 62 63/* 64 * Interrupt priority levels. 65 * XXX We are somewhat sloppy about what we mean by IPLs, sometimes 66 * XXX we refer to the eight-bit value suitable for storing into APICs' 67 * XXX priority registers, other times about the four-bit entity found 68 * XXX in the former values' upper nibble, which can be used as offsets 69 * XXX in various arrays of our implementation. We are hoping that 70 * XXX the context will provide enough information to not make this 71 * XXX sloppy naming a real problem. 72 */ 73#define IPL_NONE 0 /* nothing */ 74#define IPL_SOFTCLOCK MAKEIPL(0) /* timeouts */ 75#define IPL_SOFTNET MAKEIPL(1) /* protocol stacks */ 76#define IPL_BIO MAKEIPL(2) /* block I/O */ 77#define IPL_NET MAKEIPL(3) /* network */ 78#define IPL_SOFTTTY MAKEIPL(4) /* delayed terminal handling */ 79#define IPL_TTY MAKEIPL(5) /* terminal */ 80#define IPL_IMP MAKEIPL(6) /* memory allocation */ 81#define IPL_AUDIO MAKEIPL(7) /* audio */ 82#define IPL_CLOCK MAKEIPL(8) /* clock */ 83#define IPL_HIGH MAKEIPL(9) /* everything */ 84 85/* Interrupt sharing types. */ 86#define IST_NONE 0 /* none */ 87#define IST_PULSE 1 /* pulsed */ 88#define IST_EDGE 2 /* edge-triggered */ 89#define IST_LEVEL 3 /* level-triggered */ 90 91/* Soft interrupt masks. */ 92#define SIR_CLOCK 31 93#define SIR_NET 30 94#define SIR_TTY 29 95 96#ifndef _LOCORE 97 98volatile int cpl; /* Current interrupt priority level. */ 99volatile int ipending; /* Interrupts pending. */ 100volatile int astpending;/* Asynchronous software traps (softints) pending. */ 101int imask[NIPL]; /* Bitmasks telling what interrupts are blocked. */ 102int iunmask[NIPL]; /* Bitmasks telling what interrupts are accepted. */ 103 104#define IMASK(level) imask[IPL(level)] 105#define IUNMASK(level) iunmask[IPL(level)] 106 107extern void Xspllower __P((void)); 108 109static __inline int splraise __P((int)); 110static __inline int spllower __P((int)); 111static __inline void splx __P((int)); 112static __inline void softintr __P((int)); 113 114/* 115 * Raise current interrupt priority level, and return the old one. 116 */ 117static __inline int 118splraise(ncpl) 119 register int ncpl; 120{ 121 register int ocpl = cpl; 122 123 if (ncpl > ocpl) 124 cpl = ncpl; 125 return (ocpl); 126} 127 128/* 129 * Restore an old interrupt priority level. If any thereby unmasked 130 * interrupts are pending, call Xspllower() to process them. 131 */ 132static __inline void 133splx(ncpl) 134 register int ncpl; 135{ 136 cpl = ncpl; 137 if (ipending & IUNMASK(ncpl)) 138 Xspllower(); 139} 140 141/* 142 * Same as splx(), but we return the old value of spl, for the 143 * benefit of some splsoftclock() callers. 144 */ 145static __inline int 146spllower(ncpl) 147 register int ncpl; 148{ 149 register int ocpl = cpl; 150 151 splx(ncpl); 152 return (ocpl); 153} 154 155/* 156 * Hardware interrupt masks 157 */ 158#define splbio() splraise(IPL_BIO) 159#define splnet() splraise(IPL_NET) 160#define spltty() splraise(IPL_TTY) 161#define splaudio() splraise(IPL_AUDIO) 162#define splclock() splraise(IPL_CLOCK) 163#define splstatclock() splhigh() 164 165/* 166 * Software interrupt masks 167 * 168 * NOTE: spllowersoftclock() is used by hardclock() to lower the priority from 169 * clock to softclock before it calls softclock(). 170 */ 171#define spllowersoftclock() spllower(IPL_SOFTCLOCK) 172#define splsoftclock() splraise(IPL_SOFTCLOCK) 173#define splsoftnet() splraise(IPL_SOFTNET) 174#define splsofttty() splraise(IPL_SOFTTTY) 175 176/* 177 * Miscellaneous 178 */ 179#define splimp() splraise(IPL_IMP) 180#define splvm() splraise(IPL_IMP) 181#define splhigh() splraise(IPL_HIGH) 182#define spl0() spllower(IPL_NONE) 183 184/* 185 * Software interrupt registration 186 * 187 * We hand-code this to ensure that it's atomic. 188 */ 189static __inline void 190softintr(mask) 191 register int mask; 192{ 193 __asm __volatile("orl %0,_ipending" : : "ir" (mask)); 194} 195 196#define setsoftast() (astpending = 1) 197#define setsoftclock() softintr(1 << SIR_CLOCK) 198#define setsoftnet() softintr(1 << SIR_NET) 199#define setsofttty() softintr(1 << SIR_TTY) 200 201#endif /* !_LOCORE */ 202 203#endif /* !_I386_INTR_H_ */ 204