summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAaron Campbell <aaron@cvs.openbsd.org>2001-11-18 20:46:50 +0000
committerAaron Campbell <aaron@cvs.openbsd.org>2001-11-18 20:46:50 +0000
commited3510e3ec23ddc3fdabcc9e73813f8ef36614e8 (patch)
tree4f8baa91f7ddf04a3ca8636e81a37082d4b94cca /sys
parent8376e8e1fbcb5f1432e20d080b7f7e197c6a7f07 (diff)
Revert niklas's broken ICU interrupt handling changes; deraadt@ ok
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/i386/i386/autoconf.c7
-rw-r--r--sys/arch/i386/i386/locore.s4
-rw-r--r--sys/arch/i386/include/intr.h115
-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.c53
-rw-r--r--sys/arch/i386/isa/npx.c6
-rw-r--r--sys/arch/i386/isa/vector.s14
8 files changed, 89 insertions, 135 deletions
diff --git a/sys/arch/i386/i386/autoconf.c b/sys/arch/i386/i386/autoconf.c
index 77bc9cbafe7..02663b62c6e 100644
--- a/sys/arch/i386/i386/autoconf.c
+++ b/sys/arch/i386/i386/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.37 2001/11/12 20:28:20 niklas Exp $ */
+/* $OpenBSD: autoconf.c,v 1.38 2001/11/18 20:46:49 aaron Exp $ */
/* $NetBSD: autoconf.c,v 1.20 1996/05/03 19:41:56 christos Exp $ */
/*-
@@ -87,8 +87,9 @@ cpu_configure()
if (config_rootfound("mainbus", NULL) == NULL)
panic("cpu_configure: mainbus not configured");
- printf("biomask %x netmask %x ttymask %x\n", (u_short)IMASK(IPL_BIO),
- (u_short)IMASK(IPL_NET), (u_short)IMASK(IPL_TTY));
+ printf("biomask %x netmask %x ttymask %x\n",
+ (u_short)imask[IPL_BIO], (u_short)imask[IPL_NET],
+ (u_short)imask[IPL_TTY]);
spl0();
diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s
index cdb3d479c00..51e61d3f388 100644
--- a/sys/arch/i386/i386/locore.s
+++ b/sys/arch/i386/i386/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.60 2001/11/12 20:28:20 niklas Exp $ */
+/* $OpenBSD: locore.s,v 1.61 2001/11/18 20:46:49 aaron Exp $ */
/* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */
/*-
@@ -1653,7 +1653,7 @@ ENTRY(cpu_switch)
*/
movl $0,_C_LABEL(curproc)
- movl $IPL_NONE,_C_LABEL(cpl) # spl0()
+ movl $0,_C_LABEL(cpl) # spl0()
call _C_LABEL(Xspllower) # process pending interrupts
switch_search:
diff --git a/sys/arch/i386/include/intr.h b/sys/arch/i386/include/intr.h
index ca821fea28d..552de36e257 100644
--- a/sys/arch/i386/include/intr.h
+++ b/sys/arch/i386/include/intr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.h,v 1.8 2001/11/12 20:28:20 niklas Exp $ */
+/* $OpenBSD: intr.h,v 1.9 2001/11/18 20:46:49 aaron Exp $ */
/* $NetBSD: intr.h,v 1.5 1996/05/13 06:11:28 mycroft Exp $ */
/*
@@ -33,54 +33,19 @@
#ifndef _I386_INTR_H_
#define _I386_INTR_H_
-/*
- * Intel APICs (advanced programmable interrupt controllers) have
- * bytesized priority registers where the upper nibble is the actual
- * interrupt priority level (a.k.a. IPL). Interrupt vectors are
- * closely tied to these levels as interrupts whose vectors' upper
- * nibble is lower than or equal to the current level are blocked.
- * Not all 256 possible vectors are available for interrupts in
- * APIC systems, only
- *
- * For systems where instead the older ICU (interrupt controlling
- * unit, a.k.a. PIC or 82C59) is used, the IPL is not directly useful,
- * since the interrupt blocking is handled via interrupt masks instead
- * of levels. However the IPL is easily used as an offset into arrays
- * of masks.
- */
-#define IPLSHIFT 4 /* The upper nibble of vectors is the IPL. */
-#define NIPL 16 /* Four bits of information gives as much. */
-#define IPL(level) ((level) >> IPLSHIFT) /* Extract the IPL. */
-/* XXX Maybe this IDTVECOFF definition should be elsewhere? */
-#define IDTVECOFF 0x20 /* The lower 32 IDT vectors are reserved. */
+/* Interrupt priority `levels'; not mutually exclusive. */
+#define IPL_NONE 0 /* nothing */
+#define IPL_BIO 1 /* block I/O */
+#define IPL_NET 2 /* network */
+#define IPL_TTY 3 /* terminal */
+#define IPL_IMP 4 /* memory allocation */
+#define IPL_AUDIO 5 /* audio */
+#define IPL_CLOCK 6 /* clock */
+#define IPL_HIGH 7 /* everything */
-/*
- * This macro is only defined for 0 <= x < 14, i.e. there are fourteen
- * distinct priority levels available for interrupts.
- */
-#define MAKEIPL(priority) (IDTVECOFF + ((priority) << IPLSHIFT))
-
-/*
- * Interrupt priority levels.
- * XXX We are somewhat sloppy about what we mean by IPLs, sometimes
- * XXX we refer to the eight-bit value suitable for storing into APICs'
- * XXX priority registers, other times about the four-bit entity found
- * XXX in the former values' upper nibble, which can be used as offsets
- * XXX in various arrays of our implementation. We are hoping that
- * XXX the context will provide enough information to not make this
- * XXX sloppy naming a real problem.
- */
-#define IPL_NONE 0 /* nothing */
-#define IPL_SOFTCLOCK MAKEIPL(0) /* timeouts */
-#define IPL_SOFTNET MAKEIPL(1) /* protocol stacks */
-#define IPL_BIO MAKEIPL(2) /* block I/O */
-#define IPL_NET MAKEIPL(3) /* network */
-#define IPL_SOFTTTY MAKEIPL(4) /* delayed terminal handling */
-#define IPL_TTY MAKEIPL(5) /* terminal */
-#define IPL_IMP MAKEIPL(6) /* memory allocation */
-#define IPL_AUDIO MAKEIPL(7) /* audio */
-#define IPL_CLOCK MAKEIPL(8) /* clock */
-#define IPL_HIGH MAKEIPL(9) /* everything */
+#ifndef _LOCORE
+int imask[IPL_HIGH+1];
+#endif
/* Interrupt sharing types. */
#define IST_NONE 0 /* none */
@@ -90,19 +55,16 @@
/* Soft interrupt masks. */
#define SIR_CLOCK 31
+#define SIR_CLOCKMASK ((1 << SIR_CLOCK))
#define SIR_NET 30
+#define SIR_NETMASK ((1 << SIR_NET) | SIR_CLOCKMASK)
#define SIR_TTY 29
+#define SIR_TTYMASK ((1 << SIR_TTY) | SIR_CLOCKMASK)
+#define SIR_ALLMASK (SIR_CLOCKMASK | SIR_NETMASK | SIR_TTYMASK)
#ifndef _LOCORE
-volatile int cpl; /* Current interrupt priority level. */
-volatile int ipending; /* Interrupts pending. */
-volatile int astpending;/* Asynchronous software traps (softints) pending. */
-int imask[NIPL]; /* Bitmasks telling what interrupts are blocked. */
-int iunmask[NIPL]; /* Bitmasks telling what interrupts are accepted. */
-
-#define IMASK(level) imask[IPL(level)]
-#define IUNMASK(level) iunmask[IPL(level)]
+volatile int cpl, ipending, astpending;
extern void Xspllower __P((void));
@@ -112,7 +74,7 @@ static __inline void splx __P((int));
static __inline void softintr __P((int));
/*
- * Raise current interrupt priority level, and return the old one.
+ * Add a mask to cpl, and return the old value of cpl.
*/
static __inline int
splraise(ncpl)
@@ -120,21 +82,21 @@ splraise(ncpl)
{
register int ocpl = cpl;
- if (ncpl > ocpl)
- cpl = ncpl;
+ cpl = ocpl | ncpl;
return (ocpl);
}
/*
- * Restore an old interrupt priority level. If any thereby unmasked
+ * Restore a value to cpl (unmasking interrupts). If any unmasked
* interrupts are pending, call Xspllower() to process them.
*/
static __inline void
splx(ncpl)
register int ncpl;
{
+
cpl = ncpl;
- if (ipending & IUNMASK(ncpl))
+ if (ipending & ~ncpl)
Xspllower();
}
@@ -148,18 +110,20 @@ spllower(ncpl)
{
register int ocpl = cpl;
- splx(ncpl);
+ cpl = ncpl;
+ if (ipending & ~ncpl)
+ Xspllower();
return (ocpl);
}
/*
* Hardware interrupt masks
*/
-#define splbio() splraise(IPL_BIO)
-#define splnet() splraise(IPL_NET)
-#define spltty() splraise(IPL_TTY)
-#define splaudio() splraise(IPL_AUDIO)
-#define splclock() splraise(IPL_CLOCK)
+#define splbio() splraise(imask[IPL_BIO])
+#define splnet() splraise(imask[IPL_NET])
+#define spltty() splraise(imask[IPL_TTY])
+#define splaudio() splraise(imask[IPL_AUDIO])
+#define splclock() splraise(imask[IPL_CLOCK])
#define splstatclock() splhigh()
/*
@@ -168,18 +132,18 @@ spllower(ncpl)
* NOTE: spllowersoftclock() is used by hardclock() to lower the priority from
* clock to softclock before it calls softclock().
*/
-#define spllowersoftclock() spllower(IPL_SOFTCLOCK)
-#define splsoftclock() splraise(IPL_SOFTCLOCK)
-#define splsoftnet() splraise(IPL_SOFTNET)
-#define splsofttty() splraise(IPL_SOFTTTY)
+#define spllowersoftclock() spllower(SIR_CLOCKMASK)
+#define splsoftclock() splraise(SIR_CLOCKMASK)
+#define splsoftnet() splraise(SIR_NETMASK)
+#define splsofttty() splraise(SIR_TTYMASK)
/*
* Miscellaneous
*/
-#define splimp() splraise(IPL_IMP)
-#define splvm() splraise(IPL_IMP)
-#define splhigh() splraise(IPL_HIGH)
-#define spl0() spllower(IPL_NONE)
+#define splimp() splraise(imask[IPL_IMP])
+#define splvm() splraise(imask[IPL_IMP])
+#define splhigh() splraise(imask[IPL_HIGH])
+#define spl0() spllower(0)
/*
* Software interrupt registration
@@ -190,6 +154,7 @@ static __inline void
softintr(mask)
register int mask;
{
+
__asm __volatile("orl %0,_ipending" : : "ir" (mask));
}
diff --git a/sys/arch/i386/isa/icu.h b/sys/arch/i386/isa/icu.h
index 5414eeaaf4a..231a4404cbc 100644
--- a/sys/arch/i386/isa/icu.h
+++ b/sys/arch/i386/isa/icu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: icu.h,v 1.5 2001/11/12 20:28:20 niklas Exp $ */
+/* $OpenBSD: icu.h,v 1.6 2001/11/18 20:46:49 aaron Exp $ */
/* $NetBSD: icu.h,v 1.19 1996/02/01 22:31:21 mycroft Exp $ */
/*-
@@ -65,9 +65,6 @@ 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 f348a10b0b9..8be1d64520b 100644
--- a/sys/arch/i386/isa/icu.s
+++ b/sys/arch/i386/isa/icu.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: icu.s,v 1.16 2001/11/12 20:28:20 niklas Exp $ */
+/* $OpenBSD: icu.s,v 1.17 2001/11/18 20:46:49 aaron 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 $IPL_HIGH,%eax
+ movl $-1,%eax
xchgl %eax,_C_LABEL(cpl)
ret
@@ -72,9 +72,8 @@ IDTVEC(spllower)
pushl %edi
movl _C_LABEL(cpl),%ebx # save priority
movl $1f,%esi # address to resume loop at
-1: movl %ebx,%eax # get cpl
- shrl $4,%eax # find its mask.
- movl _C_LABEL(iunmask)(,%eax,4),%eax
+1: movl %ebx,%eax
+ notl %eax
andl _C_LABEL(ipending),%eax
jz 2f
bsfl %eax,%eax
@@ -98,9 +97,8 @@ IDTVEC(doreti)
popl %ebx # get previous priority
movl %ebx,_C_LABEL(cpl)
movl $1f,%esi # address to resume loop at
-1: movl %ebx,%eax # get cpl
- shrl $4,%eax # find its mask
- movl _C_LABEL(iunmask)(,%eax,4),%eax
+1: movl %ebx,%eax
+ notl %eax
andl _C_LABEL(ipending),%eax
jz 2f
bsfl %eax,%eax # slow, but not worth optimizing
@@ -134,7 +132,7 @@ IDTVEC(doreti)
IDTVEC(softtty)
#if NPCCOM > 0
- movl $IPL_SOFTTTY,%eax
+ leal SIR_TTYMASK(%ebx),%eax
movl %eax,_C_LABEL(cpl)
call _C_LABEL(comsoft)
movl %ebx,_C_LABEL(cpl)
@@ -149,7 +147,7 @@ IDTVEC(softtty)
1:
IDTVEC(softnet)
- movl $IPL_SOFTNET,%eax
+ leal SIR_NETMASK(%ebx),%eax
movl %eax,_C_LABEL(cpl)
xorl %edi,%edi
xchgl _C_LABEL(netisr),%edi
@@ -159,7 +157,7 @@ IDTVEC(softnet)
#undef DONETISR
IDTVEC(softclock)
- movl $IPL_SOFTCLOCK,%eax
+ leal SIR_CLOCKMASK(%ebx),%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 b57340a2977..19d352fe8ad 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.41 2001/11/12 20:28:20 niklas Exp $ */
+/* $OpenBSD: isa_machdep.c,v 1.42 2001/11/18 20:46:49 aaron Exp $ */
/* $NetBSD: isa_machdep.c,v 1.22 1997/06/12 23:57:32 thorpej Exp $ */
#define ISA_DMA_STATS
@@ -129,7 +129,6 @@
#define _I386_BUS_DMA_PRIVATE
#include <machine/bus.h>
-#include <machine/intr.h>
#include <machine/pio.h>
#include <machine/cpufunc.h>
@@ -222,8 +221,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 */
@@ -261,13 +260,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];
-
+u_long intrstray[ICU_LEN] = {0};
/*
* Caught a stray interrupt, notify
*/
@@ -288,7 +287,6 @@ isa_strayintr(irq)
int fastvec;
int intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN];
-int ilevel[ICU_LEN];
struct intrhand *intrhand[ICU_LEN];
/*
@@ -307,45 +305,45 @@ intr_calculatemasks()
for (irq = 0; irq < ICU_LEN; irq++) {
register int levels = 0;
for (q = intrhand[irq]; q; q = q->ih_next)
- levels |= 1 << IPL(q->ih_level);
+ levels |= 1 << q->ih_level;
intrlevel[irq] = levels;
}
/* Then figure out which IRQs use each level. */
- for (level = 0; level < NIPL; level++) {
+ for (level = 0; level < 5; level++) {
register int irqs = 0;
for (irq = 0; irq < ICU_LEN; irq++)
if (intrlevel[irq] & (1 << level))
irqs |= 1 << irq;
- imask[level] = irqs;
+ imask[level] = irqs | SIR_ALLMASK;
}
/*
- * Initialize soft interrupt masks to block themselves.
+ * There are tty, network and disk drivers that use free() at interrupt
+ * time, so imp > (tty | net | bio).
*/
- IMASK(IPL_SOFTCLOCK) |= 1 << SIR_CLOCK;
- IMASK(IPL_SOFTNET) |= 1 << SIR_NET;
- IMASK(IPL_SOFTTTY) |= 1 << SIR_TTY;
+ imask[IPL_IMP] |= imask[IPL_TTY] | imask[IPL_NET] | imask[IPL_BIO];
+ imask[IPL_AUDIO] |= imask[IPL_IMP];
/*
* Enforce a hierarchy that gives slow devices a better chance at not
* dropping data.
*/
- for (level = 0; level < NIPL - 1; level++)
- imask[level + 1] |= imask[level];
+ 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;
/* And eventually calculate the complete masks. */
for (irq = 0; irq < ICU_LEN; irq++) {
register int irqs = 1 << irq;
- int level = IPL_NONE;
-
- for (q = intrhand[irq]; q; q = q->ih_next) {
- irqs |= IMASK(q->ih_level);
- if (q->ih_level > level)
- level = q->ih_level;
- }
- intrmask[irq] = irqs;
- ilevel[irq] = level;
+ for (q = intrhand[irq]; q; q = q->ih_next)
+ irqs |= imask[q->ih_level];
+ intrmask[irq] = irqs | SIR_ALLMASK;
}
/* Lastly, determine which IRQs are actually in use. */
@@ -359,16 +357,13 @@ 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 fe04652777f..04fb03b0533 100644
--- a/sys/arch/i386/isa/npx.c
+++ b/sys/arch/i386/isa/npx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: npx.c,v 1.21 2001/11/12 20:28:20 niklas Exp $ */
+/* $OpenBSD: npx.c,v 1.22 2001/11/18 20:46:49 aaron 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 != IPL_NONE || npx_nointr != 0)
+ if (cpl != 0 || npx_nointr != 0)
panic("npxdna: masked");
#endif
@@ -612,7 +612,7 @@ npxsave()
{
#ifdef DIAGNOSTIC
- if (cpl != IPL_NONE || npx_nointr != 0)
+ if (cpl != 0 || 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 61c78232624..664477530e9 100644
--- a/sys/arch/i386/isa/vector.s
+++ b/sys/arch/i386/isa/vector.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: vector.s,v 1.12 2001/11/12 20:28:20 niklas Exp $ */
+/* $OpenBSD: vector.s,v 1.13 2001/11/18 20:46:49 aaron Exp $ */
/* $NetBSD: vector.s,v 1.32 1996/01/07 21:29:47 mycroft Exp $ */
/*
@@ -218,15 +218,13 @@ _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 */ ;\
- movl _C_LABEL(ilevel) + (irq_num) * 4, %eax ;\
- movzbl _C_LABEL(cpl),%ebx ;\
- cmpl %eax,%ebx ;\
- jae _C_LABEL(Xhold/**/irq_num)/* currently masked; hold it */;\
+ testb $IRQ_BIT(irq_num),_cpl + IRQ_BYTE(irq_num) ;\
+ jnz _Xhold/**/irq_num /* currently masked; hold it */ ;\
_Xresume/**/irq_num/**/: ;\
- movzbl _C_LABEL(cpl),%eax /* cpl to restore on exit */ ;\
+ movl _cpl,%eax /* cpl to restore on exit */ ;\
pushl %eax ;\
- movl _C_LABEL(ilevel) + (irq_num) * 4,%eax ;\
- movl %eax,_C_LABEL(cpl) /* block enough for this irq */ ;\
+ orl _intrmask + (irq_num) * 4,%eax ;\
+ movl %eax,_cpl /* add in this intr's mask */ ;\
sti /* safe to take intrs now */ ;\
movl _intrhand + (irq_num) * 4,%ebx /* head of chain */ ;\
testl %ebx,%ebx ;\