summaryrefslogtreecommitdiff
path: root/sys/arch/i386/isa
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>2001-12-04 00:00:37 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>2001-12-04 00:00:37 +0000
commit9bf62191c2a2e2d5aeb7537858d4a8164ea9ebcc (patch)
tree2bdc2c594e23844416a8dc77a6c5a4b0f5517b74 /sys/arch/i386/isa
parent1354afe4470c3aeace3d9c3ea0857e8ba5499de4 (diff)
New try at a level based irq system.
Diffstat (limited to 'sys/arch/i386/isa')
-rw-r--r--sys/arch/i386/isa/icu.h5
-rw-r--r--sys/arch/i386/isa/icu.s20
-rw-r--r--sys/arch/i386/isa/isa_machdep.c57
-rw-r--r--sys/arch/i386/isa/npx.c6
-rw-r--r--sys/arch/i386/isa/vector.s14
5 files changed, 59 insertions, 43 deletions
diff --git a/sys/arch/i386/isa/icu.h b/sys/arch/i386/isa/icu.h
index 231a4404cbc..5279822d3cd 100644
--- a/sys/arch/i386/isa/icu.h
+++ b/sys/arch/i386/isa/icu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: icu.h,v 1.6 2001/11/18 20:46:49 aaron Exp $ */
+/* $OpenBSD: icu.h,v 1.7 2001/12/04 00:00:36 niklas Exp $ */
/* $NetBSD: icu.h,v 1.19 1996/02/01 22:31:21 mycroft Exp $ */
/*-
@@ -65,6 +65,9 @@ extern unsigned imen; /* interrupt mask enable */
/*
* Interrupt Control offset into Interrupt descriptor table (IDT)
+ * XXX ICU_OFFSET is actually a property of our architecture not of the ICU
+ * XXX and therefore ought to use the architecture manifest constant IDTVECOFF
+ * XXX for its definition instead.
*/
#define ICU_OFFSET 32 /* 0-31 are processor exceptions */
#define ICU_LEN 16 /* 32-47 are ISA interrupts */
diff --git a/sys/arch/i386/isa/icu.s b/sys/arch/i386/isa/icu.s
index 8be1d64520b..57b11456f29 100644
--- a/sys/arch/i386/isa/icu.s
+++ b/sys/arch/i386/isa/icu.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: icu.s,v 1.17 2001/11/18 20:46:49 aaron Exp $ */
+/* $OpenBSD: icu.s,v 1.18 2001/12/04 00:00:36 niklas Exp $ */
/* $NetBSD: icu.s,v 1.45 1996/01/07 03:59:34 mycroft Exp $ */
/*-
@@ -45,7 +45,7 @@ _C_LABEL(imen):
ALIGN_TEXT
_C_LABEL(splhigh):
- movl $-1,%eax
+ movl $IPL_HIGH,%eax
xchgl %eax,_C_LABEL(cpl)
ret
@@ -72,8 +72,9 @@ IDTVEC(spllower)
pushl %edi
movl _C_LABEL(cpl),%ebx # save priority
movl $1f,%esi # address to resume loop at
-1: movl %ebx,%eax
- notl %eax
+1: movl %ebx,%eax # get cpl
+ shrl $4,%eax # find its mask.
+ movl _C_LABEL(iunmask)(,%eax,4),%eax
andl _C_LABEL(ipending),%eax
jz 2f
bsfl %eax,%eax
@@ -97,8 +98,9 @@ IDTVEC(doreti)
popl %ebx # get previous priority
movl %ebx,_C_LABEL(cpl)
movl $1f,%esi # address to resume loop at
-1: movl %ebx,%eax
- notl %eax
+1: movl %ebx,%eax # get cpl
+ shrl $4,%eax # find its mask
+ movl _C_LABEL(iunmask)(,%eax,4),%eax
andl _C_LABEL(ipending),%eax
jz 2f
bsfl %eax,%eax # slow, but not worth optimizing
@@ -132,7 +134,7 @@ IDTVEC(doreti)
IDTVEC(softtty)
#if NPCCOM > 0
- leal SIR_TTYMASK(%ebx),%eax
+ movl $IPL_SOFTTTY,%eax
movl %eax,_C_LABEL(cpl)
call _C_LABEL(comsoft)
movl %ebx,_C_LABEL(cpl)
@@ -147,7 +149,7 @@ IDTVEC(softtty)
1:
IDTVEC(softnet)
- leal SIR_NETMASK(%ebx),%eax
+ movl $IPL_SOFTNET,%eax
movl %eax,_C_LABEL(cpl)
xorl %edi,%edi
xchgl _C_LABEL(netisr),%edi
@@ -157,7 +159,7 @@ IDTVEC(softnet)
#undef DONETISR
IDTVEC(softclock)
- leal SIR_CLOCKMASK(%ebx),%eax
+ movl $IPL_SOFTCLOCK,%eax
movl %eax,_C_LABEL(cpl)
call _C_LABEL(softclock)
movl %ebx,_C_LABEL(cpl)
diff --git a/sys/arch/i386/isa/isa_machdep.c b/sys/arch/i386/isa/isa_machdep.c
index 19d352fe8ad..2ca2f0173af 100644
--- a/sys/arch/i386/isa/isa_machdep.c
+++ b/sys/arch/i386/isa/isa_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isa_machdep.c,v 1.42 2001/11/18 20:46:49 aaron Exp $ */
+/* $OpenBSD: isa_machdep.c,v 1.43 2001/12/04 00:00:36 niklas Exp $ */
/* $NetBSD: isa_machdep.c,v 1.22 1997/06/12 23:57:32 thorpej Exp $ */
#define ISA_DMA_STATS
@@ -129,6 +129,7 @@
#define _I386_BUS_DMA_PRIVATE
#include <machine/bus.h>
+#include <machine/intr.h>
#include <machine/pio.h>
#include <machine/cpufunc.h>
@@ -221,8 +222,8 @@ isa_defaultirq()
/* icu vectors */
for (i = 0; i < ICU_LEN; i++)
- setgate(&idt[ICU_OFFSET + i], IDTVEC(intr)[i], 0, SDT_SYS386IGT,
- SEL_KPL, GICODE_SEL);
+ setgate(&idt[ICU_OFFSET + i], IDTVEC(intr)[i], 0,
+ SDT_SYS386IGT, SEL_KPL, GICODE_SEL);
/* initialize 8259's */
outb(IO_ICU1, 0x11); /* reset; program device, four bytes */
@@ -260,13 +261,13 @@ isa_defaultirq()
int
isa_nmi()
{
-
/* This is historic garbage; these ports are not readable */
log(LOG_CRIT, "No-maskable interrupt, may be parity error\n");
return(0);
}
-u_long intrstray[ICU_LEN] = {0};
+u_long intrstray[ICU_LEN];
+
/*
* Caught a stray interrupt, notify
*/
@@ -287,6 +288,7 @@ isa_strayintr(irq)
int fastvec;
int intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN];
+int iminlevel[ICU_LEN], imaxlevel[ICU_LEN];
struct intrhand *intrhand[ICU_LEN];
/*
@@ -305,45 +307,49 @@ intr_calculatemasks()
for (irq = 0; irq < ICU_LEN; irq++) {
register int levels = 0;
for (q = intrhand[irq]; q; q = q->ih_next)
- levels |= 1 << q->ih_level;
+ levels |= 1 << IPL(q->ih_level);
intrlevel[irq] = levels;
}
/* Then figure out which IRQs use each level. */
- for (level = 0; level < 5; level++) {
+ for (level = 0; level < NIPL; level++) {
register int irqs = 0;
for (irq = 0; irq < ICU_LEN; irq++)
if (intrlevel[irq] & (1 << level))
irqs |= 1 << irq;
- imask[level] = irqs | SIR_ALLMASK;
+ imask[level] = irqs;
}
/*
- * There are tty, network and disk drivers that use free() at interrupt
- * time, so imp > (tty | net | bio).
+ * Initialize soft interrupt masks to block themselves.
*/
- imask[IPL_IMP] |= imask[IPL_TTY] | imask[IPL_NET] | imask[IPL_BIO];
- imask[IPL_AUDIO] |= imask[IPL_IMP];
+ IMASK(IPL_SOFTCLOCK) |= 1 << SIR_CLOCK;
+ IMASK(IPL_SOFTNET) |= 1 << SIR_NET;
+ IMASK(IPL_SOFTTTY) |= 1 << SIR_TTY;
/*
* Enforce a hierarchy that gives slow devices a better chance at not
* dropping data.
*/
- imask[IPL_TTY] |= imask[IPL_NET] | imask[IPL_BIO];
- imask[IPL_NET] |= imask[IPL_BIO];
-
- /*
- * These are pseudo-levels.
- */
- imask[IPL_NONE] = 0x00000000;
- imask[IPL_HIGH] = 0xffffffff;
+ for (level = 0; level < NIPL - 1; level++)
+ imask[level + 1] |= imask[level];
/* And eventually calculate the complete masks. */
for (irq = 0; irq < ICU_LEN; irq++) {
register int irqs = 1 << irq;
- for (q = intrhand[irq]; q; q = q->ih_next)
- irqs |= imask[q->ih_level];
- intrmask[irq] = irqs | SIR_ALLMASK;
+ int minlevel = IPL_NONE;
+ int maxlevel = IPL_NONE;
+
+ for (q = intrhand[irq]; q; q = q->ih_next) {
+ irqs |= IMASK(q->ih_level);
+ if (minlevel == IPL_NONE || q->ih_level < minlevel)
+ minlevel = q->ih_level;
+ if (q->ih_level > maxlevel)
+ maxlevel = q->ih_level;
+ }
+ intrmask[irq] = irqs;
+ iminlevel[irq] = minlevel;
+ imaxlevel[irq] = maxlevel;
}
/* Lastly, determine which IRQs are actually in use. */
@@ -357,13 +363,16 @@ intr_calculatemasks()
imen = ~irqs;
SET_ICUS();
}
+
+ /* For speed of splx, provide the inverse of the interrupt masks. */
+ for (irq = 0; irq < ICU_LEN; irq++)
+ iunmask[irq] = ~imask[irq];
}
int
fakeintr(arg)
void *arg;
{
-
return 0;
}
diff --git a/sys/arch/i386/isa/npx.c b/sys/arch/i386/isa/npx.c
index 04fb03b0533..b6fa7145ff1 100644
--- a/sys/arch/i386/isa/npx.c
+++ b/sys/arch/i386/isa/npx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: npx.c,v 1.22 2001/11/18 20:46:49 aaron Exp $ */
+/* $OpenBSD: npx.c,v 1.23 2001/12/04 00:00:36 niklas Exp $ */
/* $NetBSD: npx.c,v 1.57 1996/05/12 23:12:24 mycroft Exp $ */
#if 0
@@ -537,7 +537,7 @@ npxdna(p)
}
#ifdef DIAGNOSTIC
- if (cpl != 0 || npx_nointr != 0)
+ if (cpl != IPL_NONE || npx_nointr != 0)
panic("npxdna: masked");
#endif
@@ -612,7 +612,7 @@ npxsave()
{
#ifdef DIAGNOSTIC
- if (cpl != 0 || npx_nointr != 0)
+ if (cpl != IPL_NONE || npx_nointr != 0)
panic("npxsave: masked");
#endif
iprintf(("Fork"));
diff --git a/sys/arch/i386/isa/vector.s b/sys/arch/i386/isa/vector.s
index 664477530e9..b445c720ef1 100644
--- a/sys/arch/i386/isa/vector.s
+++ b/sys/arch/i386/isa/vector.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: vector.s,v 1.13 2001/11/18 20:46:49 aaron Exp $ */
+/* $OpenBSD: vector.s,v 1.14 2001/12/04 00:00:36 niklas Exp $ */
/* $NetBSD: vector.s,v 1.32 1996/01/07 21:29:47 mycroft Exp $ */
/*
@@ -218,13 +218,15 @@ _Xintr/**/irq_num/**/: ;\
MASK(irq_num, icu) /* mask it in hardware */ ;\
ack(irq_num) /* and allow other intrs */ ;\
incl MY_COUNT+V_INTR /* statistical info */ ;\
- testb $IRQ_BIT(irq_num),_cpl + IRQ_BYTE(irq_num) ;\
- jnz _Xhold/**/irq_num /* currently masked; hold it */ ;\
+ movl _C_LABEL(iminlevel) + (irq_num) * 4, %eax ;\
+ movzbl _C_LABEL(cpl),%ebx ;\
+ cmpl %eax,%ebx ;\
+ jae _C_LABEL(Xhold/**/irq_num)/* currently masked; hold it */;\
_Xresume/**/irq_num/**/: ;\
- movl _cpl,%eax /* cpl to restore on exit */ ;\
+ movzbl _C_LABEL(cpl),%eax /* cpl to restore on exit */ ;\
pushl %eax ;\
- orl _intrmask + (irq_num) * 4,%eax ;\
- movl %eax,_cpl /* add in this intr's mask */ ;\
+ movl _C_LABEL(imaxlevel) + (irq_num) * 4,%eax ;\
+ movl %eax,_C_LABEL(cpl) /* block enough for this irq */ ;\
sti /* safe to take intrs now */ ;\
movl _intrhand + (irq_num) * 4,%ebx /* head of chain */ ;\
testl %ebx,%ebx ;\