Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/sommerfeld_i386mp_1]: src/sys/arch/i386/include MP: MP-safe and APIC-fri...



details:   https://anonhg.NetBSD.org/src/rev/28e623c05299
branches:  sommerfeld_i386mp_1
changeset: 482160:28e623c05299
user:      sommerfeld <sommerfeld%NetBSD.org@localhost>
date:      Sun Feb 20 17:41:33 2000 +0000

description:
MP: MP-safe and APIC-friendly spl*/splx() implementation.

Keep spl state as a level, rather than interrupt mask, since on
multiple APIC systems there may be more interrupt lines than can fit
in a single 32-bit word.

Interrupt levels are now compatible with the APIC priority scheme
(high order 4 bits of the IDT vector number).

diffstat:

 sys/arch/i386/include/intr.h |  144 +++++++++++++++++++++++++++++-------------
 1 files changed, 99 insertions(+), 45 deletions(-)

diffs (224 lines):

diff -r b26cd01084d4 -r 28e623c05299 sys/arch/i386/include/intr.h
--- a/sys/arch/i386/include/intr.h      Sun Feb 20 17:38:09 2000 +0000
+++ b/sys/arch/i386/include/intr.h      Sun Feb 20 17:41:33 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: intr.h,v 1.12 1999/08/05 18:08:10 thorpej Exp $        */
+/*     $NetBSD: intr.h,v 1.12.10.1 2000/02/20 17:41:33 sommerfeld Exp $        */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -39,20 +39,33 @@
 #ifndef _I386_INTR_H_
 #define _I386_INTR_H_
 
-/* Interrupt priority `levels'. */
-#define        IPL_NONE        9       /* nothing */
-#define        IPL_SOFTCLOCK   8       /* timeouts */
-#define        IPL_SOFTNET     7       /* protocol stacks */
-#define        IPL_BIO         6       /* block I/O */
-#define        IPL_NET         5       /* network */
-#define        IPL_SOFTSERIAL  4       /* serial */
-#define        IPL_TTY         3       /* terminal */
-#define        IPL_IMP         3       /* memory allocation */
-#define        IPL_AUDIO       2       /* audio */
-#define        IPL_CLOCK       1       /* clock */
-#define        IPL_HIGH        1       /* everything */
-#define        IPL_SERIAL      0       /* serial */
-#define        NIPL            10
+/*
+ * Interrupt priority levels.
+ * 
+ * There are tty, network and disk drivers that use free() at interrupt
+ * time, so imp > (tty | net | bio).
+ *
+ * Since run queues may be manipulated by both the statclock and tty,
+ * network, and disk drivers, clock > imp.
+ *
+ * IPL_HIGH must block everything that can manipulate a run queue.
+ *
+ * We need serial drivers to run at the absolute highest priority to
+ * avoid overruns, so serial > high.
+ */
+#define        IPL_NONE        0x00    /* nothing */
+#define        IPL_SOFTCLOCK   0x50    /* timeouts */
+#define        IPL_SOFTNET     0x60    /* protocol stacks */
+#define        IPL_BIO         0x70    /* block I/O */
+#define        IPL_NET         0x80    /* network */
+#define        IPL_SOFTSERIAL  0x90    /* serial */
+#define        IPL_TTY         0xa0    /* terminal */
+#define        IPL_IMP         0xb0    /* memory allocation */
+#define        IPL_AUDIO       0xc0    /* audio */
+#define        IPL_CLOCK       0xd0    /* clock */
+#define        IPL_HIGH        0xd0    /* everything */
+#define        IPL_SERIAL      0xe0    /* serial */
+#define        NIPL            16
 
 /* Interrupt sharing types. */
 #define        IST_NONE        0       /* none */
@@ -67,15 +80,31 @@
 
 #ifndef _LOCORE
 
-volatile int cpl, ipending, astpending;
-int imask[NIPL];
+#ifdef MULTIPROCESSOR
+#include <machine/i82489reg.h>
+#include <machine/i82489var.h>
+#endif
+
+extern volatile u_int32_t lapic_tpr;
+volatile u_int32_t ipending;
+
+#ifndef MULTIPROCESSOR
+volatile u_int32_t astpending;
+#endif
+
+int imasks[NIPL];
+int iunmask[NIPL];
+
+#define CPSHIFT 4
+#define IMASK(level) imasks[(level)>>CPSHIFT]
+#define IUNMASK(level) iunmask[(level)>>CPSHIFT]
 
 extern void Xspllower __P((void));
 
 static __inline int splraise __P((int));
 static __inline int spllower __P((int));
 static __inline void splx __P((int));
