diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-01-08 09:33:50 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-01-08 09:33:50 +0000 |
commit | 5d56227f9458a53138642c1b4488b4a30f85f334 (patch) | |
tree | d1a7d0f08cc78e3ee4fe82c64e2801789d7ac09e /sys/arch | |
parent | 6c52914c1f14b56640f7bcde297a4d85330779a4 (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')
-rw-r--r-- | sys/arch/i386/i386/locore.s | 8 | ||||
-rw-r--r-- | sys/arch/i386/include/psl.h | 41 | ||||
-rw-r--r-- | sys/arch/i386/isa/icu.h | 16 | ||||
-rw-r--r-- | sys/arch/i386/isa/icu.s | 4 | ||||
-rw-r--r-- | sys/arch/i386/isa/vector.s | 53 |
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) |