summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/amd64/tsc.c12
-rw-r--r--sys/amd64/isa/clock.c12
-rw-r--r--sys/amd64/isa/isa.c358
-rw-r--r--sys/amd64/isa/vector.S238
-rw-r--r--sys/amd64/isa/vector.s238
-rw-r--r--sys/dev/sio/sio.c3
-rw-r--r--sys/i386/i386/tsc.c12
-rw-r--r--sys/i386/isa/clock.c12
-rw-r--r--sys/i386/isa/icu.s20
-rw-r--r--sys/i386/isa/isa.c358
-rw-r--r--sys/i386/isa/isa_device.h65
-rw-r--r--sys/i386/isa/sio.c3
-rw-r--r--sys/i386/isa/vector.s238
-rw-r--r--sys/isa/atrtc.c12
-rw-r--r--sys/isa/sio.c3
15 files changed, 856 insertions, 728 deletions
diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c
index 35f2e42..e3f3f21 100644
--- a/sys/amd64/amd64/tsc.c
+++ b/sys/amd64/amd64/tsc.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.13 1994/08/13 03:49:56 wollman Exp $
+ * $Id: clock.c,v 1.14 1994/08/15 03:15:18 wollman Exp $
*/
/*
@@ -497,16 +497,14 @@ test_inittodr(time_t base)
/*
* Wire clock interrupt in.
*/
-#define V(s) __CONCAT(V, s)
-extern void V(clk)();
-extern void V(rtc)();
-
void
enablertclock()
{
- setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL);
+ register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, clkintr,
+ HWI_MASK | SWI_MASK, /* unit */ 0);
INTREN(IRQ0);
- setidt(ICU_OFFSET+8, &V(rtc), SDT_SYS386IGT, SEL_KPL);
+ register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, rtcintr,
+ SWI_CLOCK_MASK, /* unit */ 0);
INTREN(IRQ8);
outb(IO_RTC, RTC_STATUSB);
outb(IO_RTC+1, RTCSB_PINTR | RTCSB_24HR);
diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c
index 35f2e42..e3f3f21 100644
--- a/sys/amd64/isa/clock.c
+++ b/sys/amd64/isa/clock.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.13 1994/08/13 03:49:56 wollman Exp $
+ * $Id: clock.c,v 1.14 1994/08/15 03:15:18 wollman Exp $
*/
/*
@@ -497,16 +497,14 @@ test_inittodr(time_t base)
/*
* Wire clock interrupt in.
*/
-#define V(s) __CONCAT(V, s)
-extern void V(clk)();
-extern void V(rtc)();
-
void
enablertclock()
{
- setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL);
+ register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, clkintr,
+ HWI_MASK | SWI_MASK, /* unit */ 0);
INTREN(IRQ0);
- setidt(ICU_OFFSET+8, &V(rtc), SDT_SYS386IGT, SEL_KPL);
+ register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, rtcintr,
+ SWI_CLOCK_MASK, /* unit */ 0);
INTREN(IRQ8);
outb(IO_RTC, RTC_STATUSB);
outb(IO_RTC+1, RTCSB_PINTR | RTCSB_24HR);
diff --git a/sys/amd64/isa/isa.c b/sys/amd64/isa/isa.c
index 80be9a5..5b5878e 100644
--- a/sys/amd64/isa/isa.c
+++ b/sys/amd64/isa/isa.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
- * $Id: isa.c,v 1.19 1994/08/10 04:39:52 wollman Exp $
+ * $Id: isa.c,v 1.20 1994/08/13 03:50:07 wollman Exp $
*/
/*
@@ -65,6 +65,7 @@
#include <i386/isa/icu.h>
#include <i386/isa/ic/i8237.h>
#include <i386/isa/ic/i8042.h>
+#include "vector.h"
/*
** Register definitions for DMA controller 1 (channels 0..3):
@@ -82,20 +83,70 @@
#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */
#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */
-void config_isadev __P((struct isa_device *, u_int *));
+/*
+ * Bits to specify the type and amount of conflict checking.
+ */
+#define CC_ATTACH (1 << 0)
+#define CC_DRQ (1 << 1)
+#define CC_IOADDR (1 << 2)
+#define CC_IRQ (1 << 3)
+#define CC_MEMADDR (1 << 4)
+
+/*
+ * XXX these defines should be in a central place.
+ */
+#define read_eflags() ({u_long ef; \
+ __asm("pushfl; popl %0" : "=a" (ef)); \
+ ef; })
+#define write_eflags(ef) __asm("pushl %0; popfl" : : "a" ((u_long)(ef)))
+
+u_long *intr_countp[ICU_LEN];
+inthand2_t *intr_handler[ICU_LEN];
+u_int intr_mask[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)
+};
+
+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)
+};
+
+static void config_isadev __P((struct isa_device *isdp, u_int *mp));
+static void conflict __P((struct isa_device *dvp, struct isa_device *tmpdvp,
+ int item, char const *whatnot, char const *reason,
+ char const *format));
+static int haveseen __P((struct isa_device *dvp, struct isa_device *tmpdvp,
+ u_int checkbits));
+static int haveseen_isadev __P((struct isa_device *dvp, u_int checkbits));
+static inthand2_t isa_strayintr;
+static void register_imask __P((struct isa_device *dvp, u_int mask));
/*
* print a conflict message
*/
-void
-conflict(dvp, tmpdvp, item, reason, format)
- struct isa_device *dvp, *tmpdvp;
+static void
+conflict(dvp, tmpdvp, item, whatnot, reason, format)
+ struct isa_device *dvp;
+ struct isa_device *tmpdvp;
int item;
- char *reason;
- char *format;
+ char const *whatnot;
+ char const *reason;
+ char const *format;
{
- printf("%s%d not probed due to %s conflict with %s%d at ",
- dvp->id_driver->name, dvp->id_unit, reason,
+ printf("%s%d not %sed due to %s conflict with %s%d at ",
+ dvp->id_driver->name, dvp->id_unit, whatnot, reason,
tmpdvp->id_driver->name, tmpdvp->id_unit);
printf(format, item);
printf("\n");
@@ -105,9 +156,11 @@ conflict(dvp, tmpdvp, item, reason, format)
* Check to see if things are alread in use, like IRQ's, I/O addresses
* and Memory addresses.
*/
-int
-haveseen(dvp, tmpdvp)
- struct isa_device *dvp, *tmpdvp;
+static int
+haveseen(dvp, tmpdvp, checkbits)
+ struct isa_device *dvp;
+ struct isa_device *tmpdvp;
+ u_int checkbits;
{
int status = 0;
@@ -115,17 +168,20 @@ haveseen(dvp, tmpdvp)
* Only check against devices that have already been found
*/
if (tmpdvp->id_alive) {
+ char const *whatnot;
+
+ whatnot = checkbits & CC_ATTACH ? "attach" : "probe";
/*
* Check for I/O address conflict. We can only check the
* starting address of the device against the range of the
* device that has already been probed since we do not
* know how many I/O addresses this device uses.
*/
- if (tmpdvp->id_alive != -1) {
+ if (checkbits & CC_IOADDR && tmpdvp->id_alive != -1) {
if ((dvp->id_iobase >= tmpdvp->id_iobase) &&
(dvp->id_iobase <=
(tmpdvp->id_iobase + tmpdvp->id_alive - 1))) {
- conflict(dvp, tmpdvp, dvp->id_iobase,
+ conflict(dvp, tmpdvp, dvp->id_iobase, whatnot,
"I/O address", "0x%x");
status = 1;
}
@@ -140,34 +196,32 @@ haveseen(dvp, tmpdvp)
* since at that time we would know the full range.
* XXX KERNBASE is a hack, we should have vaddr in the table!
*/
- if(tmpdvp->id_maddr) {
- if((KERNBASE + dvp->id_maddr >= tmpdvp->id_maddr) &&
- (KERNBASE + dvp->id_maddr <=
- (tmpdvp->id_maddr + tmpdvp->id_msize - 1))) {
- conflict(dvp, tmpdvp, dvp->id_maddr, "maddr",
- "0x%x");
+ if (checkbits & CC_MEMADDR && tmpdvp->id_maddr) {
+ if ((KERNBASE + dvp->id_maddr >= tmpdvp->id_maddr) &&
+ (KERNBASE + dvp->id_maddr <=
+ (tmpdvp->id_maddr + tmpdvp->id_msize - 1))) {
+ conflict(dvp, tmpdvp, (int)dvp->id_maddr,
+ whatnot, "maddr", "0x%x");
status = 1;
}
}
-#ifndef COM_MULTIPORT
/*
* Check for IRQ conflicts.
*/
- if(tmpdvp->id_irq) {
+ if (checkbits & CC_IRQ && tmpdvp->id_irq) {
if (tmpdvp->id_irq == dvp->id_irq) {
conflict(dvp, tmpdvp, ffs(dvp->id_irq) - 1,
- "irq", "%d");
+ whatnot, "irq", "%d");
status = 1;
}
}
-#endif
/*
* Check for DRQ conflicts.
*/
- if(tmpdvp->id_drq != -1) {
+ if (checkbits & CC_DRQ && tmpdvp->id_drq != -1) {
if (tmpdvp->id_drq == dvp->id_drq) {
- conflict(dvp, tmpdvp, dvp->id_drq,
- "drq", "%d");
+ conflict(dvp, tmpdvp, dvp->id_drq, whatnot,
+ "drq", "%d");
status = 1;
}
}
@@ -179,25 +233,22 @@ haveseen(dvp, tmpdvp)
* Search through all the isa_devtab_* tables looking for anything that
* conflicts with the current device.
*/
-int
-haveseen_isadev(dvp)
+static int
+haveseen_isadev(dvp, checkbits)
struct isa_device *dvp;
+ u_int checkbits;
{
struct isa_device *tmpdvp;
int status = 0;
- for (tmpdvp = isa_devtab_tty; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp);
- }
- for (tmpdvp = isa_devtab_bio; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp);
- }
- for (tmpdvp = isa_devtab_net; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp);
- }
- for (tmpdvp = isa_devtab_null; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp);
- }
+ for (tmpdvp = isa_devtab_tty; tmpdvp->id_driver; tmpdvp++)
+ status |= haveseen(dvp, tmpdvp, checkbits);
+ for (tmpdvp = isa_devtab_bio; tmpdvp->id_driver; tmpdvp++)
+ status |= haveseen(dvp, tmpdvp, checkbits);
+ for (tmpdvp = isa_devtab_net; tmpdvp->id_driver; tmpdvp++)
+ status |= haveseen(dvp, tmpdvp, checkbits);
+ for (tmpdvp = isa_devtab_null; tmpdvp->id_driver; tmpdvp++)
+ status |= haveseen(dvp, tmpdvp, checkbits);
return(status);
}
@@ -208,26 +259,18 @@ void
isa_configure() {
struct isa_device *dvp;
- enable_intr();
splhigh();
+ enable_intr();
INTREN(IRQ_SLAVE);
printf("Probing for devices on the ISA bus:\n");
- for (dvp = isa_devtab_tty; dvp->id_driver; dvp++) {
- if (!haveseen_isadev(dvp))
- config_isadev(dvp,&tty_imask);
- }
- for (dvp = isa_devtab_bio; dvp->id_driver; dvp++) {
- if (!haveseen_isadev(dvp))
- config_isadev(dvp,&bio_imask);
- }
- for (dvp = isa_devtab_net; dvp->id_driver; dvp++) {
- if (!haveseen_isadev(dvp))
- config_isadev(dvp,&net_imask);
- }
- for (dvp = isa_devtab_null; dvp->id_driver; dvp++) {
- if (!haveseen_isadev(dvp))
- config_isadev(dvp,(u_int *) NULL);
- }
+ for (dvp = isa_devtab_tty; dvp->id_driver; dvp++)
+ config_isadev(dvp, &tty_imask);
+ for (dvp = isa_devtab_bio; dvp->id_driver; dvp++)
+ config_isadev(dvp, &bio_imask);
+ for (dvp = isa_devtab_net; dvp->id_driver; dvp++)
+ config_isadev(dvp, &net_imask);
+ for (dvp = isa_devtab_null; dvp->id_driver; dvp++)
+ config_isadev(dvp, (u_int *)NULL);
bio_imask |= SWI_CLOCK_MASK;
net_imask |= SWI_NET_MASK;
tty_imask |= SWI_TTY_MASK;
@@ -253,27 +296,54 @@ isa_configure() {
printf("bio_imask %x tty_imask %x net_imask %x\n",
bio_imask, tty_imask, net_imask);
#endif
+ /*
+ * Finish initializing intr_mask[]. Note that the partly
+ * constructed masks aren't actually used since we're at splhigh.
+ * For fully dynamic initialization, register_intr() and
+ * unregister_intr() will have to adjust the masks for _all_
+ * interrupts and for tty_imask, etc.
+ */
+ for (dvp = isa_devtab_tty; dvp->id_driver; dvp++)
+ register_imask(dvp, tty_imask);
+ for (dvp = isa_devtab_bio; dvp->id_driver; dvp++)
+ register_imask(dvp, bio_imask);
+ for (dvp = isa_devtab_net; dvp->id_driver; dvp++)
+ register_imask(dvp, net_imask);
+ for (dvp = isa_devtab_null; dvp->id_driver; dvp++)
+ register_imask(dvp, SWI_CLOCK_MASK);
splnone();
}
/*
* Configure an ISA device.
*/
-void
+static void
config_isadev(isdp, mp)
struct isa_device *isdp;
u_int *mp;
{
+ u_int checkbits;
+ int id_alive;
struct isa_driver *dp = isdp->id_driver;
+ checkbits = 0;
+#ifndef ALLOW_CONFLICT_DRQ
+ checkbits |= CC_DRQ;
+#endif
+#ifndef ALLOW_CONFLICT_IOADDR
+ checkbits |= CC_IOADDR;
+#endif
+#ifndef ALLOW_CONFLICT_MEMADDR
+ checkbits |= CC_MEMADDR;
+#endif
+ if (haveseen_isadev(isdp, checkbits))
+ return;
if (isdp->id_maddr) {
- extern u_int atdevbase;
-
isdp->id_maddr -= 0xa0000; /* XXX should be a define */
isdp->id_maddr += atdevbase;
}
- isdp->id_alive = (*dp->probe)(isdp);
- if (isdp->id_alive) {
+ id_alive = (*dp->probe)(isdp);
+ if (id_alive) {
/*
* Only print the I/O address range if id_alive != -1
* Right now this is a temporary fix just for the new
@@ -282,21 +352,20 @@ config_isadev(isdp, mp)
* Rod Grimes 04/26/94
*/
printf("%s%d", dp->name, isdp->id_unit);
- if (isdp->id_alive != -1) {
+ if (id_alive != -1) {
printf(" at 0x%x", isdp->id_iobase);
- if ((isdp->id_iobase + isdp->id_alive - 1) !=
+ if ((isdp->id_iobase + id_alive - 1) !=
isdp->id_iobase) {
printf("-0x%x",
- isdp->id_iobase +
- isdp->id_alive - 1);
+ isdp->id_iobase + id_alive - 1);
}
}
- if(isdp->id_irq)
+ if (isdp->id_irq)
printf(" irq %d", ffs(isdp->id_irq) - 1);
if (isdp->id_drq != -1)
printf(" drq %d", isdp->id_drq);
if (isdp->id_maddr)
- printf(" maddr 0x%x", kvtop(isdp->id_maddr));
+ printf(" maddr 0x%lx", kvtop(isdp->id_maddr));
if (isdp->id_msize)
printf(" msize %d", isdp->id_msize);
if (isdp->id_flags)
@@ -312,18 +381,25 @@ config_isadev(isdp, mp)
}
}
}
-
+ /*
+ * Check for conflicts again. The driver may have changed
+ * *dvp. We should weaken the early check since the
+ * driver may have been able to change *dvp to avoid
+ * conflicts if given a chance. We already skip the early
+ * check for IRQs and force a check for IRQs in the next
+ * group of checks.
+ */
+ checkbits |= CC_IRQ;
+ if (haveseen_isadev(isdp, checkbits))
+ return;
+ isdp->id_alive = id_alive;
(*dp->attach)(isdp);
-
- if(isdp->id_irq) {
- int intrno;
-
- intrno = ffs(isdp->id_irq)-1;
- setidt(ICU_OFFSET+intrno, isdp->id_intr,
- SDT_SYS386IGT, SEL_KPL);
- if(mp) {
- INTRMASK(*mp,isdp->id_irq);
- }
+ if (isdp->id_irq) {
+ if (mp)
+ INTRMASK(*mp, isdp->id_irq);
+ register_intr(ffs(isdp->id_irq) - 1, isdp->id_id,
+ isdp->id_ri_flags, isdp->id_intr,
+ mp ? *mp : 0, isdp->id_unit);
INTREN(isdp->id_irq);
}
} else {
@@ -335,22 +411,6 @@ config_isadev(isdp, mp)
}
}
-#define IDTVEC(name) __CONCAT(X,name)
-/* default interrupt vector table entries */
-typedef void inthand_t();
-typedef void (*inthand_func_t)();
-extern inthand_t
- 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);
-
-static inthand_func_t defvec[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) };
-
/*
* Fill in default interrupt table (in case of spuruious interrupt
* during configuration of kernel, setup interrupt control unit
@@ -362,7 +422,7 @@ isa_defaultirq()
/* icu vectors */
for (i = 0; i < ICU_LEN; i++)
- setidt(ICU_OFFSET + i, defvec[i], SDT_SYS386IGT, SEL_KPL);
+ unregister_intr(i, (inthand2_t *)NULL);
/* initialize 8259's */
outb(IO_ICU1, 0x11); /* reset; program device, four bytes */
@@ -418,6 +478,9 @@ void isa_dmacascade(unsigned chan)
}
}
+static int
+isa_dmarangecheck(caddr_t va, unsigned length, unsigned chan);
+
/*
* isa_dmastart(): program 8237 DMA controller channel, avoid page alignment
* problems by using a bounce buffer.
@@ -520,7 +583,7 @@ void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
* Return true if special handling needed.
*/
-int
+static int
isa_dmarangecheck(caddr_t va, unsigned length, unsigned chan) {
vm_offset_t phys, priorpage = 0, endva;
u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1);
@@ -622,7 +685,7 @@ isa_nmi(cd)
/*
* Caught a stray interrupt, notify
*/
-void
+static void
isa_strayintr(d)
int d;
{
@@ -637,13 +700,18 @@ isa_strayintr(d)
* the first 5 get logged, then it quits logging them, and puts
* out a special message. rgrimes 3/25/1993
*/
- extern u_long intrcnt_stray;
-
- intrcnt_stray++;
- if (intrcnt_stray <= 5)
- log(LOG_ERR,"ISA strayintr %x\n", d);
- if (intrcnt_stray == 5)
- log(LOG_CRIT,"Too many ISA strayintr not logging any more\n");
+ /*
+ * 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);
}
/*
@@ -683,8 +751,84 @@ isa_irq_pending(dvp)
{
unsigned id_irq;
- id_irq = (unsigned short) dvp->id_irq; /* XXX silly type in struct */
+ id_irq = dvp->id_irq;
if (id_irq & 0xff)
return (inb(IO_ICU1) & id_irq);
return (inb(IO_ICU2) & (id_irq >> 8));
}
+
+int
+register_intr(intr, device_id, flags, handler, mask, unit)
+ int intr;
+ int device_id;
+ u_int flags;
+ inthand2_t *handler;
+ u_int mask;
+ int unit;
+{
+ char *cp;
+ u_long ef;
+ int id;
+
+ if ((u_int)intr >= ICU_LEN || intr == 2
+ || (u_int)device_id >= NR_DEVICES)
+ return (EINVAL);
+ if (intr_handler[intr] != isa_strayintr)
+ return (EBUSY);
+ ef = read_eflags();
+ disable_intr();
+ intr_countp[intr] = &intrcnt[device_id];
+ intr_handler[intr] = handler;
+ intr_mask[intr] = mask | (1 << intr);
+ intr_unit[intr] = unit;
+ setidt(ICU_OFFSET + intr,
+ flags & RI_FAST ? fastintr[intr] : slowintr[intr],
+ SDT_SYS386IGT, SEL_KPL);
+ write_eflags(ef);
+ for (cp = intrnames, id = 0; id <= device_id; id++)
+ while (*cp++ != '\0')
+ ;
+ if (cp > eintrnames)
+ return (0);
+ if (intr < 10) {
+ cp[-3] = intr + '0';
+ cp[-2] = ' ';
+ } else {
+ cp[-3] = '1';
+ cp[-2] = intr - 10 + '0';
+ }
+ 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);
+ }
+}
+
+int
+unregister_intr(intr, handler)
+ int intr;
+ inthand2_t *handler;
+{
+ u_long ef;
+
+ if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr])
+ return (EINVAL);
+ ef = read_eflags();
+ disable_intr();
+ intr_countp[intr] = &intrcnt[NR_DEVICES + intr];
+ intr_handler[intr] = isa_strayintr;
+ intr_mask[intr] = HWI_MASK | SWI_MASK;
+ intr_unit[intr] = intr;
+ setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL);
+ write_eflags(ef);
+ return (0);
+}
diff --git a/sys/amd64/isa/vector.S b/sys/amd64/isa/vector.S
index 7135ae7..252bd95 100644
--- a/sys/amd64/isa/vector.S
+++ b/sys/amd64/isa/vector.S
@@ -1,6 +1,6 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
- * $Id: vector.s,v 1.6 1994/01/10 23:15:09 ache Exp $
+ * $Id: vector.s,v 1.7 1994/04/02 07:00:50 davidg Exp $
*/
#include "i386/isa/icu.h"
@@ -97,7 +97,10 @@
* loading segregs.
*/
-#define FAST_INTR(unit, irq_num, id_num, handler, enable_icus) \
+#define FAST_INTR(irq_num, enable_icus) \
+ .text ; \
+ SUPERALIGN_TEXT ; \
+IDTVEC(fastintr/**/irq_num) ; \
pushl %eax ; /* save only call-used registers */ \
pushl %ecx ; \
pushl %edx ; \
@@ -107,12 +110,13 @@
movl %ax,%ds ; \
MAYBE_MOVW_AX_ES ; \
FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \
- pushl $unit ; \
- call handler ; /* do the work ASAP */ \
+ pushl _intr_unit + (irq_num) * 4 ; \
+ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \
addl $4,%esp ; \
incl _cnt+V_INTR ; /* book-keeping can wait */ \
- incl _intrcnt_actv + (id_num) * 4 ; \
+ movl _intr_countp + (irq_num) * 4,%eax ; \
+ incl (%eax) ; \
movl _cpl,%eax ; /* are we unmasking pending HWIs or SWIs? */ \
notl %eax ; \
andl _ipending,%eax ; \
@@ -147,7 +151,10 @@
MEXITCOUNT ; \
jmp _doreti
-#define INTR(unit, irq_num, id_num, mask, handler, icu, enable_icus, reg, stray) \
+#define INTR(irq_num, icu, enable_icus, reg) \
+ .text ; \
+ SUPERALIGN_TEXT ; \
+IDTVEC(intr/**/irq_num) ; \
pushl $0 ; /* dumby error code */ \
pushl $0 ; /* dumby trap type */ \
pushal ; \
@@ -167,15 +174,17 @@
testb $IRQ_BIT(irq_num),%reg ; \
jne 2f ; \
1: ; \
+Xresume/**/irq_num: ; \
FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \
- incl _intrcnt_actv + (id_num) * 4 ; \
+ movl _intr_countp + (irq_num) * 4,%eax ; \
+ incl (%eax) ; \
movl _cpl,%eax ; \
pushl %eax ; \
- pushl $unit ; \
- orl mask,%eax ; \
+ pushl _intr_unit + (irq_num) * 4 ; \
+ orl _intr_mask + (irq_num) * 4,%eax ; \
movl %eax,_cpl ; \
sti ; \
- call handler ; \
+ call *_intr_handler + (irq_num) * 4 ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
andb $~IRQ_BIT(irq_num),%al ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
@@ -189,9 +198,6 @@
ALIGN_TEXT ; \
2: ; \
/* XXX skip mcounting here to avoid double count */ \
- movl $1b,%eax ; /* register resume address */ \
- /* XXX - someday do it at attach time */ \
- movl %eax,ihandlers + (irq_num) * 4 ; \
orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \
popl %es ; \
popl %ds ; \
@@ -199,118 +205,48 @@
addl $4+4,%esp ; \
iret
-/*
- * vector.h has defined a macro 'BUILD_VECTORS' containing a big list of info
- * about vectors, including a submacro 'BUILD_VECTOR' that operates on the
- * info about each vector. We redefine 'BUILD_VECTOR' to expand the info
- * in different ways. Here we expand it to a list of interrupt handlers.
- * This order is of course unimportant. Elsewhere we expand it to inline
- * linear search code for which the order is a little more important and
- * concatenating the code with no holes is very important.
- *
- * XXX - now there is BUILD_FAST_VECTOR as well as BUILD_VECTOR.
- *
- * The info consists of the following items for each vector:
- *
- * name (identifier): name of the vector; used to build labels
- * unit (expression): unit number to call the device driver with
- * irq_num (number): number of the IRQ to handled (0-15)
- * id_num (number): uniq numeric id for handler (assigned by config)
- * mask (blank-ident): priority mask used
- * handler (blank-ident): interrupt handler to call
- * icu_num (number): (1 + irq_num / 8) converted for label building
- * icu_enables (number): 1 for icu_num == 1, 1_AND_2 for icu_num == 2
- * reg (blank-ident): al for icu_num == 1, ah for icu_num == 2
- *
- * 'irq_num' is converted in several ways at config time to get around
- * limitations in cpp. The macros have blanks after commas iff they would
- * not mess up identifiers and numbers.
- */
-
-#undef BUILD_FAST_VECTOR
-#define BUILD_FAST_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .globl handler ; \
- .text ; \
- .globl _V/**/name ; \
- SUPERALIGN_TEXT ; \
-_V/**/name: ; \
- FAST_INTR(unit, irq_num,id_num, handler, ENABLE_ICU/**/icu_enables)
-
-#undef BUILD_VECTOR
-#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .globl handler ; \
- .text ; \
- .globl _V/**/name ; \
- SUPERALIGN_TEXT ; \
-_V/**/name: ; \
- INTR(unit,irq_num, id_num, mask, handler, IO_ICU/**/icu_num, \
- ENABLE_ICU/**/icu_enables, reg,)
-
MCOUNT_LABEL(bintr)
- BUILD_VECTORS
-
- /* hardware interrupt catcher (IDT 32 - 47) */
- .globl _isa_strayintr
-
-#define STRAYINTR(irq_num, icu_num, icu_enables, reg) \
-IDTVEC(intr/**/irq_num) ; \
- INTR(irq_num,irq_num,irq_num, _high_imask, _isa_strayintr, \
- IO_ICU/**/icu_num, ENABLE_ICU/**/icu_enables, reg,stray)
-
-/*
- * XXX - the mask (1 << 2) == IRQ_SLAVE will be generated for IRQ 2, instead
- * of the mask IRQ2 (defined as IRQ9 == (1 << 9)). But IRQ 2 "can't happen".
- * In fact, all stray interrupts "can't happen" except for bugs. The
- * "stray" IRQ 7 is documented behaviour of the 8259. It happens when there
- * is a glitch on any of its interrupt inputs. Does it really interrupt when
- * IRQ 7 is masked?
- *
- * XXX - unpend doesn't work for these, it sends them to the real handler.
- *
- * XXX - the race bug during initialization may be because I changed the
- * order of switching from the stray to the real interrupt handler to before
- * enabling interrupts. The old order looked unsafe but maybe it is OK with
- * the stray interrupt handler installed. But these handlers only reduce
- * the window of vulnerability - it is still open at the end of
- * isa_configure().
- *
- * XXX - many comments are stale.
- */
-
- STRAYINTR(0,1,1, al)
- STRAYINTR(1,1,1, al)
- STRAYINTR(2,1,1, al)
- STRAYINTR(3,1,1, al)
- STRAYINTR(4,1,1, al)
- STRAYINTR(5,1,1, al)
- STRAYINTR(6,1,1, al)
- STRAYINTR(7,1,1, al)
- STRAYINTR(8,2,1_AND_2, ah)
- STRAYINTR(9,2,1_AND_2, ah)
- STRAYINTR(10,2,1_AND_2, ah)
- STRAYINTR(11,2,1_AND_2, ah)
- STRAYINTR(12,2,1_AND_2, ah)
- STRAYINTR(13,2,1_AND_2, ah)
- STRAYINTR(14,2,1_AND_2, ah)
- STRAYINTR(15,2,1_AND_2, ah)
-#if 0
- INTRSTRAY(255, _highmask, 255) ; call _isa_strayintr ; INTREXIT2
-#endif
+ FAST_INTR(0, ENABLE_ICU1)
+ FAST_INTR(1, ENABLE_ICU1)
+ FAST_INTR(2, ENABLE_ICU1)
+ FAST_INTR(3, ENABLE_ICU1)
+ FAST_INTR(4, ENABLE_ICU1)
+ FAST_INTR(5, ENABLE_ICU1)
+ FAST_INTR(6, ENABLE_ICU1)
+ FAST_INTR(7, ENABLE_ICU1)
+ FAST_INTR(8, ENABLE_ICU1_AND_2)
+ FAST_INTR(9, ENABLE_ICU1_AND_2)
+ FAST_INTR(10, ENABLE_ICU1_AND_2)
+ FAST_INTR(11, ENABLE_ICU1_AND_2)
+ FAST_INTR(12, ENABLE_ICU1_AND_2)
+ FAST_INTR(13, ENABLE_ICU1_AND_2)
+ FAST_INTR(14, ENABLE_ICU1_AND_2)
+ FAST_INTR(15, ENABLE_ICU1_AND_2)
+ INTR(0, IO_ICU1, ENABLE_ICU1, al)
+ INTR(1, IO_ICU1, ENABLE_ICU1, al)
+ INTR(2, IO_ICU1, ENABLE_ICU1, al)
+ INTR(3, IO_ICU1, ENABLE_ICU1, al)
+ INTR(4, IO_ICU1, ENABLE_ICU1, al)
+ INTR(5, IO_ICU1, ENABLE_ICU1, al)
+ INTR(6, IO_ICU1, ENABLE_ICU1, al)
+ INTR(7, IO_ICU1, ENABLE_ICU1, al)
+ INTR(8, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(9, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(10, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(11, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(12, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(13, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(14, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(15, IO_ICU2, ENABLE_ICU1_AND_2, ah)
MCOUNT_LABEL(eintr)
-/*
- * These are the interrupt counters, I moved them here from icu.s so that
- * they are with the name table. rgrimes
- *
- * There are now lots of counters, this has been redone to work with
- * Bruce Evans intr-0.1 code, which I modified some more to make it all
- * work with vmstat.
- */
.data
ihandlers: /* addresses of interrupt handlers */
- .space NHWI*4 /* actually resumption addresses for HWI's */
+ /* actually resumption addresses for HWI's */
+ .long Xresume0, Xresume1, Xresume2, Xresume3
+ .long Xresume4, Xresume5, Xresume6, Xresume7
+ .long Xresume8, Xresume9, Xresume10, Xresume11
+ .long Xresume12, Xresume13, Xresume14, Xresume15
.long swi_tty, swi_net, 0, 0, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, swi_clock, swi_ast
imasks: /* masks for interrupt handlers */
@@ -318,43 +254,37 @@ imasks: /* masks for interrupt handlers */
.long SWI_TTY_MASK, SWI_NET_MASK, 0, 0, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK
- .globl _intrcnt
-_intrcnt: /* used by vmstat to calc size of table */
- .globl _intrcnt_bad7
-_intrcnt_bad7: .space 4 /* glitches on irq 7 */
- .globl _intrcnt_bad15
-_intrcnt_bad15: .space 4 /* glitches on irq 15 */
- .globl _intrcnt_stray
-_intrcnt_stray: .space 4 /* total count of stray interrupts */
- .globl _intrcnt_actv
-_intrcnt_actv: .space NR_REAL_INT_HANDLERS * 4 /* active interrupts */
- .globl _eintrcnt
-_eintrcnt: /* used by vmstat to calc size of table */
-
-/*
- * Build the interrupt name table for vmstat
- */
-
-#undef BUILD_FAST_VECTOR
-#define BUILD_FAST_VECTOR BUILD_VECTOR
-
-#undef BUILD_VECTOR
-#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .ascii "name irq" ; \
- .asciz "irq_num"
/*
- * XXX - use the __STRING and __CONCAT macros from <sys/cdefs.h> to stringize
- * and concatenate names above and elsewhere. Note that __CONCAT doesn't
- * work when nested.
+ * Interrupt counters and names. The format of these and the label names
+ * must agree with what vmstat expects. The tables are indexed by device
+ * ids so that we don't have to move the names around as devices are
+ * attached.
*/
+#include "vector.h"
+ .globl _intrcnt, _eintrcnt
+_intrcnt:
+ .space (NR_DEVICES + ICU_LEN) * 4
+_eintrcnt:
- .text
.globl _intrnames, _eintrnames
_intrnames:
- BUILD_VECTOR(bad,,7,,,,,,)
- BUILD_VECTOR(bad,,15,,,,,,)
- BUILD_VECTOR(stray,,,,,,,,)
- BUILD_VECTORS
-
+ .ascii DEVICE_NAMES
+ .asciz "stray irq0"
+ .asciz "stray irq1"
+ .asciz "stray irq2"
+ .asciz "stray irq3"
+ .asciz "stray irq4"
+ .asciz "stray irq5"
+ .asciz "stray irq6"
+ .asciz "stray irq7"
+ .asciz "stray irq8"
+ .asciz "stray irq9"
+ .asciz "stray irq10"
+ .asciz "stray irq11"
+ .asciz "stray irq12"
+ .asciz "stray irq13"
+ .asciz "stray irq14"
+ .asciz "stray irq15"
_eintrnames:
+
+ .text
diff --git a/sys/amd64/isa/vector.s b/sys/amd64/isa/vector.s
index 7135ae7..252bd95 100644
--- a/sys/amd64/isa/vector.s
+++ b/sys/amd64/isa/vector.s
@@ -1,6 +1,6 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
- * $Id: vector.s,v 1.6 1994/01/10 23:15:09 ache Exp $
+ * $Id: vector.s,v 1.7 1994/04/02 07:00:50 davidg Exp $
*/
#include "i386/isa/icu.h"
@@ -97,7 +97,10 @@
* loading segregs.
*/
-#define FAST_INTR(unit, irq_num, id_num, handler, enable_icus) \
+#define FAST_INTR(irq_num, enable_icus) \
+ .text ; \
+ SUPERALIGN_TEXT ; \
+IDTVEC(fastintr/**/irq_num) ; \
pushl %eax ; /* save only call-used registers */ \
pushl %ecx ; \
pushl %edx ; \
@@ -107,12 +110,13 @@
movl %ax,%ds ; \
MAYBE_MOVW_AX_ES ; \
FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \
- pushl $unit ; \
- call handler ; /* do the work ASAP */ \
+ pushl _intr_unit + (irq_num) * 4 ; \
+ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \
addl $4,%esp ; \
incl _cnt+V_INTR ; /* book-keeping can wait */ \
- incl _intrcnt_actv + (id_num) * 4 ; \
+ movl _intr_countp + (irq_num) * 4,%eax ; \
+ incl (%eax) ; \
movl _cpl,%eax ; /* are we unmasking pending HWIs or SWIs? */ \
notl %eax ; \
andl _ipending,%eax ; \
@@ -147,7 +151,10 @@
MEXITCOUNT ; \
jmp _doreti
-#define INTR(unit, irq_num, id_num, mask, handler, icu, enable_icus, reg, stray) \
+#define INTR(irq_num, icu, enable_icus, reg) \
+ .text ; \
+ SUPERALIGN_TEXT ; \
+IDTVEC(intr/**/irq_num) ; \
pushl $0 ; /* dumby error code */ \
pushl $0 ; /* dumby trap type */ \
pushal ; \
@@ -167,15 +174,17 @@
testb $IRQ_BIT(irq_num),%reg ; \
jne 2f ; \
1: ; \
+Xresume/**/irq_num: ; \
FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \
- incl _intrcnt_actv + (id_num) * 4 ; \
+ movl _intr_countp + (irq_num) * 4,%eax ; \
+ incl (%eax) ; \
movl _cpl,%eax ; \
pushl %eax ; \
- pushl $unit ; \
- orl mask,%eax ; \
+ pushl _intr_unit + (irq_num) * 4 ; \
+ orl _intr_mask + (irq_num) * 4,%eax ; \
movl %eax,_cpl ; \
sti ; \
- call handler ; \
+ call *_intr_handler + (irq_num) * 4 ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
andb $~IRQ_BIT(irq_num),%al ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
@@ -189,9 +198,6 @@
ALIGN_TEXT ; \
2: ; \
/* XXX skip mcounting here to avoid double count */ \
- movl $1b,%eax ; /* register resume address */ \
- /* XXX - someday do it at attach time */ \
- movl %eax,ihandlers + (irq_num) * 4 ; \
orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \
popl %es ; \
popl %ds ; \
@@ -199,118 +205,48 @@
addl $4+4,%esp ; \
iret
-/*
- * vector.h has defined a macro 'BUILD_VECTORS' containing a big list of info
- * about vectors, including a submacro 'BUILD_VECTOR' that operates on the
- * info about each vector. We redefine 'BUILD_VECTOR' to expand the info
- * in different ways. Here we expand it to a list of interrupt handlers.
- * This order is of course unimportant. Elsewhere we expand it to inline
- * linear search code for which the order is a little more important and
- * concatenating the code with no holes is very important.
- *
- * XXX - now there is BUILD_FAST_VECTOR as well as BUILD_VECTOR.
- *
- * The info consists of the following items for each vector:
- *
- * name (identifier): name of the vector; used to build labels
- * unit (expression): unit number to call the device driver with
- * irq_num (number): number of the IRQ to handled (0-15)
- * id_num (number): uniq numeric id for handler (assigned by config)
- * mask (blank-ident): priority mask used
- * handler (blank-ident): interrupt handler to call
- * icu_num (number): (1 + irq_num / 8) converted for label building
- * icu_enables (number): 1 for icu_num == 1, 1_AND_2 for icu_num == 2
- * reg (blank-ident): al for icu_num == 1, ah for icu_num == 2
- *
- * 'irq_num' is converted in several ways at config time to get around
- * limitations in cpp. The macros have blanks after commas iff they would
- * not mess up identifiers and numbers.
- */
-
-#undef BUILD_FAST_VECTOR
-#define BUILD_FAST_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .globl handler ; \
- .text ; \
- .globl _V/**/name ; \
- SUPERALIGN_TEXT ; \
-_V/**/name: ; \
- FAST_INTR(unit, irq_num,id_num, handler, ENABLE_ICU/**/icu_enables)
-
-#undef BUILD_VECTOR
-#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .globl handler ; \
- .text ; \
- .globl _V/**/name ; \
- SUPERALIGN_TEXT ; \
-_V/**/name: ; \
- INTR(unit,irq_num, id_num, mask, handler, IO_ICU/**/icu_num, \
- ENABLE_ICU/**/icu_enables, reg,)
-
MCOUNT_LABEL(bintr)
- BUILD_VECTORS
-
- /* hardware interrupt catcher (IDT 32 - 47) */
- .globl _isa_strayintr
-
-#define STRAYINTR(irq_num, icu_num, icu_enables, reg) \
-IDTVEC(intr/**/irq_num) ; \
- INTR(irq_num,irq_num,irq_num, _high_imask, _isa_strayintr, \
- IO_ICU/**/icu_num, ENABLE_ICU/**/icu_enables, reg,stray)
-
-/*
- * XXX - the mask (1 << 2) == IRQ_SLAVE will be generated for IRQ 2, instead
- * of the mask IRQ2 (defined as IRQ9 == (1 << 9)). But IRQ 2 "can't happen".
- * In fact, all stray interrupts "can't happen" except for bugs. The
- * "stray" IRQ 7 is documented behaviour of the 8259. It happens when there
- * is a glitch on any of its interrupt inputs. Does it really interrupt when
- * IRQ 7 is masked?
- *
- * XXX - unpend doesn't work for these, it sends them to the real handler.
- *
- * XXX - the race bug during initialization may be because I changed the
- * order of switching from the stray to the real interrupt handler to before
- * enabling interrupts. The old order looked unsafe but maybe it is OK with
- * the stray interrupt handler installed. But these handlers only reduce
- * the window of vulnerability - it is still open at the end of
- * isa_configure().
- *
- * XXX - many comments are stale.
- */
-
- STRAYINTR(0,1,1, al)
- STRAYINTR(1,1,1, al)
- STRAYINTR(2,1,1, al)
- STRAYINTR(3,1,1, al)
- STRAYINTR(4,1,1, al)
- STRAYINTR(5,1,1, al)
- STRAYINTR(6,1,1, al)
- STRAYINTR(7,1,1, al)
- STRAYINTR(8,2,1_AND_2, ah)
- STRAYINTR(9,2,1_AND_2, ah)
- STRAYINTR(10,2,1_AND_2, ah)
- STRAYINTR(11,2,1_AND_2, ah)
- STRAYINTR(12,2,1_AND_2, ah)
- STRAYINTR(13,2,1_AND_2, ah)
- STRAYINTR(14,2,1_AND_2, ah)
- STRAYINTR(15,2,1_AND_2, ah)
-#if 0
- INTRSTRAY(255, _highmask, 255) ; call _isa_strayintr ; INTREXIT2
-#endif
+ FAST_INTR(0, ENABLE_ICU1)
+ FAST_INTR(1, ENABLE_ICU1)
+ FAST_INTR(2, ENABLE_ICU1)
+ FAST_INTR(3, ENABLE_ICU1)
+ FAST_INTR(4, ENABLE_ICU1)
+ FAST_INTR(5, ENABLE_ICU1)
+ FAST_INTR(6, ENABLE_ICU1)
+ FAST_INTR(7, ENABLE_ICU1)
+ FAST_INTR(8, ENABLE_ICU1_AND_2)
+ FAST_INTR(9, ENABLE_ICU1_AND_2)
+ FAST_INTR(10, ENABLE_ICU1_AND_2)
+ FAST_INTR(11, ENABLE_ICU1_AND_2)
+ FAST_INTR(12, ENABLE_ICU1_AND_2)
+ FAST_INTR(13, ENABLE_ICU1_AND_2)
+ FAST_INTR(14, ENABLE_ICU1_AND_2)
+ FAST_INTR(15, ENABLE_ICU1_AND_2)
+ INTR(0, IO_ICU1, ENABLE_ICU1, al)
+ INTR(1, IO_ICU1, ENABLE_ICU1, al)
+ INTR(2, IO_ICU1, ENABLE_ICU1, al)
+ INTR(3, IO_ICU1, ENABLE_ICU1, al)
+ INTR(4, IO_ICU1, ENABLE_ICU1, al)
+ INTR(5, IO_ICU1, ENABLE_ICU1, al)
+ INTR(6, IO_ICU1, ENABLE_ICU1, al)
+ INTR(7, IO_ICU1, ENABLE_ICU1, al)
+ INTR(8, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(9, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(10, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(11, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(12, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(13, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(14, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(15, IO_ICU2, ENABLE_ICU1_AND_2, ah)
MCOUNT_LABEL(eintr)
-/*
- * These are the interrupt counters, I moved them here from icu.s so that
- * they are with the name table. rgrimes
- *
- * There are now lots of counters, this has been redone to work with
- * Bruce Evans intr-0.1 code, which I modified some more to make it all
- * work with vmstat.
- */
.data
ihandlers: /* addresses of interrupt handlers */
- .space NHWI*4 /* actually resumption addresses for HWI's */
+ /* actually resumption addresses for HWI's */
+ .long Xresume0, Xresume1, Xresume2, Xresume3
+ .long Xresume4, Xresume5, Xresume6, Xresume7
+ .long Xresume8, Xresume9, Xresume10, Xresume11
+ .long Xresume12, Xresume13, Xresume14, Xresume15
.long swi_tty, swi_net, 0, 0, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, swi_clock, swi_ast
imasks: /* masks for interrupt handlers */
@@ -318,43 +254,37 @@ imasks: /* masks for interrupt handlers */
.long SWI_TTY_MASK, SWI_NET_MASK, 0, 0, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK
- .globl _intrcnt
-_intrcnt: /* used by vmstat to calc size of table */
- .globl _intrcnt_bad7
-_intrcnt_bad7: .space 4 /* glitches on irq 7 */
- .globl _intrcnt_bad15
-_intrcnt_bad15: .space 4 /* glitches on irq 15 */
- .globl _intrcnt_stray
-_intrcnt_stray: .space 4 /* total count of stray interrupts */
- .globl _intrcnt_actv
-_intrcnt_actv: .space NR_REAL_INT_HANDLERS * 4 /* active interrupts */
- .globl _eintrcnt
-_eintrcnt: /* used by vmstat to calc size of table */
-
-/*
- * Build the interrupt name table for vmstat
- */
-
-#undef BUILD_FAST_VECTOR
-#define BUILD_FAST_VECTOR BUILD_VECTOR
-
-#undef BUILD_VECTOR
-#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .ascii "name irq" ; \
- .asciz "irq_num"
/*
- * XXX - use the __STRING and __CONCAT macros from <sys/cdefs.h> to stringize
- * and concatenate names above and elsewhere. Note that __CONCAT doesn't
- * work when nested.
+ * Interrupt counters and names. The format of these and the label names
+ * must agree with what vmstat expects. The tables are indexed by device
+ * ids so that we don't have to move the names around as devices are
+ * attached.
*/
+#include "vector.h"
+ .globl _intrcnt, _eintrcnt
+_intrcnt:
+ .space (NR_DEVICES + ICU_LEN) * 4
+_eintrcnt:
- .text
.globl _intrnames, _eintrnames
_intrnames:
- BUILD_VECTOR(bad,,7,,,,,,)
- BUILD_VECTOR(bad,,15,,,,,,)
- BUILD_VECTOR(stray,,,,,,,,)
- BUILD_VECTORS
-
+ .ascii DEVICE_NAMES
+ .asciz "stray irq0"
+ .asciz "stray irq1"
+ .asciz "stray irq2"
+ .asciz "stray irq3"
+ .asciz "stray irq4"
+ .asciz "stray irq5"
+ .asciz "stray irq6"
+ .asciz "stray irq7"
+ .asciz "stray irq8"
+ .asciz "stray irq9"
+ .asciz "stray irq10"
+ .asciz "stray irq11"
+ .asciz "stray irq12"
+ .asciz "stray irq13"
+ .asciz "stray irq14"
+ .asciz "stray irq15"
_eintrnames:
+
+ .text
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c
index de95e90..d505c4d 100644
--- a/sys/dev/sio/sio.c
+++ b/sys/dev/sio/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.47 1994/05/26 13:31:40 rgrimes Exp $
+ * $Id: sio.c,v 1.48 1994/08/13 03:50:13 wollman Exp $
*/
#include "sio.h"
@@ -427,6 +427,7 @@ sioattach(isdp)
int s;
int unit;
+ isdp->id_ri_flags |= RI_FAST;
iobase = isdp->id_iobase;
unit = isdp->id_unit;
s = spltty();
diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c
index 35f2e42..e3f3f21 100644
--- a/sys/i386/i386/tsc.c
+++ b/sys/i386/i386/tsc.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.13 1994/08/13 03:49:56 wollman Exp $
+ * $Id: clock.c,v 1.14 1994/08/15 03:15:18 wollman Exp $
*/
/*
@@ -497,16 +497,14 @@ test_inittodr(time_t base)
/*
* Wire clock interrupt in.
*/
-#define V(s) __CONCAT(V, s)
-extern void V(clk)();
-extern void V(rtc)();
-
void
enablertclock()
{
- setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL);
+ register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, clkintr,
+ HWI_MASK | SWI_MASK, /* unit */ 0);
INTREN(IRQ0);
- setidt(ICU_OFFSET+8, &V(rtc), SDT_SYS386IGT, SEL_KPL);
+ register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, rtcintr,
+ SWI_CLOCK_MASK, /* unit */ 0);
INTREN(IRQ8);
outb(IO_RTC, RTC_STATUSB);
outb(IO_RTC+1, RTCSB_PINTR | RTCSB_24HR);
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c
index 35f2e42..e3f3f21 100644
--- a/sys/i386/isa/clock.c
+++ b/sys/i386/isa/clock.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.13 1994/08/13 03:49:56 wollman Exp $
+ * $Id: clock.c,v 1.14 1994/08/15 03:15:18 wollman Exp $
*/
/*
@@ -497,16 +497,14 @@ test_inittodr(time_t base)
/*
* Wire clock interrupt in.
*/
-#define V(s) __CONCAT(V, s)
-extern void V(clk)();
-extern void V(rtc)();
-
void
enablertclock()
{
- setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL);
+ register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, clkintr,
+ HWI_MASK | SWI_MASK, /* unit */ 0);
INTREN(IRQ0);
- setidt(ICU_OFFSET+8, &V(rtc), SDT_SYS386IGT, SEL_KPL);
+ register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, rtcintr,
+ SWI_CLOCK_MASK, /* unit */ 0);
INTREN(IRQ8);
outb(IO_RTC, RTC_STATUSB);
outb(IO_RTC+1, RTCSB_PINTR | RTCSB_24HR);
diff --git a/sys/i386/isa/icu.s b/sys/i386/isa/icu.s
index 735eeda..4956ab8 100644
--- a/sys/i386/isa/icu.s
+++ b/sys/i386/isa/icu.s
@@ -36,7 +36,7 @@
*
* @(#)icu.s 7.2 (Berkeley) 5/21/91
*
- * $Id: icu.s,v 1.10 1994/08/13 03:50:01 wollman Exp $
+ * $Id: icu.s,v 1.11 1994/08/15 03:15:19 wollman Exp $
*/
/*
@@ -57,7 +57,6 @@
_cpl: .long HWI_MASK | SWI_MASK /* current priority (all off) */
.globl _imen
_imen: .long HWI_MASK /* interrupt mask enable (all h/w off) */
-_high_imask: .long HWI_MASK | SWI_MASK
.globl _stat_imask
_stat_imask: .long (1 << 8)
.globl _tty_imask
@@ -236,8 +235,8 @@ splz_swi:
jmp splz_next
/*
- * Fake clock IRQ so that it appears to come from our caller and not from
- * vec0, so that kernel profiling works.
+ * Fake clock interrupt(s) so that they appear to come from our caller instead
+ * of from here, so that system profiling works.
* XXX do this more generally (for all vectors; look up the C entry point).
* XXX frame bogusness stops us from just jumping to the C entry point.
*/
@@ -250,7 +249,17 @@ vec0:
pushl %eax
cli
MEXITCOUNT
- jmp _Vclk
+ jmp _Xintr0 /* XXX might need _Xfastintr0 */
+
+ ALIGN_TEXT
+vec8:
+ popl %eax
+ pushfl
+ pushl $KCSEL
+ pushl %eax
+ cli
+ MEXITCOUNT
+ jmp _Xintr8 /* XXX might need _Xfastintr8 */
#define BUILD_VEC(irq_num) \
ALIGN_TEXT ; \
@@ -265,7 +274,6 @@ vec/**/irq_num: ; \
BUILD_VEC(5)
BUILD_VEC(6)
BUILD_VEC(7)
- BUILD_VEC(8)
BUILD_VEC(9)
BUILD_VEC(10)
BUILD_VEC(11)
diff --git a/sys/i386/isa/isa.c b/sys/i386/isa/isa.c
index 80be9a5..5b5878e 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.19 1994/08/10 04:39:52 wollman Exp $
+ * $Id: isa.c,v 1.20 1994/08/13 03:50:07 wollman Exp $
*/
/*
@@ -65,6 +65,7 @@
#include <i386/isa/icu.h>
#include <i386/isa/ic/i8237.h>
#include <i386/isa/ic/i8042.h>
+#include "vector.h"
/*
** Register definitions for DMA controller 1 (channels 0..3):
@@ -82,20 +83,70 @@
#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */
#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */
-void config_isadev __P((struct isa_device *, u_int *));
+/*
+ * Bits to specify the type and amount of conflict checking.
+ */
+#define CC_ATTACH (1 << 0)
+#define CC_DRQ (1 << 1)
+#define CC_IOADDR (1 << 2)
+#define CC_IRQ (1 << 3)
+#define CC_MEMADDR (1 << 4)
+
+/*
+ * XXX these defines should be in a central place.
+ */
+#define read_eflags() ({u_long ef; \
+ __asm("pushfl; popl %0" : "=a" (ef)); \
+ ef; })
+#define write_eflags(ef) __asm("pushl %0; popfl" : : "a" ((u_long)(ef)))
+
+u_long *intr_countp[ICU_LEN];
+inthand2_t *intr_handler[ICU_LEN];
+u_int intr_mask[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)
+};
+
+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)
+};
+
+static void config_isadev __P((struct isa_device *isdp, u_int *mp));
+static void conflict __P((struct isa_device *dvp, struct isa_device *tmpdvp,
+ int item, char const *whatnot, char const *reason,
+ char const *format));
+static int haveseen __P((struct isa_device *dvp, struct isa_device *tmpdvp,
+ u_int checkbits));
+static int haveseen_isadev __P((struct isa_device *dvp, u_int checkbits));
+static inthand2_t isa_strayintr;
+static void register_imask __P((struct isa_device *dvp, u_int mask));
/*
* print a conflict message
*/
-void
-conflict(dvp, tmpdvp, item, reason, format)
- struct isa_device *dvp, *tmpdvp;
+static void
+conflict(dvp, tmpdvp, item, whatnot, reason, format)
+ struct isa_device *dvp;
+ struct isa_device *tmpdvp;
int item;
- char *reason;
- char *format;
+ char const *whatnot;
+ char const *reason;
+ char const *format;
{
- printf("%s%d not probed due to %s conflict with %s%d at ",
- dvp->id_driver->name, dvp->id_unit, reason,
+ printf("%s%d not %sed due to %s conflict with %s%d at ",
+ dvp->id_driver->name, dvp->id_unit, whatnot, reason,
tmpdvp->id_driver->name, tmpdvp->id_unit);
printf(format, item);
printf("\n");
@@ -105,9 +156,11 @@ conflict(dvp, tmpdvp, item, reason, format)
* Check to see if things are alread in use, like IRQ's, I/O addresses
* and Memory addresses.
*/
-int
-haveseen(dvp, tmpdvp)
- struct isa_device *dvp, *tmpdvp;
+static int
+haveseen(dvp, tmpdvp, checkbits)
+ struct isa_device *dvp;
+ struct isa_device *tmpdvp;
+ u_int checkbits;
{
int status = 0;
@@ -115,17 +168,20 @@ haveseen(dvp, tmpdvp)
* Only check against devices that have already been found
*/
if (tmpdvp->id_alive) {
+ char const *whatnot;
+
+ whatnot = checkbits & CC_ATTACH ? "attach" : "probe";
/*
* Check for I/O address conflict. We can only check the
* starting address of the device against the range of the
* device that has already been probed since we do not
* know how many I/O addresses this device uses.
*/
- if (tmpdvp->id_alive != -1) {
+ if (checkbits & CC_IOADDR && tmpdvp->id_alive != -1) {
if ((dvp->id_iobase >= tmpdvp->id_iobase) &&
(dvp->id_iobase <=
(tmpdvp->id_iobase + tmpdvp->id_alive - 1))) {
- conflict(dvp, tmpdvp, dvp->id_iobase,
+ conflict(dvp, tmpdvp, dvp->id_iobase, whatnot,
"I/O address", "0x%x");
status = 1;
}
@@ -140,34 +196,32 @@ haveseen(dvp, tmpdvp)
* since at that time we would know the full range.
* XXX KERNBASE is a hack, we should have vaddr in the table!
*/
- if(tmpdvp->id_maddr) {
- if((KERNBASE + dvp->id_maddr >= tmpdvp->id_maddr) &&
- (KERNBASE + dvp->id_maddr <=
- (tmpdvp->id_maddr + tmpdvp->id_msize - 1))) {
- conflict(dvp, tmpdvp, dvp->id_maddr, "maddr",
- "0x%x");
+ if (checkbits & CC_MEMADDR && tmpdvp->id_maddr) {
+ if ((KERNBASE + dvp->id_maddr >= tmpdvp->id_maddr) &&
+ (KERNBASE + dvp->id_maddr <=
+ (tmpdvp->id_maddr + tmpdvp->id_msize - 1))) {
+ conflict(dvp, tmpdvp, (int)dvp->id_maddr,
+ whatnot, "maddr", "0x%x");
status = 1;
}
}
-#ifndef COM_MULTIPORT
/*
* Check for IRQ conflicts.
*/
- if(tmpdvp->id_irq) {
+ if (checkbits & CC_IRQ && tmpdvp->id_irq) {
if (tmpdvp->id_irq == dvp->id_irq) {
conflict(dvp, tmpdvp, ffs(dvp->id_irq) - 1,
- "irq", "%d");
+ whatnot, "irq", "%d");
status = 1;
}
}
-#endif
/*
* Check for DRQ conflicts.
*/
- if(tmpdvp->id_drq != -1) {
+ if (checkbits & CC_DRQ && tmpdvp->id_drq != -1) {
if (tmpdvp->id_drq == dvp->id_drq) {
- conflict(dvp, tmpdvp, dvp->id_drq,
- "drq", "%d");
+ conflict(dvp, tmpdvp, dvp->id_drq, whatnot,
+ "drq", "%d");
status = 1;
}
}
@@ -179,25 +233,22 @@ haveseen(dvp, tmpdvp)
* Search through all the isa_devtab_* tables looking for anything that
* conflicts with the current device.
*/
-int
-haveseen_isadev(dvp)
+static int
+haveseen_isadev(dvp, checkbits)
struct isa_device *dvp;
+ u_int checkbits;
{
struct isa_device *tmpdvp;
int status = 0;
- for (tmpdvp = isa_devtab_tty; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp);
- }
- for (tmpdvp = isa_devtab_bio; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp);
- }
- for (tmpdvp = isa_devtab_net; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp);
- }
- for (tmpdvp = isa_devtab_null; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp);
- }
+ for (tmpdvp = isa_devtab_tty; tmpdvp->id_driver; tmpdvp++)
+ status |= haveseen(dvp, tmpdvp, checkbits);
+ for (tmpdvp = isa_devtab_bio; tmpdvp->id_driver; tmpdvp++)
+ status |= haveseen(dvp, tmpdvp, checkbits);
+ for (tmpdvp = isa_devtab_net; tmpdvp->id_driver; tmpdvp++)
+ status |= haveseen(dvp, tmpdvp, checkbits);
+ for (tmpdvp = isa_devtab_null; tmpdvp->id_driver; tmpdvp++)
+ status |= haveseen(dvp, tmpdvp, checkbits);
return(status);
}
@@ -208,26 +259,18 @@ void
isa_configure() {
struct isa_device *dvp;
- enable_intr();
splhigh();
+ enable_intr();
INTREN(IRQ_SLAVE);
printf("Probing for devices on the ISA bus:\n");
- for (dvp = isa_devtab_tty; dvp->id_driver; dvp++) {
- if (!haveseen_isadev(dvp))
- config_isadev(dvp,&tty_imask);
- }
- for (dvp = isa_devtab_bio; dvp->id_driver; dvp++) {
- if (!haveseen_isadev(dvp))
- config_isadev(dvp,&bio_imask);
- }
- for (dvp = isa_devtab_net; dvp->id_driver; dvp++) {
- if (!haveseen_isadev(dvp))
- config_isadev(dvp,&net_imask);
- }
- for (dvp = isa_devtab_null; dvp->id_driver; dvp++) {
- if (!haveseen_isadev(dvp))
- config_isadev(dvp,(u_int *) NULL);
- }
+ for (dvp = isa_devtab_tty; dvp->id_driver; dvp++)
+ config_isadev(dvp, &tty_imask);
+ for (dvp = isa_devtab_bio; dvp->id_driver; dvp++)
+ config_isadev(dvp, &bio_imask);
+ for (dvp = isa_devtab_net; dvp->id_driver; dvp++)
+ config_isadev(dvp, &net_imask);
+ for (dvp = isa_devtab_null; dvp->id_driver; dvp++)
+ config_isadev(dvp, (u_int *)NULL);
bio_imask |= SWI_CLOCK_MASK;
net_imask |= SWI_NET_MASK;
tty_imask |= SWI_TTY_MASK;
@@ -253,27 +296,54 @@ isa_configure() {
printf("bio_imask %x tty_imask %x net_imask %x\n",
bio_imask, tty_imask, net_imask);
#endif
+ /*
+ * Finish initializing intr_mask[]. Note that the partly
+ * constructed masks aren't actually used since we're at splhigh.
+ * For fully dynamic initialization, register_intr() and
+ * unregister_intr() will have to adjust the masks for _all_
+ * interrupts and for tty_imask, etc.
+ */
+ for (dvp = isa_devtab_tty; dvp->id_driver; dvp++)
+ register_imask(dvp, tty_imask);
+ for (dvp = isa_devtab_bio; dvp->id_driver; dvp++)
+ register_imask(dvp, bio_imask);
+ for (dvp = isa_devtab_net; dvp->id_driver; dvp++)
+ register_imask(dvp, net_imask);
+ for (dvp = isa_devtab_null; dvp->id_driver; dvp++)
+ register_imask(dvp, SWI_CLOCK_MASK);
splnone();
}
/*
* Configure an ISA device.
*/
-void
+static void
config_isadev(isdp, mp)
struct isa_device *isdp;
u_int *mp;
{
+ u_int checkbits;
+ int id_alive;
struct isa_driver *dp = isdp->id_driver;
+ checkbits = 0;
+#ifndef ALLOW_CONFLICT_DRQ
+ checkbits |= CC_DRQ;
+#endif
+#ifndef ALLOW_CONFLICT_IOADDR
+ checkbits |= CC_IOADDR;
+#endif
+#ifndef ALLOW_CONFLICT_MEMADDR
+ checkbits |= CC_MEMADDR;
+#endif
+ if (haveseen_isadev(isdp, checkbits))
+ return;
if (isdp->id_maddr) {
- extern u_int atdevbase;
-
isdp->id_maddr -= 0xa0000; /* XXX should be a define */
isdp->id_maddr += atdevbase;
}
- isdp->id_alive = (*dp->probe)(isdp);
- if (isdp->id_alive) {
+ id_alive = (*dp->probe)(isdp);
+ if (id_alive) {
/*
* Only print the I/O address range if id_alive != -1
* Right now this is a temporary fix just for the new
@@ -282,21 +352,20 @@ config_isadev(isdp, mp)
* Rod Grimes 04/26/94
*/
printf("%s%d", dp->name, isdp->id_unit);
- if (isdp->id_alive != -1) {
+ if (id_alive != -1) {
printf(" at 0x%x", isdp->id_iobase);
- if ((isdp->id_iobase + isdp->id_alive - 1) !=
+ if ((isdp->id_iobase + id_alive - 1) !=
isdp->id_iobase) {
printf("-0x%x",
- isdp->id_iobase +
- isdp->id_alive - 1);
+ isdp->id_iobase + id_alive - 1);
}
}
- if(isdp->id_irq)
+ if (isdp->id_irq)
printf(" irq %d", ffs(isdp->id_irq) - 1);
if (isdp->id_drq != -1)
printf(" drq %d", isdp->id_drq);
if (isdp->id_maddr)
- printf(" maddr 0x%x", kvtop(isdp->id_maddr));
+ printf(" maddr 0x%lx", kvtop(isdp->id_maddr));
if (isdp->id_msize)
printf(" msize %d", isdp->id_msize);
if (isdp->id_flags)
@@ -312,18 +381,25 @@ config_isadev(isdp, mp)
}
}
}
-
+ /*
+ * Check for conflicts again. The driver may have changed
+ * *dvp. We should weaken the early check since the
+ * driver may have been able to change *dvp to avoid
+ * conflicts if given a chance. We already skip the early
+ * check for IRQs and force a check for IRQs in the next
+ * group of checks.
+ */
+ checkbits |= CC_IRQ;
+ if (haveseen_isadev(isdp, checkbits))
+ return;
+ isdp->id_alive = id_alive;
(*dp->attach)(isdp);
-
- if(isdp->id_irq) {
- int intrno;
-
- intrno = ffs(isdp->id_irq)-1;
- setidt(ICU_OFFSET+intrno, isdp->id_intr,
- SDT_SYS386IGT, SEL_KPL);
- if(mp) {
- INTRMASK(*mp,isdp->id_irq);
- }
+ if (isdp->id_irq) {
+ if (mp)
+ INTRMASK(*mp, isdp->id_irq);
+ register_intr(ffs(isdp->id_irq) - 1, isdp->id_id,
+ isdp->id_ri_flags, isdp->id_intr,
+ mp ? *mp : 0, isdp->id_unit);
INTREN(isdp->id_irq);
}
} else {
@@ -335,22 +411,6 @@ config_isadev(isdp, mp)
}
}
-#define IDTVEC(name) __CONCAT(X,name)
-/* default interrupt vector table entries */
-typedef void inthand_t();
-typedef void (*inthand_func_t)();
-extern inthand_t
- 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);
-
-static inthand_func_t defvec[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) };
-
/*
* Fill in default interrupt table (in case of spuruious interrupt
* during configuration of kernel, setup interrupt control unit
@@ -362,7 +422,7 @@ isa_defaultirq()
/* icu vectors */
for (i = 0; i < ICU_LEN; i++)
- setidt(ICU_OFFSET + i, defvec[i], SDT_SYS386IGT, SEL_KPL);
+ unregister_intr(i, (inthand2_t *)NULL);
/* initialize 8259's */
outb(IO_ICU1, 0x11); /* reset; program device, four bytes */
@@ -418,6 +478,9 @@ void isa_dmacascade(unsigned chan)
}
}
+static int
+isa_dmarangecheck(caddr_t va, unsigned length, unsigned chan);
+
/*
* isa_dmastart(): program 8237 DMA controller channel, avoid page alignment
* problems by using a bounce buffer.
@@ -520,7 +583,7 @@ void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
* Return true if special handling needed.
*/
-int
+static int
isa_dmarangecheck(caddr_t va, unsigned length, unsigned chan) {
vm_offset_t phys, priorpage = 0, endva;
u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1);
@@ -622,7 +685,7 @@ isa_nmi(cd)
/*
* Caught a stray interrupt, notify
*/
-void
+static void
isa_strayintr(d)
int d;
{
@@ -637,13 +700,18 @@ isa_strayintr(d)
* the first 5 get logged, then it quits logging them, and puts
* out a special message. rgrimes 3/25/1993
*/
- extern u_long intrcnt_stray;
-
- intrcnt_stray++;
- if (intrcnt_stray <= 5)
- log(LOG_ERR,"ISA strayintr %x\n", d);
- if (intrcnt_stray == 5)
- log(LOG_CRIT,"Too many ISA strayintr not logging any more\n");
+ /*
+ * 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);
}
/*
@@ -683,8 +751,84 @@ isa_irq_pending(dvp)
{
unsigned id_irq;
- id_irq = (unsigned short) dvp->id_irq; /* XXX silly type in struct */
+ id_irq = dvp->id_irq;
if (id_irq & 0xff)
return (inb(IO_ICU1) & id_irq);
return (inb(IO_ICU2) & (id_irq >> 8));
}
+
+int
+register_intr(intr, device_id, flags, handler, mask, unit)
+ int intr;
+ int device_id;
+ u_int flags;
+ inthand2_t *handler;
+ u_int mask;
+ int unit;
+{
+ char *cp;
+ u_long ef;
+ int id;
+
+ if ((u_int)intr >= ICU_LEN || intr == 2
+ || (u_int)device_id >= NR_DEVICES)
+ return (EINVAL);
+ if (intr_handler[intr] != isa_strayintr)
+ return (EBUSY);
+ ef = read_eflags();
+ disable_intr();
+ intr_countp[intr] = &intrcnt[device_id];
+ intr_handler[intr] = handler;
+ intr_mask[intr] = mask | (1 << intr);
+ intr_unit[intr] = unit;
+ setidt(ICU_OFFSET + intr,
+ flags & RI_FAST ? fastintr[intr] : slowintr[intr],
+ SDT_SYS386IGT, SEL_KPL);
+ write_eflags(ef);
+ for (cp = intrnames, id = 0; id <= device_id; id++)
+ while (*cp++ != '\0')
+ ;
+ if (cp > eintrnames)
+ return (0);
+ if (intr < 10) {
+ cp[-3] = intr + '0';
+ cp[-2] = ' ';
+ } else {
+ cp[-3] = '1';
+ cp[-2] = intr - 10 + '0';
+ }
+ 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);
+ }
+}
+
+int
+unregister_intr(intr, handler)
+ int intr;
+ inthand2_t *handler;
+{
+ u_long ef;
+
+ if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr])
+ return (EINVAL);
+ ef = read_eflags();
+ disable_intr();
+ intr_countp[intr] = &intrcnt[NR_DEVICES + intr];
+ intr_handler[intr] = isa_strayintr;
+ intr_mask[intr] = HWI_MASK | SWI_MASK;
+ intr_unit[intr] = intr;
+ setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL);
+ write_eflags(ef);
+ return (0);
+}
diff --git a/sys/i386/isa/isa_device.h b/sys/i386/isa/isa_device.h
index 16fac9a..47dd12d 100644
--- a/sys/i386/isa/isa_device.h
+++ b/sys/i386/isa/isa_device.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa_device.h 7.1 (Berkeley) 5/9/91
- * $Id: isa_device.h,v 1.4 1993/12/19 00:50:42 wollman Exp $
+ * $Id: isa_device.h,v 1.5 1994/01/04 20:06:30 nate Exp $
*/
#ifndef _I386_ISA_ISA_DEVICE_H_
@@ -41,21 +41,38 @@
* ISA Bus Autoconfiguration
*/
+#define IDTVEC(name) __CONCAT(X,name)
+
+/*
+ * Type of the first (asm) part of an interrupt handler.
+ */
+typedef void inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss));
+
+/*
+ * Usual type of the second (C) part of an interrupt handler. Some bogus
+ * ones need the arg to be the interrupt frame (and not a copy of it, which
+ * is all that is possible in C).
+ */
+typedef void inthand2_t __P((int unit));
+
/*
* Per device structure.
*/
struct isa_device {
+ int id_id; /* device id */
struct isa_driver *id_driver;
short id_iobase; /* base i/o address */
u_short id_irq; /* interrupt request */
short id_drq; /* DMA request */
caddr_t id_maddr; /* physical i/o memory address on bus (if any)*/
int id_msize; /* size of i/o memory */
- void (*id_intr)(); /* interrupt interface routine */
+ inthand2_t *id_intr; /* interrupt interface routine */
int id_unit; /* unit number */
int id_flags; /* flags */
int id_scsiid; /* scsi id if needed */
int id_alive; /* device is present */
+#define RI_FAST 1 /* fast interrupt handler */
+ u_int id_ri_flags; /* flags for register_intr() */
};
/*
@@ -66,17 +83,49 @@ struct isa_device {
* These are used at boot time by the configuration program.
*/
struct isa_driver {
- int (*probe)(); /* test whether device is present */
- int (*attach)(); /* setup driver for a device */
+ int (*probe) __P((struct isa_device *idp));
+ /* test whether device is present */
+ int (*attach) __P((struct isa_device *idp));
+ /* setup driver for a device */
char *name; /* device name */
};
+extern char eintrnames[]; /* end of intrnames[] */
+extern u_long intrcnt[]; /* counts for for each device and stray */
+extern char intrnames[]; /* string table containing device names */
+u_long *intr_countp[]; /* indirectors into intrcnt[] */
+inthand2_t *intr_handler[]; /* C entry points of intr handlers */
+u_int intr_mask[]; /* sets of intrs masked during handling of 1 */
+int intr_unit[]; /* cookies to pass to intr handlers */
+
extern struct isa_device isa_devtab_bio[], isa_devtab_tty[], isa_devtab_net[],
isa_devtab_null[], isa_biotab_wdc[], isa_biotab_fdc[];
-extern struct isa_device *find_isadev(/* table, driver, unit*/);
-
-extern void isa_dmastart(int, caddr_t, unsigned, unsigned);
-extern void isa_dmadone(int, caddr_t, int, int);
+inthand_t
+ 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);
+struct isa_device *find_isadev __P((struct isa_device *table,
+ struct isa_driver *driverp, int unit));
+inthand_t
+ 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);
+void isa_configure __P((void));
+void isa_defaultirq __P((void));
+void isa_dmacascade __P((unsigned chan));
+void isa_dmadone __P((int, caddr_t, int, int));
+void isa_dmastart __P((int, caddr_t, unsigned, unsigned));
+int isa_irq_pending __P((struct isa_device *dvp));
+int isa_nmi __P((int cd));
+int register_intr __P((int intr, int device_id, u_int flags,
+ inthand2_t *handler, u_int mask, int unit));
+int unregister_intr __P((int intr, inthand2_t *handler));
#endif /* _I386_ISA_ISA_DEVICE_H_ */
diff --git a/sys/i386/isa/sio.c b/sys/i386/isa/sio.c
index de95e90..d505c4d 100644
--- a/sys/i386/isa/sio.c
+++ b/sys/i386/isa/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.47 1994/05/26 13:31:40 rgrimes Exp $
+ * $Id: sio.c,v 1.48 1994/08/13 03:50:13 wollman Exp $
*/
#include "sio.h"
@@ -427,6 +427,7 @@ sioattach(isdp)
int s;
int unit;
+ isdp->id_ri_flags |= RI_FAST;
iobase = isdp->id_iobase;
unit = isdp->id_unit;
s = spltty();
diff --git a/sys/i386/isa/vector.s b/sys/i386/isa/vector.s
index 7135ae7..252bd95 100644
--- a/sys/i386/isa/vector.s
+++ b/sys/i386/isa/vector.s
@@ -1,6 +1,6 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
- * $Id: vector.s,v 1.6 1994/01/10 23:15:09 ache Exp $
+ * $Id: vector.s,v 1.7 1994/04/02 07:00:50 davidg Exp $
*/
#include "i386/isa/icu.h"
@@ -97,7 +97,10 @@
* loading segregs.
*/
-#define FAST_INTR(unit, irq_num, id_num, handler, enable_icus) \
+#define FAST_INTR(irq_num, enable_icus) \
+ .text ; \
+ SUPERALIGN_TEXT ; \
+IDTVEC(fastintr/**/irq_num) ; \
pushl %eax ; /* save only call-used registers */ \
pushl %ecx ; \
pushl %edx ; \
@@ -107,12 +110,13 @@
movl %ax,%ds ; \
MAYBE_MOVW_AX_ES ; \
FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \
- pushl $unit ; \
- call handler ; /* do the work ASAP */ \
+ pushl _intr_unit + (irq_num) * 4 ; \
+ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \
addl $4,%esp ; \
incl _cnt+V_INTR ; /* book-keeping can wait */ \
- incl _intrcnt_actv + (id_num) * 4 ; \
+ movl _intr_countp + (irq_num) * 4,%eax ; \
+ incl (%eax) ; \
movl _cpl,%eax ; /* are we unmasking pending HWIs or SWIs? */ \
notl %eax ; \
andl _ipending,%eax ; \
@@ -147,7 +151,10 @@
MEXITCOUNT ; \
jmp _doreti
-#define INTR(unit, irq_num, id_num, mask, handler, icu, enable_icus, reg, stray) \
+#define INTR(irq_num, icu, enable_icus, reg) \
+ .text ; \
+ SUPERALIGN_TEXT ; \
+IDTVEC(intr/**/irq_num) ; \
pushl $0 ; /* dumby error code */ \
pushl $0 ; /* dumby trap type */ \
pushal ; \
@@ -167,15 +174,17 @@
testb $IRQ_BIT(irq_num),%reg ; \
jne 2f ; \
1: ; \
+Xresume/**/irq_num: ; \
FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \
- incl _intrcnt_actv + (id_num) * 4 ; \
+ movl _intr_countp + (irq_num) * 4,%eax ; \
+ incl (%eax) ; \
movl _cpl,%eax ; \
pushl %eax ; \
- pushl $unit ; \
- orl mask,%eax ; \
+ pushl _intr_unit + (irq_num) * 4 ; \
+ orl _intr_mask + (irq_num) * 4,%eax ; \
movl %eax,_cpl ; \
sti ; \
- call handler ; \
+ call *_intr_handler + (irq_num) * 4 ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
andb $~IRQ_BIT(irq_num),%al ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
@@ -189,9 +198,6 @@
ALIGN_TEXT ; \
2: ; \
/* XXX skip mcounting here to avoid double count */ \
- movl $1b,%eax ; /* register resume address */ \
- /* XXX - someday do it at attach time */ \
- movl %eax,ihandlers + (irq_num) * 4 ; \
orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \
popl %es ; \
popl %ds ; \
@@ -199,118 +205,48 @@
addl $4+4,%esp ; \
iret
-/*
- * vector.h has defined a macro 'BUILD_VECTORS' containing a big list of info
- * about vectors, including a submacro 'BUILD_VECTOR' that operates on the
- * info about each vector. We redefine 'BUILD_VECTOR' to expand the info
- * in different ways. Here we expand it to a list of interrupt handlers.
- * This order is of course unimportant. Elsewhere we expand it to inline
- * linear search code for which the order is a little more important and
- * concatenating the code with no holes is very important.
- *
- * XXX - now there is BUILD_FAST_VECTOR as well as BUILD_VECTOR.
- *
- * The info consists of the following items for each vector:
- *
- * name (identifier): name of the vector; used to build labels
- * unit (expression): unit number to call the device driver with
- * irq_num (number): number of the IRQ to handled (0-15)
- * id_num (number): uniq numeric id for handler (assigned by config)
- * mask (blank-ident): priority mask used
- * handler (blank-ident): interrupt handler to call
- * icu_num (number): (1 + irq_num / 8) converted for label building
- * icu_enables (number): 1 for icu_num == 1, 1_AND_2 for icu_num == 2
- * reg (blank-ident): al for icu_num == 1, ah for icu_num == 2
- *
- * 'irq_num' is converted in several ways at config time to get around
- * limitations in cpp. The macros have blanks after commas iff they would
- * not mess up identifiers and numbers.
- */
-
-#undef BUILD_FAST_VECTOR
-#define BUILD_FAST_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .globl handler ; \
- .text ; \
- .globl _V/**/name ; \
- SUPERALIGN_TEXT ; \
-_V/**/name: ; \
- FAST_INTR(unit, irq_num,id_num, handler, ENABLE_ICU/**/icu_enables)
-
-#undef BUILD_VECTOR
-#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .globl handler ; \
- .text ; \
- .globl _V/**/name ; \
- SUPERALIGN_TEXT ; \
-_V/**/name: ; \
- INTR(unit,irq_num, id_num, mask, handler, IO_ICU/**/icu_num, \
- ENABLE_ICU/**/icu_enables, reg,)
-
MCOUNT_LABEL(bintr)
- BUILD_VECTORS
-
- /* hardware interrupt catcher (IDT 32 - 47) */
- .globl _isa_strayintr
-
-#define STRAYINTR(irq_num, icu_num, icu_enables, reg) \
-IDTVEC(intr/**/irq_num) ; \
- INTR(irq_num,irq_num,irq_num, _high_imask, _isa_strayintr, \
- IO_ICU/**/icu_num, ENABLE_ICU/**/icu_enables, reg,stray)
-
-/*
- * XXX - the mask (1 << 2) == IRQ_SLAVE will be generated for IRQ 2, instead
- * of the mask IRQ2 (defined as IRQ9 == (1 << 9)). But IRQ 2 "can't happen".
- * In fact, all stray interrupts "can't happen" except for bugs. The
- * "stray" IRQ 7 is documented behaviour of the 8259. It happens when there
- * is a glitch on any of its interrupt inputs. Does it really interrupt when
- * IRQ 7 is masked?
- *
- * XXX - unpend doesn't work for these, it sends them to the real handler.
- *
- * XXX - the race bug during initialization may be because I changed the
- * order of switching from the stray to the real interrupt handler to before
- * enabling interrupts. The old order looked unsafe but maybe it is OK with
- * the stray interrupt handler installed. But these handlers only reduce
- * the window of vulnerability - it is still open at the end of
- * isa_configure().
- *
- * XXX - many comments are stale.
- */
-
- STRAYINTR(0,1,1, al)
- STRAYINTR(1,1,1, al)
- STRAYINTR(2,1,1, al)
- STRAYINTR(3,1,1, al)
- STRAYINTR(4,1,1, al)
- STRAYINTR(5,1,1, al)
- STRAYINTR(6,1,1, al)
- STRAYINTR(7,1,1, al)
- STRAYINTR(8,2,1_AND_2, ah)
- STRAYINTR(9,2,1_AND_2, ah)
- STRAYINTR(10,2,1_AND_2, ah)
- STRAYINTR(11,2,1_AND_2, ah)
- STRAYINTR(12,2,1_AND_2, ah)
- STRAYINTR(13,2,1_AND_2, ah)
- STRAYINTR(14,2,1_AND_2, ah)
- STRAYINTR(15,2,1_AND_2, ah)
-#if 0
- INTRSTRAY(255, _highmask, 255) ; call _isa_strayintr ; INTREXIT2
-#endif
+ FAST_INTR(0, ENABLE_ICU1)
+ FAST_INTR(1, ENABLE_ICU1)
+ FAST_INTR(2, ENABLE_ICU1)
+ FAST_INTR(3, ENABLE_ICU1)
+ FAST_INTR(4, ENABLE_ICU1)
+ FAST_INTR(5, ENABLE_ICU1)
+ FAST_INTR(6, ENABLE_ICU1)
+ FAST_INTR(7, ENABLE_ICU1)
+ FAST_INTR(8, ENABLE_ICU1_AND_2)
+ FAST_INTR(9, ENABLE_ICU1_AND_2)
+ FAST_INTR(10, ENABLE_ICU1_AND_2)
+ FAST_INTR(11, ENABLE_ICU1_AND_2)
+ FAST_INTR(12, ENABLE_ICU1_AND_2)
+ FAST_INTR(13, ENABLE_ICU1_AND_2)
+ FAST_INTR(14, ENABLE_ICU1_AND_2)
+ FAST_INTR(15, ENABLE_ICU1_AND_2)
+ INTR(0, IO_ICU1, ENABLE_ICU1, al)
+ INTR(1, IO_ICU1, ENABLE_ICU1, al)
+ INTR(2, IO_ICU1, ENABLE_ICU1, al)
+ INTR(3, IO_ICU1, ENABLE_ICU1, al)
+ INTR(4, IO_ICU1, ENABLE_ICU1, al)
+ INTR(5, IO_ICU1, ENABLE_ICU1, al)
+ INTR(6, IO_ICU1, ENABLE_ICU1, al)
+ INTR(7, IO_ICU1, ENABLE_ICU1, al)
+ INTR(8, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(9, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(10, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(11, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(12, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(13, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(14, IO_ICU2, ENABLE_ICU1_AND_2, ah)
+ INTR(15, IO_ICU2, ENABLE_ICU1_AND_2, ah)
MCOUNT_LABEL(eintr)
-/*
- * These are the interrupt counters, I moved them here from icu.s so that
- * they are with the name table. rgrimes
- *
- * There are now lots of counters, this has been redone to work with
- * Bruce Evans intr-0.1 code, which I modified some more to make it all
- * work with vmstat.
- */
.data
ihandlers: /* addresses of interrupt handlers */
- .space NHWI*4 /* actually resumption addresses for HWI's */
+ /* actually resumption addresses for HWI's */
+ .long Xresume0, Xresume1, Xresume2, Xresume3
+ .long Xresume4, Xresume5, Xresume6, Xresume7
+ .long Xresume8, Xresume9, Xresume10, Xresume11
+ .long Xresume12, Xresume13, Xresume14, Xresume15
.long swi_tty, swi_net, 0, 0, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, swi_clock, swi_ast
imasks: /* masks for interrupt handlers */
@@ -318,43 +254,37 @@ imasks: /* masks for interrupt handlers */
.long SWI_TTY_MASK, SWI_NET_MASK, 0, 0, 0, 0, 0, 0
.long 0, 0, 0, 0, 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK
- .globl _intrcnt
-_intrcnt: /* used by vmstat to calc size of table */
- .globl _intrcnt_bad7
-_intrcnt_bad7: .space 4 /* glitches on irq 7 */
- .globl _intrcnt_bad15
-_intrcnt_bad15: .space 4 /* glitches on irq 15 */
- .globl _intrcnt_stray
-_intrcnt_stray: .space 4 /* total count of stray interrupts */
- .globl _intrcnt_actv
-_intrcnt_actv: .space NR_REAL_INT_HANDLERS * 4 /* active interrupts */
- .globl _eintrcnt
-_eintrcnt: /* used by vmstat to calc size of table */
-
-/*
- * Build the interrupt name table for vmstat
- */
-
-#undef BUILD_FAST_VECTOR
-#define BUILD_FAST_VECTOR BUILD_VECTOR
-
-#undef BUILD_VECTOR
-#define BUILD_VECTOR(name, unit, irq_num, id_num, mask, handler, \
- icu_num, icu_enables, reg) \
- .ascii "name irq" ; \
- .asciz "irq_num"
/*
- * XXX - use the __STRING and __CONCAT macros from <sys/cdefs.h> to stringize
- * and concatenate names above and elsewhere. Note that __CONCAT doesn't
- * work when nested.
+ * Interrupt counters and names. The format of these and the label names
+ * must agree with what vmstat expects. The tables are indexed by device
+ * ids so that we don't have to move the names around as devices are
+ * attached.
*/
+#include "vector.h"
+ .globl _intrcnt, _eintrcnt
+_intrcnt:
+ .space (NR_DEVICES + ICU_LEN) * 4
+_eintrcnt:
- .text
.globl _intrnames, _eintrnames
_intrnames:
- BUILD_VECTOR(bad,,7,,,,,,)
- BUILD_VECTOR(bad,,15,,,,,,)
- BUILD_VECTOR(stray,,,,,,,,)
- BUILD_VECTORS
-
+ .ascii DEVICE_NAMES
+ .asciz "stray irq0"
+ .asciz "stray irq1"
+ .asciz "stray irq2"
+ .asciz "stray irq3"
+ .asciz "stray irq4"
+ .asciz "stray irq5"
+ .asciz "stray irq6"
+ .asciz "stray irq7"
+ .asciz "stray irq8"
+ .asciz "stray irq9"
+ .asciz "stray irq10"
+ .asciz "stray irq11"
+ .asciz "stray irq12"
+ .asciz "stray irq13"
+ .asciz "stray irq14"
+ .asciz "stray irq15"
_eintrnames:
+
+ .text
diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c
index 35f2e42..e3f3f21 100644
--- a/sys/isa/atrtc.c
+++ b/sys/isa/atrtc.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.13 1994/08/13 03:49:56 wollman Exp $
+ * $Id: clock.c,v 1.14 1994/08/15 03:15:18 wollman Exp $
*/
/*
@@ -497,16 +497,14 @@ test_inittodr(time_t base)
/*
* Wire clock interrupt in.
*/
-#define V(s) __CONCAT(V, s)
-extern void V(clk)();
-extern void V(rtc)();
-
void
enablertclock()
{
- setidt(ICU_OFFSET+0, &V(clk), SDT_SYS386IGT, SEL_KPL);
+ register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0, clkintr,
+ HWI_MASK | SWI_MASK, /* unit */ 0);
INTREN(IRQ0);
- setidt(ICU_OFFSET+8, &V(rtc), SDT_SYS386IGT, SEL_KPL);
+ register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0, rtcintr,
+ SWI_CLOCK_MASK, /* unit */ 0);
INTREN(IRQ8);
outb(IO_RTC, RTC_STATUSB);
outb(IO_RTC+1, RTCSB_PINTR | RTCSB_24HR);
diff --git a/sys/isa/sio.c b/sys/isa/sio.c
index de95e90..d505c4d 100644
--- a/sys/isa/sio.c
+++ b/sys/isa/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.47 1994/05/26 13:31:40 rgrimes Exp $
+ * $Id: sio.c,v 1.48 1994/08/13 03:50:13 wollman Exp $
*/
#include "sio.h"
@@ -427,6 +427,7 @@ sioattach(isdp)
int s;
int unit;
+ isdp->id_ri_flags |= RI_FAST;
iobase = isdp->id_iobase;
unit = isdp->id_unit;
s = spltty();
OpenPOWER on IntegriCloud