-static __inline void softintr __P((int));
+static __inline void softintr __P((int, int));
 
 /*
  * Add a mask to cpl, and return the old value of cpl.
@@ -84,9 +113,10 @@
 splraise(ncpl)
        register int ncpl;
 {
-       register int ocpl = cpl;
+       register int ocpl = lapic_tpr;
 
-       cpl = ocpl | ncpl;
+       if (ncpl > ocpl)
+               lapic_tpr = ncpl;
        return (ocpl);
 }
 
@@ -98,9 +128,11 @@
 splx(ncpl)
        register int ncpl;
 {
+       register int cmask;
 
-       cpl = ncpl;
-       if (ipending & ~ncpl)
+       lapic_tpr = ncpl;
+       cmask = IUNMASK(ncpl);
+       if (ipending & cmask)
                Xspllower();
 }
 
@@ -112,10 +144,12 @@
 spllower(ncpl)
        register int ncpl;
 {
-       register int ocpl = cpl;
-
-       cpl = ncpl;
-       if (ipending & ~ncpl)
+       register int ocpl = lapic_tpr;
+       register int cmask;
+       
+       lapic_tpr = ncpl;
+       cmask = IUNMASK(ncpl);
+       if (ipending & cmask)
                Xspllower();
        return (ocpl);
 }
@@ -123,13 +157,13 @@
 /*
  * Hardware interrupt masks
  */
-#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        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        splstatclock()  splclock()
-#define        splserial()     splraise(imask[IPL_SERIAL])
+#define        splserial()     splraise(IPL_SERIAL)
 
 #define spllpt()       spltty()
 
@@ -139,17 +173,18 @@
  * NOTE: splsoftclock() is used by hardclock() to lower the priority from
  * clock to softclock before it calls softclock().
  */
-#define        spllowersoftclock() spllower(imask[IPL_SOFTCLOCK])
-#define        splsoftclock()  splraise(imask[IPL_SOFTCLOCK])
-#define        splsoftnet()    splraise(imask[IPL_SOFTNET])
-#define        splsoftserial() splraise(imask[IPL_SOFTSERIAL])
+#define        spllowersoftclock() spllower(IPL_SOFTCLOCK)
+
+#define        splsoftclock()  splraise(IPL_SOFTCLOCK)
+#define        splsoftnet()    splraise(IPL_SOFTNET)
+#define        splsoftserial() splraise(IPL_SOFTSERIAL)
 
 /*
  * Miscellaneous
  */
-#define        splimp()        splraise(imask[IPL_IMP])
-#define        splhigh()       splraise(imask[IPL_HIGH])
-#define        spl0()          spllower(0)
+#define        splimp()        splraise(IPL_IMP)
+#define        splhigh()       splraise(IPL_HIGH)
+#define        spl0()          spllower(IPL_NONE)
 
 /*
  * Software interrupt registration
@@ -157,16 +192,35 @@
  * We hand-code this to ensure that it's atomic.
  */
 static __inline void
-softintr(mask)
-       register int mask;
+softintr(sir, vec)
+       register int sir;
+       register int vec;
 {
-       __asm __volatile("orl %1, %0" : "=m"(ipending) : "ir" (1 << mask));
+       __asm __volatile("orl %1, %0" : "=m"(ipending) : "ir" (1 << sir));
+#ifdef MULTIPROCESSOR
+       i82489_writereg(LAPIC_ICRLO,
+           vec | LAPIC_DLMODE_FIXED | LAPIC_LVL_ASSERT | LAPIC_DEST_SELF);
+#endif
 }
 
 #define        setsoftast()    (astpending = 1)
-#define        setsoftclock()  softintr(SIR_CLOCK)
-#define        setsoftnet()    softintr(SIR_NET)
-#define        setsoftserial() softintr(SIR_SERIAL)
+#define        setsoftclock()  softintr(SIR_CLOCK,IPL_SOFTCLOCK)
+#define        setsoftnet()    softintr(SIR_NET,IPL_SOFTNET)
+#define        setsoftserial() softintr(SIR_SERIAL,IPL_SOFTSERIAL)
+
+
+#define I386_IPI_HALT          0x00000001
+#define I386_IPI_TLB           0x00000002
+
+/* the following are for debugging.. */
+#define I386_IPI_GMTB          0x00000010
+#define I386_IPI_NYCHI         0x00000020
+
+#define I386_NIPI              6
+
+void i386_send_ipi (int, int);
+void i386_broadcast_ipi (int);
+void i386_ipi_handler (void);
 
 #endif /* !_LOCORE */
 



Home | Main Index | Thread Index | Old Index