summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1996-01-08 09:33:50 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1996-01-08 09:33:50 +0000
commit5d56227f9458a53138642c1b4488b4a30f85f334 (patch)
treed1a7d0f08cc78e3ee4fe82c64e2801789d7ac09e /sys/arch/i386
parent6c52914c1f14b56640f7bcde297a4d85330779a4 (diff)
from netbsd:
Deal with GCC's dead code elimination being suboptimal. Modify splraise() to allow better optimization. Make cpl, ipending, and astpending volatile. Make sure interrupts are disabled before jumping to a resume point, to prevent races. Make FPU faults use INTRFASTEXIT, and remove INTREXIT. Build the frame for recursive interrupts manually, and make sure to disable interrupts to avoid races. VS: ----------------------------------------------------------------------
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/i386/locore.s8
-rw-r--r--sys/arch/i386/include/psl.h41
-rw-r--r--sys/arch/i386/isa/icu.h16
-rw-r--r--sys/arch/i386/isa/icu.s4
-rw-r--r--sys/arch/i386/isa/vector.s53
5 files changed, 45 insertions, 77 deletions
diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s
index 9b2bdc25188..3fe77734a0e 100644
--- a/sys/arch/i386/i386/locore.s
+++ b/sys/arch/i386/i386/locore.s
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.s,v 1.139.2.1 1995/10/24 16:32:42 mycroft Exp $ */
+/* $NetBSD: locore.s,v 1.142 1996/01/07 03:59:28 mycroft Exp $ */
#undef DIAGNOSTIC
#define DIAGNOSTIC
@@ -101,8 +101,6 @@
movl $GSEL(GDATA_SEL, SEL_KPL),%eax ; \
movl %ax,%ds ; \
movl %ax,%es
-#define INTREXIT \
- jmp _Xdoreti
#define INTRFASTEXIT \
popl %es ; \
popl %ds ; \
@@ -1530,7 +1528,7 @@ ENTRY(cpu_switch)
movl $0,_curproc
movl $0,_cpl # spl0()
- call _spllower # process pending interrupts
+ call _Xspllower # process pending interrupts
switch_search:
/*
@@ -1877,7 +1875,7 @@ IDTVEC(fpu)
incl _cnt+V_TRAP
call _npxintr
addl $4,%esp
- INTREXIT
+ INTRFASTEXIT
#else
ZTRAP(T_ARITHTRAP)
#endif
diff --git a/sys/arch/i386/include/psl.h b/sys/arch/i386/include/psl.h
index 4160fe81f04..52747892ae2 100644
--- a/sys/arch/i386/include/psl.h
+++ b/sys/arch/i386/include/psl.h
@@ -1,4 +1,4 @@
-/* $NetBSD: psl.h,v 1.22 1995/10/11 04:20:23 mycroft Exp $ */
+/* $NetBSD: psl.h,v 1.25 1996/01/07 03:59:32 mycroft Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -99,7 +99,10 @@
#ifndef LOCORE
-int cpl, ipending, astpending, imask[5];
+volatile int cpl, ipending, astpending;
+int imask[5];
+
+extern void Xspllower __P((void));
/*
* Add a mask to cpl, and return the old value of cpl.
@@ -109,28 +112,38 @@ splraise(ncpl)
register int ncpl;
{
register int ocpl = cpl;
- cpl |= ncpl;
+
+ cpl = ocpl | ncpl;
return (ocpl);
}
-extern void spllower __P((void));
-
/*
* Restore a value to cpl (unmasking interrupts). If any unmasked
- * interrupts are pending, call spllower() to process them.
- *
- * NOTE: We go to the trouble of returning the old value of cpl for
- * the benefit of some splsoftclock() callers. This extra work is
- * usually optimized away by the compiler.
+ * interrupts are pending, call Xspllower() to process them.
*/
-static __inline int
+static __inline void
splx(ncpl)
register int ncpl;
{
+
+ cpl = ncpl;
+ if (ipending & ~ncpl)
+ Xspllower();
+}
+
+/*
+ * Same as splx(), but we return the old value of spl, for the
+ * benefit of some splsoftclock() callers.
+ */
+static __inline int
+spllower(ncpl)
+ register int ncpl;
+{
register int ocpl = cpl;
+
cpl = ncpl;
if (ipending & ~ncpl)
- spllower();
+ Xspllower();
return (ocpl);
}
@@ -150,7 +163,7 @@ splx(ncpl)
* NOTE: splsoftclock() is used by hardclock() to lower the priority from
* clock to softclock before it calls softclock().
*/
-#define splsoftclock() splx(SIR_CLOCKMASK)
+#define splsoftclock() spllower(SIR_CLOCKMASK)
#define splsoftnet() splraise(SIR_NETMASK)
#define splsofttty() splraise(SIR_TTYMASK)
@@ -158,7 +171,7 @@ splx(ncpl)
* Miscellaneous
*/
#define splhigh() splraise(-1)
-#define spl0() splx(0)
+#define spl0() spllower(0)
/*
* Software interrupt registration
diff --git a/sys/arch/i386/isa/icu.h b/sys/arch/i386/isa/icu.h
index d9a7e144d28..b2cc5068c34 100644
--- a/sys/arch/i386/isa/icu.h
+++ b/sys/arch/i386/isa/icu.h
@@ -1,4 +1,4 @@
-/* $NetBSD: icu.h,v 1.17 1994/11/04 19:13:49 mycroft Exp $ */
+/* $NetBSD: icu.h,v 1.18 1996/01/07 02:03:20 mycroft Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -53,19 +53,7 @@
*/
extern unsigned imen; /* interrupt mask enable */
-#define INTRUNMASK(msk,s) (msk &= ~(s))
-#define INTREN(s) (INTRUNMASK(imen, s), SET_ICUS())
-#define INTRMASK(msk,s) (msk |= (s))
-#define INTRDIS(s) (INTRMASK(imen, s), SET_ICUS())
-#if 0
-#define SET_ICUS() (outb(IO_ICU1 + 1, imen), outb(IU_ICU2 + 1, imen >> 8))
-#else
-/*
- * XXX - IO_ICU* are defined in isa.h, not icu.h, and nothing much bothers to
- * include isa.h, while too many things include icu.h.
- */
-#define SET_ICUS() (outb(0x21, imen), outb(0xa1, imen >> 8))
-#endif
+#define SET_ICUS() (outb(IO_ICU1 + 1, imen), outb(IO_ICU2 + 1, imen >> 8))
#endif /* !LOCORE */
diff --git a/sys/arch/i386/isa/icu.s b/sys/arch/i386/isa/icu.s
index 1f5de650230..b6ffcd13c79 100644
--- a/sys/arch/i386/isa/icu.s
+++ b/sys/arch/i386/isa/icu.s
@@ -1,4 +1,4 @@
-/* $NetBSD: icu.s,v 1.43 1995/10/11 04:20:31 mycroft Exp $ */
+/* $NetBSD: icu.s,v 1.45 1996/01/07 03:59:34 mycroft Exp $ */
/*-
* Copyright (c) 1993, 1994, 1995 Charles M. Hannum. All rights reserved.
@@ -64,7 +64,6 @@ _splx:
* esi - address to resume loop at
* edi - scratch for Xsoftnet
*/
-ENTRY(spllower)
IDTVEC(spllower)
pushl %ebx
pushl %esi
@@ -103,6 +102,7 @@ IDTVEC(doreti)
bsfl %eax,%eax # slow, but not worth optimizing
btrl %eax,_ipending
jnc 1b # some intr cleared the in-memory bit
+ cli
jmp *_Xresume(,%eax,4)
2: /* Check for ASTs on exit to user mode. */
cli
diff --git a/sys/arch/i386/isa/vector.s b/sys/arch/i386/isa/vector.s
index 0558ebbde2b..01acbfbe80d 100644
--- a/sys/arch/i386/isa/vector.s
+++ b/sys/arch/i386/isa/vector.s
@@ -1,4 +1,4 @@
-/* $NetBSD: vector.s,v 1.29 1995/05/08 18:00:20 mycroft Exp $ */
+/* $NetBSD: vector.s,v 1.31 1996/01/07 03:59:35 mycroft Exp $ */
/*
* Copyright (c) 1993, 1994, 1995 Charles M. Hannum. All rights reserved.
@@ -111,7 +111,7 @@
* XXX
* The interrupt frame is set up to look like a trap frame. This may be a
* waste. The only handler which needs a frame is the clock handler, and it
- * only needs a few bits. doreti() needs a trap frame for handling ASTs, but
+ * only needs a few bits. Xdoreti() needs a trap frame for handling ASTs, but
* it could easily convert the frame on demand.
*
* The direct costs of setting up a trap frame are two pushl's (error code and
@@ -199,10 +199,15 @@ FAST(15, IO_ICU2, ENABLE_ICU1_AND_2)
* interrupt. On a system with level-triggered interrupts, we could terminate
* immediately when one of them returns 1; but this is a PC.
*
- * On exit, we jump to doreti, to process soft interrupts and ASTs.
+ * On exit, we jump to Xdoreti(), to process soft interrupts and ASTs.
*/
#define INTR(irq_num, icu, enable_icus) \
-IDTVEC(intr/**/irq_num) ;\
+IDTVEC(recurse/**/irq_num) ;\
+ pushfl ;\
+ pushl %cs ;\
+ pushl %esi ;\
+ cli ;\
+_Xintr/**/irq_num/**/: ;\
pushl $0 /* dummy error code */ ;\
pushl $T_ASTFLT /* trap # for doing ASTs */ ;\
INTRENTRY ;\
@@ -235,7 +240,7 @@ _Xresume/**/irq_num/**/: ;\
jnz 7b ;\
STRAY_TEST /* see if it's a stray */ ;\
5: UNMASK(irq_num, icu) /* unmask it in hardware */ ;\
- INTREXIT /* lower spl and do ASTs */ ;\
+ jmp _Xdoreti /* lower spl and do ASTs */ ;\
IDTVEC(stray/**/irq_num) ;\
pushl $irq_num ;\
call _isa_strayintr ;\
@@ -284,42 +289,6 @@ INTR(14, IO_ICU2, ENABLE_ICU1_AND_2)
INTR(15, IO_ICU2, ENABLE_ICU1_AND_2)
/*
- * Recursive interrupts.
- *
- * This is a somewhat nasty hack to deal with resuming interrupts from splx().
- * We can't just jump to the resume point, because some handlers require an
- * interrupt frame. Instead, we just recursively interrupt.
- *
- * On entry, %esi contains a pointer to where we need to return. This is a
- * bit faster than a call/ret/jmp to continue the loop.
- *
- * XXX
- * It might be a little faster to build the interrupt frame manually and jump
- * to the resume point. The code would be larger, though.
- */
-#define RECURSE(irq_num) \
-IDTVEC(recurse/**/irq_num) ;\
- int $(ICU_OFFSET + irq_num) ;\
- jmp %esi
-
-RECURSE(0)
-RECURSE(1)
-RECURSE(2)
-RECURSE(3)
-RECURSE(4)
-RECURSE(5)
-RECURSE(6)
-RECURSE(7)
-RECURSE(8)
-RECURSE(9)
-RECURSE(10)
-RECURSE(11)
-RECURSE(12)
-RECURSE(13)
-RECURSE(14)
-RECURSE(15)
-
-/*
* These tables are used by the ISA configuration code.
*/
/* interrupt service routine entry points */
@@ -334,7 +303,7 @@ IDTVEC(fast)
.long _Xfast13, _Xfast14, _Xfast15
/*
- * These tables are used by doreti() and spllower().
+ * These tables are used by Xdoreti() and Xspllower().
*/
/* resume points for suspended interrupts */
IDTVEC(resume)