from netbsd:
authorderaadt <deraadt@openbsd.org>
Mon, 8 Jan 1996 09:33:31 +0000 (09:33 +0000)
committerderaadt <deraadt@openbsd.org>
Mon, 8 Jan 1996 09:33:31 +0000 (09:33 +0000)
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: ----------------------------------------------------------------------

sys/arch/i386/i386/locore.s
sys/arch/i386/include/psl.h
sys/arch/i386/isa/icu.h
sys/arch/i386/isa/icu.s
sys/arch/i386/isa/vector.s

index 9b2bdc2..3fe7773 100644 (file)
@@ -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
        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
index 4160fe8..5274789 100644 (file)
@@ -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.
 
 #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
index d9a7e14..b2cc506 100644 (file)
@@ -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.
  */
 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 */
 
index 1f5de65..b6ffcd1 100644 (file)
@@ -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
index 0558ebb..01acbfb 100644 (file)
@@ -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.
  * 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                                          ;\
@@ -283,42 +288,6 @@ INTR(13, IO_ICU2, ENABLE_ICU1_AND_2)
 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.
  */
@@ -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)