intr.h revision 1.20
1/* $OpenBSD: intr.h,v 1.20 2004/05/23 00:06:01 tedu 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_VM MAKEIPL(6) /* memory allocation */ 81#define IPL_IMP IPL_VM /* XXX - should not be here. */ 82#define IPL_AUDIO MAKEIPL(7) /* audio */ 83#define IPL_CLOCK MAKEIPL(8) /* clock */ 84#define IPL_STATCLOCK MAKEIPL(9) /* statclock */ 85#define IPL_HIGH MAKEIPL(9) /* everything */ 86 87/* Interrupt sharing types. */ 88#define IST_NONE 0 /* none */ 89#define IST_PULSE 1 /* pulsed */ 90#define IST_EDGE 2 /* edge-triggered */ 91#define IST_LEVEL 3 /* level-triggered */ 92 93/* Soft interrupt masks. */ 94#define SIR_CLOCK 31 95#define SIR_NET 30 96#define SIR_TTY 29 97 98#ifndef _LOCORE 99 100volatile int cpl; /* Current interrupt priority level. */ 101volatile int ipending; /* Interrupts pending. */ 102volatile int astpending;/* Asynchronous software traps (softints) pending. */ 103int imask[NIPL]; /* Bitmasks telling what interrupts are blocked. */ 104int iunmask[NIPL]; /* Bitmasks telling what interrupts are accepted. */ 105 106#define IMASK(level) imask[IPL(level)] 107#define IUNMASK(level) iunmask[IPL(level)] 108 109extern void Xspllower(void); 110 111int splraise(int); 112int spllower(int); 113void splx(int); 114void softintr(int); 115 116/* SPL asserts */ 117#ifdef DIAGNOSTIC 118/* 119 * Although this function is implemented in MI code, it must be in this MD 120 * header because we don't want this header to include MI includes. 121 */ 122void splassert_fail(int, int, const char *); 123extern int splassert_ctl; 124void splassert_check(int, const char *); 125#define splassert(__wantipl) do { \ 126 if (__predict_false(splassert_ctl > 0)) { \ 127 splassert_check(__wantipl, __func__); \ 128 } \ 129} while (0) 130#else 131#define splassert(wantipl) do { /* nada */ } while (0) 132#endif 133 134/* 135 * Hardware interrupt masks 136 */ 137#define splbio() splraise(IPL_BIO) 138#define splnet() splraise(IPL_NET) 139#define spltty() splraise(IPL_TTY) 140#define splaudio() splraise(IPL_AUDIO) 141#define splclock() splraise(IPL_CLOCK) 142#define splstatclock() splhigh() 143 144/* 145 * Software interrupt masks 146 * 147 * NOTE: spllowersoftclock() is used by hardclock() to lower the priority from 148 * clock to softclock before it calls softclock(). 149 */ 150#define spllowersoftclock() spllower(IPL_SOFTCLOCK) 151#define splsoftclock() splraise(IPL_SOFTCLOCK) 152#define splsoftnet() splraise(IPL_SOFTNET) 153#define splsofttty() splraise(IPL_SOFTTTY) 154 155/* 156 * Miscellaneous 157 */ 158#define splvm() splraise(IPL_VM) 159#define splimp() splvm() 160#define splhigh() splraise(IPL_HIGH) 161#define spl0() spllower(IPL_NONE) 162 163#define setsoftast() (astpending = 1) 164#define setsoftclock() softintr(1 << SIR_CLOCK) 165#define setsoftnet() softintr(1 << SIR_NET) 166#define setsofttty() softintr(1 << SIR_TTY) 167 168#endif /* !_LOCORE */ 169 170#endif /* !_I386_INTR_H_ */ 171