summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/isa.c
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>1997-06-02 08:19:06 +0000
committerdfr <dfr@FreeBSD.org>1997-06-02 08:19:06 +0000
commit6ba14cc686e7f472a6937088de33f356556bf759 (patch)
treec7c4bcee2063b32a59ec0918ff2f82386e367571 /sys/i386/isa/isa.c
parent33ddef35e6191fb2cd19ec096f2d855851331a45 (diff)
downloadFreeBSD-src-6ba14cc686e7f472a6937088de33f356556bf759.zip
FreeBSD-src-6ba14cc686e7f472a6937088de33f356556bf759.tar.gz
Move interrupt handling code from isa.c to a new file. This should make
isa.c (slightly) more portable and will make my life developing the really portable version much easier. Reviewed by: peter, fsmp
Diffstat (limited to 'sys/i386/isa/isa.c')
-rw-r--r--sys/i386/isa/isa.c358
1 files changed, 2 insertions, 356 deletions
diff --git a/sys/i386/isa/isa.c b/sys/i386/isa/isa.c
index a54f7bb..ccadc08 100644
--- a/sys/i386/isa/isa.c
+++ b/sys/i386/isa/isa.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
- * $Id: isa.c,v 1.87 1997/05/29 05:56:12 fsmp Exp $
+ * $Id: isa.c,v 1.88 1997/05/31 09:27:31 peter Exp $
*/
/*
@@ -47,8 +47,6 @@
* isa_dmastart()
*/
-#include "opt_auto_eoi.h"
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
@@ -65,6 +63,7 @@
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <i386/isa/isa_device.h>
+#include <i386/isa/intr_machdep.h>
#include <i386/isa/isa.h>
#include <i386/isa/icu.h>
#include <i386/isa/ic/i8237.h>
@@ -72,14 +71,6 @@
#include <sys/interrupt.h>
-#ifdef APIC_IO
-/*
- * This is to accommodate "mixed-mode" programming for
- * motherboards that don't connect the 8254 to the IO APIC.
- */
-#define AUTO_EOI_1
-#endif
-
/*
** Register definitions for DMA controller 1 (channels 0..3):
*/
@@ -96,40 +87,6 @@
#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */
#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */
-u_long *intr_countp[ICU_LEN];
-inthand2_t *intr_handler[ICU_LEN];
-u_int intr_mask[ICU_LEN];
-u_int* intr_mptr[ICU_LEN];
-int intr_unit[ICU_LEN];
-
-static inthand_t *fastintr[ICU_LEN] = {
- &IDTVEC(fastintr0), &IDTVEC(fastintr1),
- &IDTVEC(fastintr2), &IDTVEC(fastintr3),
- &IDTVEC(fastintr4), &IDTVEC(fastintr5),
- &IDTVEC(fastintr6), &IDTVEC(fastintr7),
- &IDTVEC(fastintr8), &IDTVEC(fastintr9),
- &IDTVEC(fastintr10), &IDTVEC(fastintr11),
- &IDTVEC(fastintr12), &IDTVEC(fastintr13),
- &IDTVEC(fastintr14), &IDTVEC(fastintr15)
-#if defined(APIC_IO)
- , &IDTVEC(fastintr16), &IDTVEC(fastintr17),
- &IDTVEC(fastintr18), &IDTVEC(fastintr19),
- &IDTVEC(fastintr20), &IDTVEC(fastintr21),
- &IDTVEC(fastintr22), &IDTVEC(fastintr23)
-#endif /* APIC_IO */
-};
-
-static inthand_t *slowintr[ICU_LEN] = {
- &IDTVEC(intr0), &IDTVEC(intr1), &IDTVEC(intr2), &IDTVEC(intr3),
- &IDTVEC(intr4), &IDTVEC(intr5), &IDTVEC(intr6), &IDTVEC(intr7),
- &IDTVEC(intr8), &IDTVEC(intr9), &IDTVEC(intr10), &IDTVEC(intr11),
- &IDTVEC(intr12), &IDTVEC(intr13), &IDTVEC(intr14), &IDTVEC(intr15)
-#if defined(APIC_IO)
- , &IDTVEC(intr16), &IDTVEC(intr17), &IDTVEC(intr18), &IDTVEC(intr19),
- &IDTVEC(intr20), &IDTVEC(intr21), &IDTVEC(intr22), &IDTVEC(intr23)
-#endif /* APIC_IO */
-};
-
static void config_isadev __P((struct isa_device *isdp, u_int *mp));
static void config_isadev_c __P((struct isa_device *isdp, u_int *mp,
int reconfig));
@@ -139,8 +96,6 @@ static void conflict __P((struct isa_device *dvp, struct isa_device *tmpdvp,
static int haveseen __P((struct isa_device *dvp, struct isa_device *tmpdvp,
u_int checkbits));
static int isa_dmarangecheck __P((caddr_t va, u_int length, int chan));
-static inthand2_t isa_strayintr;
-static void register_imask __P((struct isa_device *dvp, u_int mask));
/*
* print a conflict message
@@ -615,44 +570,6 @@ config_isadev_c(isdp, mp, reconfig)
}
}
-/*
- * Fill in default interrupt table (in case of spuruious interrupt
- * during configuration of kernel, setup interrupt control unit
- */
-void
-isa_defaultirq()
-{
- int i;
-
- /* icu vectors */
- for (i = 0; i < ICU_LEN; i++)
- icu_unset(i, (inthand2_t *)NULL);
-
- /* initialize 8259's */
- outb(IO_ICU1, 0x11); /* reset; program device, four bytes */
- outb(IO_ICU1+1, NRSVIDT); /* starting at this vector index */
- outb(IO_ICU1+1, 1<<2); /* slave on line 2 */
-#ifdef AUTO_EOI_1
- outb(IO_ICU1+1, 2 | 1); /* auto EOI, 8086 mode */
-#else
- outb(IO_ICU1+1, 1); /* 8086 mode */
-#endif
- outb(IO_ICU1+1, 0xff); /* leave interrupts masked */
- outb(IO_ICU1, 0x0a); /* default to IRR on read */
- outb(IO_ICU1, 0xc0 | (3 - 1)); /* pri order 3-7, 0-2 (com2 first) */
-
- outb(IO_ICU2, 0x11); /* reset; program device, four bytes */
- outb(IO_ICU2+1, NRSVIDT+8); /* staring at this vector index */
- outb(IO_ICU2+1,2); /* my slave id is 2 */
-#ifdef AUTO_EOI_2
- outb(IO_ICU2+1, 2 | 1); /* auto EOI, 8086 mode */
-#else
- outb(IO_ICU2+1,1); /* 8086 mode */
-#endif
- outb(IO_ICU2+1, 0xff); /* leave interrupts masked */
- outb(IO_ICU2, 0x0a); /* default to IRR on read */
-}
-
static caddr_t dma_bouncebuf[8];
static u_int dma_bouncebufsize[8];
static u_int8_t dma_bounced = 0;
@@ -956,70 +873,6 @@ isa_dmarangecheck(caddr_t va, u_int length, int chan) {
return (0);
}
-#define NMI_PARITY (1 << 7)
-#define NMI_IOCHAN (1 << 6)
-#define ENMI_WATCHDOG (1 << 7)
-#define ENMI_BUSTIMER (1 << 6)
-#define ENMI_IOSTATUS (1 << 5)
-
-/*
- * Handle a NMI, possibly a machine check.
- * return true to panic system, false to ignore.
- */
-int
-isa_nmi(cd)
- int cd;
-{
- int isa_port = inb(0x61);
- int eisa_port = inb(0x461);
- if(isa_port & NMI_PARITY) {
- panic("RAM parity error, likely hardware failure.");
- } else if(isa_port & NMI_IOCHAN) {
- panic("I/O channel check, likely hardware failure.");
- } else if(eisa_port & ENMI_WATCHDOG) {
- panic("EISA watchdog timer expired, likely hardware failure.");
- } else if(eisa_port & ENMI_BUSTIMER) {
- panic("EISA bus timeout, likely hardware failure.");
- } else if(eisa_port & ENMI_IOSTATUS) {
- panic("EISA I/O port status error.");
- } else {
- printf("\nNMI ISA %x, EISA %x\n", isa_port, eisa_port);
- return(0);
- }
-}
-
-/*
- * Caught a stray interrupt, notify
- */
-static void
-isa_strayintr(d)
- int d;
-{
-
- /* DON'T BOTHER FOR NOW! */
- /* for some reason, we get bursts of intr #7, even if not enabled! */
- /*
- * Well the reason you got bursts of intr #7 is because someone
- * raised an interrupt line and dropped it before the 8259 could
- * prioritize it. This is documented in the intel data book. This
- * means you have BAD hardware! I have changed this so that only
- * the first 5 get logged, then it quits logging them, and puts
- * out a special message. rgrimes 3/25/1993
- */
- /*
- * XXX TODO print a different message for #7 if it is for a
- * glitch. Glitches can be distinguished from real #7's by
- * testing that the in-service bit is _not_ set. The test
- * must be done before sending an EOI so it can't be done if
- * we are using AUTO_EOI_1.
- */
- if (intrcnt[NR_DEVICES + d] <= 5)
- log(LOG_ERR, "stray irq %d\n", d);
- if (intrcnt[NR_DEVICES + d] == 5)
- log(LOG_CRIT,
- "too many stray irq %d's; not logging any more\n", d);
-}
-
/*
* Find the highest priority enabled display device. Since we can't
* distinguish display devices from ttys, depend on display devices
@@ -1067,210 +920,3 @@ struct isa_device *find_isadev(table, driverp, unit)
return (table);
}
-/*
- * Return nonzero if a (masked) irq is pending for a given device.
- */
-#if defined(APIC_IO)
-
-int
-isa_irq_pending(dvp)
- struct isa_device *dvp;
-{
- /* read APIC IRR containing the 16 ISA INTerrupts */
- return ((lapic__irr1 & 0x00ffffff)
- & (u_int32_t)dvp->id_irq) ? 1 : 0;
-}
-
-/*
- * an 8259 specific routine,
- * for use by boot probes in certain device drivers.
- */
-int
-icu_irq_pending(dvp)
- struct isa_device *dvp;
-{
- unsigned id_irq;
- id_irq = dvp->id_irq;
- if (id_irq & 0xff)
- return (inb(IO_ICU1) & id_irq);
- return (inb(IO_ICU2) & (id_irq >> 8));
-}
-
-#else /* APIC_IO */
-
-int
-isa_irq_pending(dvp)
- struct isa_device *dvp;
-{
- unsigned id_irq;
- id_irq = dvp->id_irq;
- if (id_irq & 0xff)
- return (inb(IO_ICU1) & id_irq);
- return (inb(IO_ICU2) & (id_irq >> 8));
-}
-
-#endif /* APIC_IO */
-
-int
-update_intr_masks(void)
-{
- int intr, n=0;
- u_int mask,*maskptr;
-
- for (intr=0; intr < ICU_LEN; intr ++) {
-#if defined(APIC_IO)
- /* no 8259 SLAVE to ignore */
-#else
- if (intr==2) continue; /* ignore 8259 SLAVE output */
-#endif /* APIC_IO */
- maskptr = intr_mptr[intr];
- if (!maskptr) continue;
- *maskptr |= 1 << intr;
- mask = *maskptr;
- if (mask != intr_mask[intr]) {
-#if 0
- printf ("intr_mask[%2d] old=%08x new=%08x ptr=%p.\n",
- intr, intr_mask[intr], mask, maskptr);
-#endif
- intr_mask[intr]=mask;
- n++;
- }
-
- }
- return (n);
-}
-
-/*
- * The find_device_id function is only required because of the way the
- * device names are currently stored for reporting in systat or vmstat.
- * In fact, those programs should be modified to use the sysctl interface
- * to obtain a list of driver names by traversing intreclist_head[irq].
- */
-
-static int
-find_device_id(int irq)
-{
- char buf[16];
- char *cp;
- int free_id, id;
-
- sprintf(buf, "pci irq%d", irq);
- cp = intrnames;
- /* default to 0, which corresponds to clk0 */
- free_id = 0;
-
- for (id = 0; id < NR_DEVICES; id++) {
- if (strcmp(cp, buf) == 0)
- return (id);
- if (free_id == 0 && strcmp(cp, "pci irqnn") == 0)
- free_id = id;
- while (*cp++ != '\0');
- }
-#if 0
- if (free_id == 0) {
- /*
- * All pci irq counters are in use, perhaps because config
- * is old so there aren't any. Abuse the clk0 counter.
- */
- printf("\tcounting shared irq%d as clk0 irq\n", irq);
- }
-#endif
- return (free_id);
-}
-
-void
-update_intrname(int intr, int device_id)
-{
- char *cp;
- int id;
-
- if (device_id == -1)
- device_id = find_device_id(intr);
-
- if ((u_int)device_id >= NR_DEVICES)
- return;
-
- intr_countp[intr] = &intrcnt[device_id];
-
- for (cp = intrnames, id = 0; id <= device_id; id++)
- while (*cp++ != '\0')
- ;
- if (cp > eintrnames)
- return;
- if (intr < 10) {
- cp[-3] = intr + '0';
- cp[-2] = ' ';
- } else if (intr < 20) {
- cp[-3] = '1';
- cp[-2] = intr - 10 + '0';
- } else {
- cp[-3] = '2';
- cp[-2] = intr - 20 + '0';
- }
-}
-
-int
-icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags)
-{
- u_long ef;
- u_int mask = (maskptr ? *maskptr : 0);
-
-#if defined(APIC_IO)
- if ((u_int)intr >= ICU_LEN) /* no 8259 SLAVE to ignore */
-#else
- if ((u_int)intr >= ICU_LEN || intr == 2)
-#endif /* APIC_IO */
- if (intr_handler[intr] != isa_strayintr)
- return (EBUSY);
-
- ef = read_eflags();
- disable_intr();
- intr_handler[intr] = handler;
- intr_mptr[intr] = maskptr;
- intr_mask[intr] = mask | (1 << intr);
- intr_unit[intr] = arg;
- setidt(ICU_OFFSET + intr,
- flags & RI_FAST ? fastintr[intr] : slowintr[intr],
- SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
- INTREN(1 << intr);
- write_eflags(ef);
- return (0);
-}
-
-static void
-register_imask(dvp, mask)
- struct isa_device *dvp;
- u_int mask;
-{
- if (dvp->id_alive && dvp->id_irq) {
- int intr;
-
- intr = ffs(dvp->id_irq) - 1;
- intr_mask[intr] = mask | (1 <<intr);
- }
- (void) update_intr_masks();
-}
-
-int
-icu_unset(intr, handler)
- int intr;
- inthand2_t *handler;
-{
- u_long ef;
-
- if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr])
- return (EINVAL);
-
- INTRDIS(1 << intr);
- ef = read_eflags();
- disable_intr();
- intr_countp[intr] = &intrcnt[NR_DEVICES + intr];
- intr_handler[intr] = isa_strayintr;
- intr_mptr[intr] = NULL;
- intr_mask[intr] = HWI_MASK | SWI_MASK;
- intr_unit[intr] = intr;
- setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- write_eflags(ef);
- return (0);
-}
OpenPOWER on IntegriCloud