diff options
author | fsmp <fsmp@FreeBSD.org> | 1997-08-30 08:08:10 +0000 |
---|---|---|
committer | fsmp <fsmp@FreeBSD.org> | 1997-08-30 08:08:10 +0000 |
commit | e2310cdbcf324f3bbeda76add82e773d37ee43cd (patch) | |
tree | ab2ac308116ca3f26a9055eae17d100d5901e501 /sys | |
parent | 62dbf14e9ad4dbe9bc03c2657d854b47ef4b3f65 (diff) | |
download | FreeBSD-src-e2310cdbcf324f3bbeda76add82e773d37ee43cd.zip FreeBSD-src-e2310cdbcf324f3bbeda76add82e773d37ee43cd.tar.gz |
Another round of lock pushdown.
Add a simplelock to deal with disable_intr()/enable_intr() as used in UP kernel.
UP kernel expects that this is enough to guarantee exclusive access to
regions of code bracketed by these 2 functions.
Add a simplelock to bracket clock accesses in clock.c: clock_lock.
Help from: Bruce Evans <bde@zeta.org.au>
Diffstat (limited to 'sys')
39 files changed, 824 insertions, 567 deletions
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index d78d320..0652b69 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.32 1997/08/29 18:37:23 smp Exp smp $ + * $Id: apic_vector.s,v 1.33 1997/08/30 01:23:40 smp Exp smp $ */ @@ -75,9 +75,10 @@ IDTVEC(vec_name) ; \ movl %ax,%ds ; \ MAYBE_MOVW_AX_ES ; \ FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ - GET_FAST_INTR_LOCK ; \ pushl _intr_unit + (irq_num) * 4 ; \ + GET_FAST_INTR_LOCK ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ + REL_FAST_INTR_LOCK ; \ addl $4, %esp ; \ movl $0, lapic_eoi ; \ lock ; \ @@ -86,7 +87,6 @@ IDTVEC(vec_name) ; \ lock ; \ incl (%eax) ; \ MEXITCOUNT ; \ - REL_FAST_INTR_LOCK ; \ MAYBE_POPL_ES ; \ popl %ds ; \ popl %edx ; \ diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S index f072e7a..9a74ca1 100644 --- a/sys/amd64/amd64/exception.S +++ b/sys/amd64/amd64/exception.S @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.19 1997/08/28 09:50:41 smp Exp smp $ + * $Id: exception.s,v 1.42 1997/08/29 18:16:17 fsmp Exp $ */ #include "npx.h" /* NNPX */ @@ -38,9 +38,9 @@ #include <machine/ipl.h> /* SWI_AST_MASK ... */ #include <machine/psl.h> /* PSL_I */ #include <machine/trap.h> /* trap codes */ -#include <machine/asmacros.h> /* miscellaneous macros */ -#include <machine/param.h> +#include <machine/asmacros.h> #include <machine/smptests.h> /* INTR_SIMPLELOCK */ +#include <machine/lock.h> #ifndef SMP #undef INTR_SIMPLELOCK /* simplifies cpp tests */ diff --git a/sys/amd64/amd64/exception.s b/sys/amd64/amd64/exception.s index f072e7a..9a74ca1 100644 --- a/sys/amd64/amd64/exception.s +++ b/sys/amd64/amd64/exception.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.19 1997/08/28 09:50:41 smp Exp smp $ + * $Id: exception.s,v 1.42 1997/08/29 18:16:17 fsmp Exp $ */ #include "npx.h" /* NNPX */ @@ -38,9 +38,9 @@ #include <machine/ipl.h> /* SWI_AST_MASK ... */ #include <machine/psl.h> /* PSL_I */ #include <machine/trap.h> /* trap codes */ -#include <machine/asmacros.h> /* miscellaneous macros */ -#include <machine/param.h> +#include <machine/asmacros.h> #include <machine/smptests.h> /* INTR_SIMPLELOCK */ +#include <machine/lock.h> #ifndef SMP #undef INTR_SIMPLELOCK /* simplifies cpp tests */ diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index d5ea71c..955a3a1 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.46 1997/08/26 18:10:31 peter Exp $ + * $Id: mp_machdep.c,v 1.32 1997/08/30 01:25:13 smp Exp smp $ */ #include "opt_smp.h" @@ -1446,8 +1446,16 @@ struct simplelock fast_intr_lock; /* critical region around INTR() routines */ struct simplelock intr_lock; +#ifdef SIMPLE_MPINTRLOCK +/* critical region around INTR() routines */ +struct simplelock mpintr_lock; +struct simplelock clock_lock; +#endif + +#if 0 /* lock the com (tty) data structures */ struct simplelock com_lock; +#endif static void init_locks(void) @@ -1459,7 +1467,13 @@ init_locks(void) mp_lock = 0x00000001; /* ISR uses its own "giant lock" */ - isr_lock = 0x00000000; + isr_lock = FREE_LOCK; + +#ifdef SIMPLE_MPINTRLOCK + /* lock regions protected in UP kernel via cli/sti */ + s_lock_init((struct simplelock*)&mpintr_lock); + s_lock_init((struct simplelock*)&clock_lock); +#endif /* serializes FAST_INTR() accesses */ s_lock_init((struct simplelock*)&fast_intr_lock); @@ -1470,11 +1484,13 @@ init_locks(void) /* locks the IO APIC and apic_imen accesses */ s_lock_init((struct simplelock*)&imen_lock); - /* locks cpl accesses */ + /* locks cpl/cml/cim/ipending accesses */ s_lock_init((struct simplelock*)&cpl_lock); +#if 0 /* locks com (tty) data/hardware accesses: a FASTINTR() */ s_lock_init((struct simplelock*)&com_lock); +#endif } diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c index d5ea71c..955a3a1 100644 --- a/sys/amd64/amd64/mptable.c +++ b/sys/amd64/amd64/mptable.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.46 1997/08/26 18:10:31 peter Exp $ + * $Id: mp_machdep.c,v 1.32 1997/08/30 01:25:13 smp Exp smp $ */ #include "opt_smp.h" @@ -1446,8 +1446,16 @@ struct simplelock fast_intr_lock; /* critical region around INTR() routines */ struct simplelock intr_lock; +#ifdef SIMPLE_MPINTRLOCK +/* critical region around INTR() routines */ +struct simplelock mpintr_lock; +struct simplelock clock_lock; +#endif + +#if 0 /* lock the com (tty) data structures */ struct simplelock com_lock; +#endif static void init_locks(void) @@ -1459,7 +1467,13 @@ init_locks(void) mp_lock = 0x00000001; /* ISR uses its own "giant lock" */ - isr_lock = 0x00000000; + isr_lock = FREE_LOCK; + +#ifdef SIMPLE_MPINTRLOCK + /* lock regions protected in UP kernel via cli/sti */ + s_lock_init((struct simplelock*)&mpintr_lock); + s_lock_init((struct simplelock*)&clock_lock); +#endif /* serializes FAST_INTR() accesses */ s_lock_init((struct simplelock*)&fast_intr_lock); @@ -1470,11 +1484,13 @@ init_locks(void) /* locks the IO APIC and apic_imen accesses */ s_lock_init((struct simplelock*)&imen_lock); - /* locks cpl accesses */ + /* locks cpl/cml/cim/ipending accesses */ s_lock_init((struct simplelock*)&cpl_lock); +#if 0 /* locks com (tty) data/hardware accesses: a FASTINTR() */ s_lock_init((struct simplelock*)&com_lock); +#endif } diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c index 28f6dc9..0755baf 100644 --- a/sys/amd64/amd64/tsc.c +++ b/sys/amd64/amd64/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.99 1997/08/21 05:08:07 fsmp Exp $ + * $Id: clock.c,v 1.10 1997/08/30 01:23:40 smp Exp smp $ */ /* @@ -65,9 +65,9 @@ #include <machine/frame.h> #include <machine/ipl.h> #include <machine/limits.h> -#ifdef APIC_IO +#if defined(SMP) || defined(APIC_IO) #include <machine/smp.h> -#endif /* APIC_IO */ +#endif /* SMP || APIC_IO */ #include <i386/isa/icu.h> #include <i386/isa/isa.h> @@ -77,6 +77,34 @@ #include <i386/isa/intr_machdep.h> #include <sys/interrupt.h> +#ifdef SMP +#include <machine/smptests.h> + +#ifdef SIMPLE_MPINTRLOCK +#define DISABLE_INTR() \ + __asm __volatile("cli" : : : "memory"); \ + s_lock(&clock_lock); + +#define ENABLE_INTR() \ + s_unlock(&clock_lock); \ + __asm __volatile("sti"); + +#define CLOCK_UNLOCK() \ + s_unlock(&clock_lock); +#else /* SIMPLE_MPINTRLOCK */ +#define DISABLE_INTR() disable_intr() +#define ENABLE_INTR() enable_intr() +#define CLOCK_UNLOCK() +#endif /* SIMPLE_MPINTRLOCK */ + +#else /* SMP */ + +#define DISABLE_INTR() disable_intr() +#define ENABLE_INTR() enable_intr() +#define CLOCK_UNLOCK() + +#endif /* SMP */ + /* * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we * can use a simple formula for leap years. @@ -183,11 +211,11 @@ clkintr(struct clockframe frame) timer0_max_count = TIMER_DIV(new_rate); timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; - disable_intr(); + DISABLE_INTR(); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - enable_intr(); + ENABLE_INTR(); timer0_prescaler_count = 0; timer_func = new_function; timer0_state = ACQUIRED; @@ -201,12 +229,12 @@ clkintr(struct clockframe frame) timer0_max_count = hardclock_max_count; timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; - disable_intr(); + DISABLE_INTR(); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - enable_intr(); + ENABLE_INTR(); /* * See microtime.s for this magic. */ @@ -358,7 +386,7 @@ getit(void) int high, low; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -366,6 +394,7 @@ getit(void) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); + CLOCK_UNLOCK(); write_eflags(ef); return ((high << 8) | low); } @@ -480,10 +509,10 @@ sysbeep(int pitch, int period) splx(x); return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ } - disable_intr(); + DISABLE_INTR(); outb(TIMER_CNTR2, pitch); outb(TIMER_CNTR2, (pitch>>8)); - enable_intr(); + ENABLE_INTR(); if (!beeping) { /* enable counter2 output to speaker */ outb(IO_PPI, inb(IO_PPI) | 3); @@ -626,13 +655,14 @@ set_timer_freq(u_int freq, int intr_freq) u_long ef; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); timer_freq = freq; timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); + CLOCK_UNLOCK(); write_eflags(ef); } @@ -1002,10 +1032,11 @@ set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq) << I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq; multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); i586_ctr_freq = i586_freq; i586_ctr_comultiplier = comultiplier; i586_ctr_multiplier = multiplier; + CLOCK_UNLOCK(); write_eflags(ef); } diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h index 41e1bd7..9fd475e 100644 --- a/sys/amd64/include/cpufunc.h +++ b/sys/amd64/include/cpufunc.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cpufunc.h,v 1.68 1997/05/31 09:13:03 peter Exp $ + * $Id: cpufunc.h,v 1.69 1997/07/17 04:33:46 dyson Exp $ */ /* @@ -43,6 +43,9 @@ #include <sys/cdefs.h> #include <sys/types.h> +#include <machine/lock.h> + + #ifdef __GNUC__ static __inline void @@ -55,11 +58,13 @@ static __inline void disable_intr(void) { __asm __volatile("cli" : : : "memory"); + MPINTR_LOCK(); } static __inline void enable_intr(void) { + MPINTR_UNLOCK(); __asm __volatile("sti"); } diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h index d5ea71c..955a3a1 100644 --- a/sys/amd64/include/mptable.h +++ b/sys/amd64/include/mptable.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.46 1997/08/26 18:10:31 peter Exp $ + * $Id: mp_machdep.c,v 1.32 1997/08/30 01:25:13 smp Exp smp $ */ #include "opt_smp.h" @@ -1446,8 +1446,16 @@ struct simplelock fast_intr_lock; /* critical region around INTR() routines */ struct simplelock intr_lock; +#ifdef SIMPLE_MPINTRLOCK +/* critical region around INTR() routines */ +struct simplelock mpintr_lock; +struct simplelock clock_lock; +#endif + +#if 0 /* lock the com (tty) data structures */ struct simplelock com_lock; +#endif static void init_locks(void) @@ -1459,7 +1467,13 @@ init_locks(void) mp_lock = 0x00000001; /* ISR uses its own "giant lock" */ - isr_lock = 0x00000000; + isr_lock = FREE_LOCK; + +#ifdef SIMPLE_MPINTRLOCK + /* lock regions protected in UP kernel via cli/sti */ + s_lock_init((struct simplelock*)&mpintr_lock); + s_lock_init((struct simplelock*)&clock_lock); +#endif /* serializes FAST_INTR() accesses */ s_lock_init((struct simplelock*)&fast_intr_lock); @@ -1470,11 +1484,13 @@ init_locks(void) /* locks the IO APIC and apic_imen accesses */ s_lock_init((struct simplelock*)&imen_lock); - /* locks cpl accesses */ + /* locks cpl/cml/cim/ipending accesses */ s_lock_init((struct simplelock*)&cpl_lock); +#if 0 /* locks com (tty) data/hardware accesses: a FASTINTR() */ s_lock_init((struct simplelock*)&com_lock); +#endif } diff --git a/sys/amd64/include/profile.h b/sys/amd64/include/profile.h index 50da5fe..d451245 100644 --- a/sys/amd64/include/profile.h +++ b/sys/amd64/include/profile.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)profile.h 8.1 (Berkeley) 6/11/93 - * $Id$ + * $Id: profile.h,v 1.11 1997/02/22 09:35:01 peter Exp $ */ #ifndef _MACHINE_PROFILE_H_ @@ -63,7 +63,11 @@ #else #define MCOUNT_DECL(s) u_long s; #define MCOUNT_ENTER(s) { s = read_eflags(); disable_intr(); } +#ifdef SMP +#define MCOUNT_EXIT(s) { MPINTR_UNLOCK(); write_eflags(s); } +#else #define MCOUNT_EXIT(s) (write_eflags(s)) +#endif #endif /* GUPROF */ #else /* !KERNEL */ diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index 276b838..a7051ff 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.29 1997/08/24 20:33:24 fsmp Exp $ + * $Id: smp.h,v 1.30 1997/08/26 18:10:37 peter Exp $ * */ @@ -60,11 +60,19 @@ void bootMP __P((void)); /* global data in mplock.s */ extern u_int mp_lock; extern u_int isr_lock; +#ifdef RECURSIVE_MPINTRLOCK +extern u_int mpintr_lock; +#endif /* RECURSIVE_MPINTRLOCK */ /* functions in mplock.s */ void get_mplock __P((void)); void rel_mplock __P((void)); void try_mplock __P((void)); +#ifdef RECURSIVE_MPINTRLOCK +void get_mpintrlock __P((void)); +void rel_mpintrlock __P((void)); +void try_mpintrlock __P((void)); +#endif /* RECURSIVE_MPINTRLOCK */ /* global data in apic_vector.s */ extern u_int ivectors[]; diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index 28f6dc9..0755baf 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.99 1997/08/21 05:08:07 fsmp Exp $ + * $Id: clock.c,v 1.10 1997/08/30 01:23:40 smp Exp smp $ */ /* @@ -65,9 +65,9 @@ #include <machine/frame.h> #include <machine/ipl.h> #include <machine/limits.h> -#ifdef APIC_IO +#if defined(SMP) || defined(APIC_IO) #include <machine/smp.h> -#endif /* APIC_IO */ +#endif /* SMP || APIC_IO */ #include <i386/isa/icu.h> #include <i386/isa/isa.h> @@ -77,6 +77,34 @@ #include <i386/isa/intr_machdep.h> #include <sys/interrupt.h> +#ifdef SMP +#include <machine/smptests.h> + +#ifdef SIMPLE_MPINTRLOCK +#define DISABLE_INTR() \ + __asm __volatile("cli" : : : "memory"); \ + s_lock(&clock_lock); + +#define ENABLE_INTR() \ + s_unlock(&clock_lock); \ + __asm __volatile("sti"); + +#define CLOCK_UNLOCK() \ + s_unlock(&clock_lock); +#else /* SIMPLE_MPINTRLOCK */ +#define DISABLE_INTR() disable_intr() +#define ENABLE_INTR() enable_intr() +#define CLOCK_UNLOCK() +#endif /* SIMPLE_MPINTRLOCK */ + +#else /* SMP */ + +#define DISABLE_INTR() disable_intr() +#define ENABLE_INTR() enable_intr() +#define CLOCK_UNLOCK() + +#endif /* SMP */ + /* * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we * can use a simple formula for leap years. @@ -183,11 +211,11 @@ clkintr(struct clockframe frame) timer0_max_count = TIMER_DIV(new_rate); timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; - disable_intr(); + DISABLE_INTR(); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - enable_intr(); + ENABLE_INTR(); timer0_prescaler_count = 0; timer_func = new_function; timer0_state = ACQUIRED; @@ -201,12 +229,12 @@ clkintr(struct clockframe frame) timer0_max_count = hardclock_max_count; timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; - disable_intr(); + DISABLE_INTR(); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - enable_intr(); + ENABLE_INTR(); /* * See microtime.s for this magic. */ @@ -358,7 +386,7 @@ getit(void) int high, low; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -366,6 +394,7 @@ getit(void) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); + CLOCK_UNLOCK(); write_eflags(ef); return ((high << 8) | low); } @@ -480,10 +509,10 @@ sysbeep(int pitch, int period) splx(x); return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ } - disable_intr(); + DISABLE_INTR(); outb(TIMER_CNTR2, pitch); outb(TIMER_CNTR2, (pitch>>8)); - enable_intr(); + ENABLE_INTR(); if (!beeping) { /* enable counter2 output to speaker */ outb(IO_PPI, inb(IO_PPI) | 3); @@ -626,13 +655,14 @@ set_timer_freq(u_int freq, int intr_freq) u_long ef; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); timer_freq = freq; timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); + CLOCK_UNLOCK(); write_eflags(ef); } @@ -1002,10 +1032,11 @@ set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq) << I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq; multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); i586_ctr_freq = i586_freq; i586_ctr_comultiplier = comultiplier; i586_ctr_multiplier = multiplier; + CLOCK_UNLOCK(); write_eflags(ef); } diff --git a/sys/amd64/isa/intr_machdep.c b/sys/amd64/isa/intr_machdep.c index c9b5da5..fd836dd 100644 --- a/sys/amd64/isa/intr_machdep.c +++ b/sys/amd64/isa/intr_machdep.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.1 1997/08/29 18:38:35 smp Exp smp $ + * $Id: intr_machdep.c,v 1.5 1997/08/29 18:45:19 fsmp Exp $ */ #include "opt_auto_eoi.h" @@ -451,6 +451,7 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ INTREN(1 << intr); + MPINTR_UNLOCK(); write_eflags(ef); return (0); } @@ -487,8 +488,15 @@ icu_unset(intr, handler) intr_mptr[intr] = NULL; intr_mask[intr] = HWI_MASK | SWI_MASK; intr_unit[intr] = intr; +#ifdef FAST_HI_XXX + /* XXX how do I re-create dvp here? */ + setidt(flags & INTR_FAST ? TPR_FAST_INTS + intr : TPR_SLOW_INTS + intr, + slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#else /* FAST_HI */ setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* FAST_HI */ + MPINTR_UNLOCK(); write_eflags(ef); return (0); } diff --git a/sys/amd64/isa/nmi.c b/sys/amd64/isa/nmi.c index c9b5da5..fd836dd 100644 --- a/sys/amd64/isa/nmi.c +++ b/sys/amd64/isa/nmi.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.1 1997/08/29 18:38:35 smp Exp smp $ + * $Id: intr_machdep.c,v 1.5 1997/08/29 18:45:19 fsmp Exp $ */ #include "opt_auto_eoi.h" @@ -451,6 +451,7 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ INTREN(1 << intr); + MPINTR_UNLOCK(); write_eflags(ef); return (0); } @@ -487,8 +488,15 @@ icu_unset(intr, handler) intr_mptr[intr] = NULL; intr_mask[intr] = HWI_MASK | SWI_MASK; intr_unit[intr] = intr; +#ifdef FAST_HI_XXX + /* XXX how do I re-create dvp here? */ + setidt(flags & INTR_FAST ? TPR_FAST_INTS + intr : TPR_SLOW_INTS + intr, + slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#else /* FAST_HI */ setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* FAST_HI */ + MPINTR_UNLOCK(); write_eflags(ef); return (0); } diff --git a/sys/dev/cy/cy.c b/sys/dev/cy/cy.c index 65647d3..62a3598 100644 --- a/sys/dev/cy/cy.c +++ b/sys/dev/cy/cy.c @@ -27,7 +27,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: cy.c,v 1.49 1997/08/20 06:16:44 fsmp Exp $ + * $Id: cy.c,v 1.4 1997/08/30 01:23:40 smp Exp smp $ */ #include "cy.h" @@ -756,26 +756,22 @@ open_top: } disable_intr(); - COM_LOCK(); (void) inb(com->line_status_port); (void) inb(com->data_port); com->prev_modem_status = com->last_modem_status = inb(com->modem_status_port); outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC); - COM_UNLOCK(); enable_intr(); #else /* !0 */ /* XXX raise RTS too */ (void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET); disable_intr(); - COM_LOCK(); com->prev_modem_status = com->last_modem_status = cd_inb(iobase, CD1400_MSVR2, com->cy_align); cd_outb(iobase, CD1400_SRER, com->cy_align, com->intr_enable = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA); - COM_UNLOCK(); enable_intr(); #endif /* 0 */ /* @@ -877,9 +873,7 @@ comhardclose(com) outb(iobase + com_ier, 0); #else disable_intr(); - COM_LOCK(); cd_outb(iobase, CD1400_SRER, com->cy_align, com->intr_enable = 0); - COM_UNLOCK(); enable_intr(); #endif tp = com->tp; @@ -994,6 +988,8 @@ siointr(unit) int baseu, cyu, cy_align; u_char status; + MPINTR_LOCK(); /* XXX could this be placed down lower in the loop? */ + baseu = unit * CY_MAX_PORTS; cy_iobase = com_addr(baseu)->cy_iobase; cy_align = com_addr(baseu)->cy_align; @@ -1340,6 +1336,8 @@ cont: cd_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0); schedsofttty(); + + MPINTR_UNLOCK(); } #if 0 @@ -1537,7 +1535,6 @@ repeat: * loop. */ disable_intr(); - COM_LOCK(); incc = com->iptr - com->ibuf; com->iptr = com->ibuf; if (com->state & CS_CHECKMSR) { @@ -1545,7 +1542,6 @@ repeat: com->state &= ~CS_CHECKMSR; } com_events -= incc; - COM_UNLOCK(); enable_intr(); if (incc != 0) log(LOG_DEBUG, @@ -1561,7 +1557,6 @@ repeat: } else { buf = ibuf; disable_intr(); - COM_LOCK(); incc = com->iptr - buf; com_events -= incc; if (ibuf == com->ibuf1) @@ -1590,7 +1585,6 @@ repeat: cd_outb(iobase, CD1400_MSVR1, com->cy_align, com->mcr_image |= MCR_RTS); #endif - COM_UNLOCK(); enable_intr(); com->ibuf = ibuf; } @@ -1599,13 +1593,11 @@ repeat: u_char delta_modem_status; disable_intr(); - COM_LOCK(); delta_modem_status = com->last_modem_status ^ com->prev_modem_status; com->prev_modem_status = com->last_modem_status; com_events -= LOTS_OF_EVENTS; com->state &= ~CS_CHECKMSR; - COM_UNLOCK(); enable_intr(); if (delta_modem_status & MSR_DCD) (*linesw[tp->t_line].l_modem) @@ -1613,12 +1605,10 @@ repeat: } if (com->state & CS_ODONE) { disable_intr(); - COM_LOCK(); com_events -= LOTS_OF_EVENTS; com->state &= ~CS_ODONE; if (!(com->state & CS_BUSY)) com->tp->t_state &= ~TS_BUSY; - COM_UNLOCK(); enable_intr(); (*linesw[tp->t_line].l_start)(tp); } @@ -1961,7 +1951,6 @@ comparam(tp, t) * to change all atomically. */ disable_intr(); - COM_LOCK(); com->state &= ~CS_TTGO; if (!(tp->t_state & TS_TTSTOP)) @@ -2023,7 +2012,6 @@ comparam(tp, t) com->intr_enable &= ~CD1400_SRER_TXRDY); } - COM_UNLOCK(); enable_intr(); splx(s); comstart(tp); @@ -2053,7 +2041,6 @@ comstart(tp) #endif disable_intr(); - COM_LOCK(); cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN); if (tp->t_state & TS_TTSTOP) { com->state &= ~CS_TTGO; @@ -2085,7 +2072,6 @@ comstart(tp) com->mcr_image |= MCR_RTS); #endif } - COM_UNLOCK(); enable_intr(); if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { splx(s); @@ -2105,7 +2091,6 @@ comstart(tp) com->obufs[0].l_next = NULL; com->obufs[0].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2122,7 +2107,6 @@ comstart(tp) com->intr_enable |= CD1400_SRER_TXRDY); } - COM_UNLOCK(); enable_intr(); } if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { @@ -2135,7 +2119,6 @@ comstart(tp) com->obufs[1].l_next = NULL; com->obufs[1].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2152,7 +2135,6 @@ comstart(tp) com->intr_enable |= CD1400_SRER_TXRDY); } - COM_UNLOCK(); enable_intr(); } tp->t_state |= TS_BUSY; @@ -2163,10 +2145,8 @@ comstart(tp) #endif #if 0 disable_intr(); - COM_LOCK(); if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); /* fake interrupt to start output */ - COM_UNLOCK(); enable_intr(); #endif ttwwakeup(tp); @@ -2182,7 +2162,6 @@ siostop(tp, rw) com = com_addr(DEV_TO_UNIT(tp->t_dev)); disable_intr(); - COM_LOCK(); if (rw & FWRITE) { com->obufs[0].l_queued = FALSE; com->obufs[1].l_queued = FALSE; @@ -2195,7 +2174,6 @@ siostop(tp, rw) com_events -= (com->iptr - com->ibuf); com->iptr = com->ibuf; } - COM_UNLOCK(); enable_intr(); comstart(tp); @@ -2266,7 +2244,6 @@ commctl(com, bits, how) if (bits & TIOCM_RTS) mcr |= MCR_RTS; disable_intr(); - COM_LOCK(); switch (how) { case DMSET: com->mcr_image = mcr; @@ -2284,7 +2261,6 @@ commctl(com, bits, how) cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr); break; } - COM_UNLOCK(); enable_intr(); return (0); } @@ -2347,9 +2323,7 @@ comwakeup(chan) if (com != NULL && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { disable_intr(); - COM_LOCK(); siointr1(com); - COM_UNLOCK(); enable_intr(); } } @@ -2372,10 +2346,8 @@ comwakeup(chan) u_long total; disable_intr(); - COM_LOCK(); delta = com->delta_error_counts[errnum]; com->delta_error_counts[errnum] = 0; - COM_UNLOCK(); enable_intr(); if (delta == 0) continue; diff --git a/sys/dev/cy/cy_isa.c b/sys/dev/cy/cy_isa.c index 65647d3..62a3598 100644 --- a/sys/dev/cy/cy_isa.c +++ b/sys/dev/cy/cy_isa.c @@ -27,7 +27,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: cy.c,v 1.49 1997/08/20 06:16:44 fsmp Exp $ + * $Id: cy.c,v 1.4 1997/08/30 01:23:40 smp Exp smp $ */ #include "cy.h" @@ -756,26 +756,22 @@ open_top: } disable_intr(); - COM_LOCK(); (void) inb(com->line_status_port); (void) inb(com->data_port); com->prev_modem_status = com->last_modem_status = inb(com->modem_status_port); outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC); - COM_UNLOCK(); enable_intr(); #else /* !0 */ /* XXX raise RTS too */ (void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET); disable_intr(); - COM_LOCK(); com->prev_modem_status = com->last_modem_status = cd_inb(iobase, CD1400_MSVR2, com->cy_align); cd_outb(iobase, CD1400_SRER, com->cy_align, com->intr_enable = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA); - COM_UNLOCK(); enable_intr(); #endif /* 0 */ /* @@ -877,9 +873,7 @@ comhardclose(com) outb(iobase + com_ier, 0); #else disable_intr(); - COM_LOCK(); cd_outb(iobase, CD1400_SRER, com->cy_align, com->intr_enable = 0); - COM_UNLOCK(); enable_intr(); #endif tp = com->tp; @@ -994,6 +988,8 @@ siointr(unit) int baseu, cyu, cy_align; u_char status; + MPINTR_LOCK(); /* XXX could this be placed down lower in the loop? */ + baseu = unit * CY_MAX_PORTS; cy_iobase = com_addr(baseu)->cy_iobase; cy_align = com_addr(baseu)->cy_align; @@ -1340,6 +1336,8 @@ cont: cd_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0); schedsofttty(); + + MPINTR_UNLOCK(); } #if 0 @@ -1537,7 +1535,6 @@ repeat: * loop. */ disable_intr(); - COM_LOCK(); incc = com->iptr - com->ibuf; com->iptr = com->ibuf; if (com->state & CS_CHECKMSR) { @@ -1545,7 +1542,6 @@ repeat: com->state &= ~CS_CHECKMSR; } com_events -= incc; - COM_UNLOCK(); enable_intr(); if (incc != 0) log(LOG_DEBUG, @@ -1561,7 +1557,6 @@ repeat: } else { buf = ibuf; disable_intr(); - COM_LOCK(); incc = com->iptr - buf; com_events -= incc; if (ibuf == com->ibuf1) @@ -1590,7 +1585,6 @@ repeat: cd_outb(iobase, CD1400_MSVR1, com->cy_align, com->mcr_image |= MCR_RTS); #endif - COM_UNLOCK(); enable_intr(); com->ibuf = ibuf; } @@ -1599,13 +1593,11 @@ repeat: u_char delta_modem_status; disable_intr(); - COM_LOCK(); delta_modem_status = com->last_modem_status ^ com->prev_modem_status; com->prev_modem_status = com->last_modem_status; com_events -= LOTS_OF_EVENTS; com->state &= ~CS_CHECKMSR; - COM_UNLOCK(); enable_intr(); if (delta_modem_status & MSR_DCD) (*linesw[tp->t_line].l_modem) @@ -1613,12 +1605,10 @@ repeat: } if (com->state & CS_ODONE) { disable_intr(); - COM_LOCK(); com_events -= LOTS_OF_EVENTS; com->state &= ~CS_ODONE; if (!(com->state & CS_BUSY)) com->tp->t_state &= ~TS_BUSY; - COM_UNLOCK(); enable_intr(); (*linesw[tp->t_line].l_start)(tp); } @@ -1961,7 +1951,6 @@ comparam(tp, t) * to change all atomically. */ disable_intr(); - COM_LOCK(); com->state &= ~CS_TTGO; if (!(tp->t_state & TS_TTSTOP)) @@ -2023,7 +2012,6 @@ comparam(tp, t) com->intr_enable &= ~CD1400_SRER_TXRDY); } - COM_UNLOCK(); enable_intr(); splx(s); comstart(tp); @@ -2053,7 +2041,6 @@ comstart(tp) #endif disable_intr(); - COM_LOCK(); cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN); if (tp->t_state & TS_TTSTOP) { com->state &= ~CS_TTGO; @@ -2085,7 +2072,6 @@ comstart(tp) com->mcr_image |= MCR_RTS); #endif } - COM_UNLOCK(); enable_intr(); if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { splx(s); @@ -2105,7 +2091,6 @@ comstart(tp) com->obufs[0].l_next = NULL; com->obufs[0].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2122,7 +2107,6 @@ comstart(tp) com->intr_enable |= CD1400_SRER_TXRDY); } - COM_UNLOCK(); enable_intr(); } if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { @@ -2135,7 +2119,6 @@ comstart(tp) com->obufs[1].l_next = NULL; com->obufs[1].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2152,7 +2135,6 @@ comstart(tp) com->intr_enable |= CD1400_SRER_TXRDY); } - COM_UNLOCK(); enable_intr(); } tp->t_state |= TS_BUSY; @@ -2163,10 +2145,8 @@ comstart(tp) #endif #if 0 disable_intr(); - COM_LOCK(); if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); /* fake interrupt to start output */ - COM_UNLOCK(); enable_intr(); #endif ttwwakeup(tp); @@ -2182,7 +2162,6 @@ siostop(tp, rw) com = com_addr(DEV_TO_UNIT(tp->t_dev)); disable_intr(); - COM_LOCK(); if (rw & FWRITE) { com->obufs[0].l_queued = FALSE; com->obufs[1].l_queued = FALSE; @@ -2195,7 +2174,6 @@ siostop(tp, rw) com_events -= (com->iptr - com->ibuf); com->iptr = com->ibuf; } - COM_UNLOCK(); enable_intr(); comstart(tp); @@ -2266,7 +2244,6 @@ commctl(com, bits, how) if (bits & TIOCM_RTS) mcr |= MCR_RTS; disable_intr(); - COM_LOCK(); switch (how) { case DMSET: com->mcr_image = mcr; @@ -2284,7 +2261,6 @@ commctl(com, bits, how) cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr); break; } - COM_UNLOCK(); enable_intr(); return (0); } @@ -2347,9 +2323,7 @@ comwakeup(chan) if (com != NULL && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { disable_intr(); - COM_LOCK(); siointr1(com); - COM_UNLOCK(); enable_intr(); } } @@ -2372,10 +2346,8 @@ comwakeup(chan) u_long total; disable_intr(); - COM_LOCK(); delta = com->delta_error_counts[errnum]; com->delta_error_counts[errnum] = 0; - COM_UNLOCK(); enable_intr(); if (delta == 0) continue; diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index 62300b6..7555e2f 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.5 1997/08/21 06:08:45 smp Exp smp $ + * $Id: sio.c,v 1.8 1997/08/30 01:23:40 smp Exp smp $ */ #include "opt_comconsole.h" @@ -65,6 +65,11 @@ #endif #include <machine/clock.h> +#ifdef SMP +#include <machine/smp.h> +#else +#define POSTCODE_HI(X) +#endif #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> @@ -559,11 +564,11 @@ static int card_intr(struct pccard_dev *dp) { struct com_s *com; - COM_LOCK(); + MPINTR_LOCK(); com = com_addr(dp->isahd.id_unit); if (com && !com_addr(dp->isahd.id_unit)->gone) siointr1(com_addr(dp->isahd.id_unit)); - COM_UNLOCK(); + MPINTR_UNLOCK(); return(1); } #endif /* NCRD > 0 */ @@ -644,7 +649,9 @@ sioprobe(dev) * but mask them in the processor as well in case there are some * (misconfigured) shared interrupts. */ + POSTCODE_HI(0x8); disable_intr(); + POSTCODE_HI(0x9); /* EXTRA DELAY? */ /* @@ -750,7 +757,9 @@ sioprobe(dev) failures[8] = isa_irq_pending(idev) ? 1 : 0; failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND; + POSTCODE_HI(0xa); enable_intr(); + POSTCODE_HI(0xb); result = IO_COMSIZE; for (fn = 0; fn < sizeof failures; ++fn) @@ -1185,14 +1194,12 @@ open_top: } disable_intr(); - COM_LOCK(); (void) inb(com->line_status_port); (void) inb(com->data_port); com->prev_modem_status = com->last_modem_status = inb(com->modem_status_port); outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC); - COM_UNLOCK(); enable_intr(); /* * Handle initial DCD. Callout devices get a fake initial @@ -1421,9 +1428,9 @@ siointr(unit) int unit; { #ifndef COM_MULTIPORT - COM_LOCK(); + MPINTR_LOCK(); siointr1(com_addr(unit)); - COM_UNLOCK(); + MPINTR_UNLOCK(); #else /* COM_MULTIPORT */ struct com_s *com; bool_t possibly_more_intrs; @@ -1435,11 +1442,15 @@ siointr(unit) * devices, then the edge from one may be lost because another is * on. */ - COM_LOCK(); + MPINTR_LOCK(); do { possibly_more_intrs = FALSE; for (unit = 0; unit < NSIO; ++unit) { com = com_addr(unit); + /* + * XXX MPINTR_LOCK(); + * would it work here, or be counter-productive? + */ if (com != NULL && !com->gone && (inb(com->int_id_port) & IIR_IMASK) @@ -1447,9 +1458,10 @@ siointr(unit) siointr1(com); possibly_more_intrs = TRUE; } + /* XXX MPINTR_UNLOCK(); */ } } while (possibly_more_intrs); - COM_UNLOCK(); + MPINTR_UNLOCK(); #endif /* COM_MULTIPORT */ } @@ -1829,7 +1841,6 @@ repeat: * loop. */ disable_intr(); - COM_LOCK(); incc = com->iptr - com->ibuf; com->iptr = com->ibuf; if (com->state & CS_CHECKMSR) { @@ -1837,7 +1848,6 @@ repeat: com->state &= ~CS_CHECKMSR; } com_events -= incc; - COM_UNLOCK(); enable_intr(); if (incc != 0) log(LOG_DEBUG, @@ -1853,7 +1863,6 @@ repeat: } else { buf = ibuf; disable_intr(); - COM_LOCK(); incc = com->iptr - buf; com_events -= incc; if (ibuf == com->ibuf1) @@ -1874,7 +1883,6 @@ repeat: && !(tp->t_state & TS_TBLOCK)) outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); - COM_UNLOCK(); enable_intr(); com->ibuf = ibuf; } @@ -1883,13 +1891,11 @@ repeat: u_char delta_modem_status; disable_intr(); - COM_LOCK(); delta_modem_status = com->last_modem_status ^ com->prev_modem_status; com->prev_modem_status = com->last_modem_status; com_events -= LOTS_OF_EVENTS; com->state &= ~CS_CHECKMSR; - COM_UNLOCK(); enable_intr(); if (delta_modem_status & MSR_DCD) (*linesw[tp->t_line].l_modem) @@ -1897,10 +1903,8 @@ repeat: } if (com->state & CS_ODONE) { disable_intr(); - COM_LOCK(); com_events -= LOTS_OF_EVENTS; com->state &= ~CS_ODONE; - COM_UNLOCK(); enable_intr(); if (!(com->state & CS_BUSY) && !(com->extra_state & CSE_BUSYCHECK)) { @@ -2056,11 +2060,9 @@ comparam(tp, t) * error bits, but that is acceptable here. */ disable_intr(); - COM_LOCK(); retry: com->state &= ~CS_TTGO; txtimeout = tp->t_timeout; - COM_UNLOCK(); enable_intr(); while ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY)) != (LSR_TSRE | LSR_TXRDY)) { @@ -2077,9 +2079,7 @@ retry: if (error != 0 && error != EAGAIN) { if (!(tp->t_state & TS_TTSTOP)) { disable_intr(); - COM_LOCK(); com->state |= CS_TTGO; - COM_UNLOCK(); enable_intr(); } splx(s); @@ -2088,7 +2088,6 @@ retry: } disable_intr(); /* very important while com_data is hidden */ - COM_LOCK(); /* * XXX - clearing CS_TTGO is not sufficient to stop further output, @@ -2184,7 +2183,6 @@ retry: if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); - COM_UNLOCK(); enable_intr(); splx(s); comstart(tp); @@ -2203,7 +2201,6 @@ comstart(tp) com = com_addr(unit); s = spltty(); disable_intr(); - COM_LOCK(); if (tp->t_state & TS_TTSTOP) com->state &= ~CS_TTGO; else @@ -2216,7 +2213,6 @@ comstart(tp) && com->state & CS_RTS_IFLOW) outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); } - COM_UNLOCK(); enable_intr(); if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { splx(s); @@ -2233,7 +2229,6 @@ comstart(tp) com->obufs[0].l_next = NULL; com->obufs[0].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2245,7 +2240,6 @@ comstart(tp) com->obufq.l_next = &com->obufs[0]; com->state |= CS_BUSY; } - COM_UNLOCK(); enable_intr(); } if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { @@ -2255,7 +2249,6 @@ comstart(tp) com->obufs[1].l_next = NULL; com->obufs[1].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2267,16 +2260,13 @@ comstart(tp) com->obufq.l_next = &com->obufs[1]; com->state |= CS_BUSY; } - COM_UNLOCK(); enable_intr(); } tp->t_state |= TS_BUSY; } disable_intr(); - COM_LOCK(); if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); /* fake interrupt to start output */ - COM_UNLOCK(); enable_intr(); ttwwakeup(tp); splx(s); @@ -2293,7 +2283,6 @@ siostop(tp, rw) if (com->gone) return; disable_intr(); - COM_LOCK(); if (rw & FWRITE) { if (com->hasfifo) #ifdef COM_ESP @@ -2322,7 +2311,6 @@ siostop(tp, rw) com_events -= (com->iptr - com->ibuf); com->iptr = com->ibuf; } - COM_UNLOCK(); enable_intr(); comstart(tp); } @@ -2383,7 +2371,6 @@ commctl(com, bits, how) if (com->gone) return(0); disable_intr(); - COM_LOCK(); switch (how) { case DMSET: outb(com->modem_ctl_port, @@ -2396,7 +2383,6 @@ commctl(com, bits, how) outb(com->modem_ctl_port, com->mcr_image &= ~mcr); break; } - COM_UNLOCK(); enable_intr(); return (0); } @@ -2456,9 +2442,7 @@ comwakeup(chan) if (com != NULL && !com->gone && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { disable_intr(); - COM_LOCK(); siointr1(com); - COM_UNLOCK(); enable_intr(); } } @@ -2482,10 +2466,8 @@ comwakeup(chan) u_long total; disable_intr(); - COM_LOCK(); delta = com->delta_error_counts[errnum]; com->delta_error_counts[errnum] = 0; - COM_UNLOCK(); enable_intr(); if (delta == 0) continue; diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index d78d320..0652b69 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.32 1997/08/29 18:37:23 smp Exp smp $ + * $Id: apic_vector.s,v 1.33 1997/08/30 01:23:40 smp Exp smp $ */ @@ -75,9 +75,10 @@ IDTVEC(vec_name) ; \ movl %ax,%ds ; \ MAYBE_MOVW_AX_ES ; \ FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ - GET_FAST_INTR_LOCK ; \ pushl _intr_unit + (irq_num) * 4 ; \ + GET_FAST_INTR_LOCK ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ + REL_FAST_INTR_LOCK ; \ addl $4, %esp ; \ movl $0, lapic_eoi ; \ lock ; \ @@ -86,7 +87,6 @@ IDTVEC(vec_name) ; \ lock ; \ incl (%eax) ; \ MEXITCOUNT ; \ - REL_FAST_INTR_LOCK ; \ MAYBE_POPL_ES ; \ popl %ds ; \ popl %edx ; \ diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s index f072e7a..9a74ca1 100644 --- a/sys/i386/i386/exception.s +++ b/sys/i386/i386/exception.s @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exception.s,v 1.19 1997/08/28 09:50:41 smp Exp smp $ + * $Id: exception.s,v 1.42 1997/08/29 18:16:17 fsmp Exp $ */ #include "npx.h" /* NNPX */ @@ -38,9 +38,9 @@ #include <machine/ipl.h> /* SWI_AST_MASK ... */ #include <machine/psl.h> /* PSL_I */ #include <machine/trap.h> /* trap codes */ -#include <machine/asmacros.h> /* miscellaneous macros */ -#include <machine/param.h> +#include <machine/asmacros.h> #include <machine/smptests.h> /* INTR_SIMPLELOCK */ +#include <machine/lock.h> #ifndef SMP #undef INTR_SIMPLELOCK /* simplifies cpp tests */ diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index d5ea71c..955a3a1 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.46 1997/08/26 18:10:31 peter Exp $ + * $Id: mp_machdep.c,v 1.32 1997/08/30 01:25:13 smp Exp smp $ */ #include "opt_smp.h" @@ -1446,8 +1446,16 @@ struct simplelock fast_intr_lock; /* critical region around INTR() routines */ struct simplelock intr_lock; +#ifdef SIMPLE_MPINTRLOCK +/* critical region around INTR() routines */ +struct simplelock mpintr_lock; +struct simplelock clock_lock; +#endif + +#if 0 /* lock the com (tty) data structures */ struct simplelock com_lock; +#endif static void init_locks(void) @@ -1459,7 +1467,13 @@ init_locks(void) mp_lock = 0x00000001; /* ISR uses its own "giant lock" */ - isr_lock = 0x00000000; + isr_lock = FREE_LOCK; + +#ifdef SIMPLE_MPINTRLOCK + /* lock regions protected in UP kernel via cli/sti */ + s_lock_init((struct simplelock*)&mpintr_lock); + s_lock_init((struct simplelock*)&clock_lock); +#endif /* serializes FAST_INTR() accesses */ s_lock_init((struct simplelock*)&fast_intr_lock); @@ -1470,11 +1484,13 @@ init_locks(void) /* locks the IO APIC and apic_imen accesses */ s_lock_init((struct simplelock*)&imen_lock); - /* locks cpl accesses */ + /* locks cpl/cml/cim/ipending accesses */ s_lock_init((struct simplelock*)&cpl_lock); +#if 0 /* locks com (tty) data/hardware accesses: a FASTINTR() */ s_lock_init((struct simplelock*)&com_lock); +#endif } diff --git a/sys/i386/i386/mplock.s b/sys/i386/i386/mplock.s index 18868f7..3bf9f41 100644 --- a/sys/i386/i386/mplock.s +++ b/sys/i386/i386/mplock.s @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: mplock.s,v 1.19 1997/08/29 07:26:27 smp Exp smp $ + * $Id: mplock.s,v 1.22 1997/08/29 18:16:17 fsmp Exp $ * * Functions for locking between CPUs in a SMP system. * @@ -461,6 +461,49 @@ NON_GPROF_ENTRY(rel_altsyscall_lock) #endif /* notneeded */ +#ifdef RECURSIVE_MPINTRLOCK +/*********************************************************************** + * void get_mpintrlock() + * ----------------- + * All registers preserved + */ + +NON_GPROF_ENTRY(get_mpintrlock) + pushl %eax + pushl %ecx + pushl %edx + + pushl $_mpintr_lock + call _MPgetlock + add $4, %esp + + popl %edx + popl %ecx + popl %eax + ret + +/*********************************************************************** + * void rel_mpintrlock() + * ----------------- + * All registers preserved + */ + +NON_GPROF_ENTRY(rel_mpintrlock) + pushl %eax + pushl %ecx + pushl %edx + + pushl $_mpintr_lock + call _MPrellock + add $4, %esp + + popl %edx + popl %ecx + popl %eax + ret +#endif /* RECURSIVE_MPINTRLOCK */ + + /*********************************************************************** * */ @@ -473,6 +516,11 @@ _mp_lock: .long 0 .globl _isr_lock _isr_lock: .long 0 +#ifdef RECURSIVE_MPINTRLOCK + .globl _mpintr_lock +_mpintr_lock: .long 0xffffffff +#endif /* RECURSIVE_MPINTRLOCK */ + #ifdef GLPROFILE .globl _gethits diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c index d5ea71c..955a3a1 100644 --- a/sys/i386/i386/mptable.c +++ b/sys/i386/i386/mptable.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.46 1997/08/26 18:10:31 peter Exp $ + * $Id: mp_machdep.c,v 1.32 1997/08/30 01:25:13 smp Exp smp $ */ #include "opt_smp.h" @@ -1446,8 +1446,16 @@ struct simplelock fast_intr_lock; /* critical region around INTR() routines */ struct simplelock intr_lock; +#ifdef SIMPLE_MPINTRLOCK +/* critical region around INTR() routines */ +struct simplelock mpintr_lock; +struct simplelock clock_lock; +#endif + +#if 0 /* lock the com (tty) data structures */ struct simplelock com_lock; +#endif static void init_locks(void) @@ -1459,7 +1467,13 @@ init_locks(void) mp_lock = 0x00000001; /* ISR uses its own "giant lock" */ - isr_lock = 0x00000000; + isr_lock = FREE_LOCK; + +#ifdef SIMPLE_MPINTRLOCK + /* lock regions protected in UP kernel via cli/sti */ + s_lock_init((struct simplelock*)&mpintr_lock); + s_lock_init((struct simplelock*)&clock_lock); +#endif /* serializes FAST_INTR() accesses */ s_lock_init((struct simplelock*)&fast_intr_lock); @@ -1470,11 +1484,13 @@ init_locks(void) /* locks the IO APIC and apic_imen accesses */ s_lock_init((struct simplelock*)&imen_lock); - /* locks cpl accesses */ + /* locks cpl/cml/cim/ipending accesses */ s_lock_init((struct simplelock*)&cpl_lock); +#if 0 /* locks com (tty) data/hardware accesses: a FASTINTR() */ s_lock_init((struct simplelock*)&com_lock); +#endif } diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c index 28f6dc9..0755baf 100644 --- a/sys/i386/i386/tsc.c +++ b/sys/i386/i386/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.99 1997/08/21 05:08:07 fsmp Exp $ + * $Id: clock.c,v 1.10 1997/08/30 01:23:40 smp Exp smp $ */ /* @@ -65,9 +65,9 @@ #include <machine/frame.h> #include <machine/ipl.h> #include <machine/limits.h> -#ifdef APIC_IO +#if defined(SMP) || defined(APIC_IO) #include <machine/smp.h> -#endif /* APIC_IO */ +#endif /* SMP || APIC_IO */ #include <i386/isa/icu.h> #include <i386/isa/isa.h> @@ -77,6 +77,34 @@ #include <i386/isa/intr_machdep.h> #include <sys/interrupt.h> +#ifdef SMP +#include <machine/smptests.h> + +#ifdef SIMPLE_MPINTRLOCK +#define DISABLE_INTR() \ + __asm __volatile("cli" : : : "memory"); \ + s_lock(&clock_lock); + +#define ENABLE_INTR() \ + s_unlock(&clock_lock); \ + __asm __volatile("sti"); + +#define CLOCK_UNLOCK() \ + s_unlock(&clock_lock); +#else /* SIMPLE_MPINTRLOCK */ +#define DISABLE_INTR() disable_intr() +#define ENABLE_INTR() enable_intr() +#define CLOCK_UNLOCK() +#endif /* SIMPLE_MPINTRLOCK */ + +#else /* SMP */ + +#define DISABLE_INTR() disable_intr() +#define ENABLE_INTR() enable_intr() +#define CLOCK_UNLOCK() + +#endif /* SMP */ + /* * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we * can use a simple formula for leap years. @@ -183,11 +211,11 @@ clkintr(struct clockframe frame) timer0_max_count = TIMER_DIV(new_rate); timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; - disable_intr(); + DISABLE_INTR(); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - enable_intr(); + ENABLE_INTR(); timer0_prescaler_count = 0; timer_func = new_function; timer0_state = ACQUIRED; @@ -201,12 +229,12 @@ clkintr(struct clockframe frame) timer0_max_count = hardclock_max_count; timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; - disable_intr(); + DISABLE_INTR(); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - enable_intr(); + ENABLE_INTR(); /* * See microtime.s for this magic. */ @@ -358,7 +386,7 @@ getit(void) int high, low; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -366,6 +394,7 @@ getit(void) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); + CLOCK_UNLOCK(); write_eflags(ef); return ((high << 8) | low); } @@ -480,10 +509,10 @@ sysbeep(int pitch, int period) splx(x); return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ } - disable_intr(); + DISABLE_INTR(); outb(TIMER_CNTR2, pitch); outb(TIMER_CNTR2, (pitch>>8)); - enable_intr(); + ENABLE_INTR(); if (!beeping) { /* enable counter2 output to speaker */ outb(IO_PPI, inb(IO_PPI) | 3); @@ -626,13 +655,14 @@ set_timer_freq(u_int freq, int intr_freq) u_long ef; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); timer_freq = freq; timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); + CLOCK_UNLOCK(); write_eflags(ef); } @@ -1002,10 +1032,11 @@ set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq) << I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq; multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); i586_ctr_freq = i586_freq; i586_ctr_comultiplier = comultiplier; i586_ctr_multiplier = multiplier; + CLOCK_UNLOCK(); write_eflags(ef); } diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h index 41e1bd7..9fd475e 100644 --- a/sys/i386/include/cpufunc.h +++ b/sys/i386/include/cpufunc.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cpufunc.h,v 1.68 1997/05/31 09:13:03 peter Exp $ + * $Id: cpufunc.h,v 1.69 1997/07/17 04:33:46 dyson Exp $ */ /* @@ -43,6 +43,9 @@ #include <sys/cdefs.h> #include <sys/types.h> +#include <machine/lock.h> + + #ifdef __GNUC__ static __inline void @@ -55,11 +58,13 @@ static __inline void disable_intr(void) { __asm __volatile("cli" : : : "memory"); + MPINTR_LOCK(); } static __inline void enable_intr(void) { + MPINTR_UNLOCK(); __asm __volatile("sti"); } diff --git a/sys/i386/include/lock.h b/sys/i386/include/lock.h new file mode 100644 index 0000000..39b474d --- /dev/null +++ b/sys/i386/include/lock.h @@ -0,0 +1,226 @@ +/* + * Copyright (c) 1997, by Steve Passe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the developer may NOT be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: lock.h,v 1.2 1997/08/30 07:51:10 smp Exp smp $ + */ + + +#ifndef _MACHINE_LOCK_H_ +#define _MACHINE_LOCK_H_ + +/* + * XXX some temp debug control of cpl locks + */ +#define REAL_ECPL /* exception.s: SCPL_LOCK/SCPL_UNLOCK */ +#define REAL_ICPL /* ipl.s: CPL_LOCK/CPL_UNLOCK/FAST */ +#define REAL_AICPL /* apic_ipl.s: SCPL_LOCK/SCPL_UNLOCK */ +#define REAL_AVCPL /* apic_vector.s: CPL_LOCK/CPL_UNLOCK */ + +#define REAL_IFCPL /* ipl_funcs.c: SCPL_LOCK/SCPL_UNLOCK */ + +#define REAL_MCPL_NOT /* microtime.s: CPL_LOCK/movl $0,_cpl_lock */ + + +#ifdef LOCORE + +#ifdef SMP + +#define MPLOCKED lock ; + +/* + * Some handy macros to allow logical organization and + * convenient reassignment of various locks. + */ + +#define FPU_LOCK call _get_fpu_lock +#define ALIGN_LOCK call _get_align_lock +#define SYSCALL_LOCK call _get_syscall_lock +#define ALTSYSCALL_LOCK call _get_altsyscall_lock + +/* + * Protects INTR() ISRs. + */ +#define ISR_TRYLOCK \ + pushl $_mp_lock ; /* GIANT_LOCK */ \ + call _MPtrylock ; /* try to get lock */ \ + add $4, %esp + +#define ISR_RELLOCK \ + pushl $_mp_lock ; /* GIANT_LOCK */ \ + call _MPrellock ; \ + add $4, %esp + +/* + * Protects the IO APIC and apic_imen as a critical region. + */ +#define IMASK_LOCK \ + pushl $_imen_lock ; /* address of lock */ \ + call _s_lock ; /* MP-safe */ \ + addl $4, %esp + +#define IMASK_UNLOCK \ + pushl $_imen_lock ; /* address of lock */ \ + call _s_unlock ; /* MP-safe */ \ + addl $4, %esp + +/* + * Variations of CPL_LOCK protect spl updates as a critical region. + * Items within this 'region' include: + * cpl + * cil + * ipending + * ??? + */ + +/* + * Botom half routines, ie. those already protected from INTs. + * + * Used in: + * sys/i386/i386/microtime.s (XXX currently NOT used, possible race?) + * sys/i386/isa/ipl.s: _doreti + * sys/i386/isa/apic_vector.s: _Xintr0, ..., _Xintr23 + */ +#define CPL_LOCK \ + pushl $_cpl_lock ; /* address of lock */ \ + call _s_lock ; /* MP-safe */ \ + addl $4, %esp + +#define CPL_UNLOCK \ + pushl $_cpl_lock ; /* address of lock */ \ + call _s_unlock ; /* MP-safe */ \ + addl $4, %esp + +/* + * INT safe version for top half of kernel. + * + * Used in: + * sys/i386/i386/exception.s: _Xfpu, _Xalign, _Xsyscall, _Xint0x80_syscall + * sys/i386/isa/apic_ipl.s: splz() + */ +#define SCPL_LOCK \ + pushl $_cpl_lock ; \ + call _ss_lock ; \ + addl $4, %esp + +#define SCPL_UNLOCK \ + pushl $_cpl_lock ; \ + call _ss_unlock ; \ + addl $4, %esp + +#else /* SMP */ + +#define MPLOCKED /* NOP */ + +#define FPU_LOCK /* NOP */ +#define ALIGN_LOCK /* NOP */ +#define SYSCALL_LOCK /* NOP */ +#define ALTSYSCALL_LOCK /* NOP */ + +#endif /* SMP */ + +#else /* LOCORE */ + +#ifdef SMP + +#include <machine/smptests.h> /** XXX_MPINTR_LOCK */ + +/* + * Protects cpl/cml/cil/ipending data as a critical region. + * + * Used in: + * sys/i386/isa/ipl_funcs.c: DO_SETBITS, softclockpending(), GENSPL, + * spl0(), splx(), splq() + */ + +/* Bottom half */ +#define CPL_LOCK() s_lock(&cpl_lock) +#define CPL_UNLOCK() s_unlock(&cpl_lock) + +/* INT safe version for top half of kernel */ +#define SCPL_LOCK() ss_lock(&cpl_lock) +#define SCPL_UNLOCK() ss_unlock(&cpl_lock) + +/* lock regions protected in UP kernel via cli/sti */ +#if defined(SIMPLE_MPINTRLOCK) +#define MPINTR_LOCK() s_lock(&mpintr_lock) +#define MPINTR_UNLOCK() s_unlock(&mpintr_lock) +#elif defined(RECURSIVE_MPINTRLOCK) +#define MPINTR_LOCK() get_mpintrlock() +#define MPINTR_UNLOCK() rel_mpintrlock(); +#else +#error whats up doc? +#endif /* _MPINTRLOCK */ + +#else /* SMP */ + +#define CPL_LOCK() +#define CPL_UNLOCK() +#define SCPL_LOCK() +#define SCPL_UNLOCK() +#define MPINTR_LOCK() +#define MPINTR_UNLOCK() + +#endif /* SMP */ + +/* + * Simple spin lock. + * It is an error to hold one of these locks while a process is sleeping. + */ +struct simplelock { + volatile int lock_data; +}; + +/* functions in simplelock.s */ +void s_lock_init __P((struct simplelock *)); +void s_lock __P((struct simplelock *)); +int s_lock_try __P((struct simplelock *)); +void s_unlock __P((struct simplelock *)); +void ss_lock __P((struct simplelock *)); +void ss_unlock __P((struct simplelock *)); + +/* global data in mp_machdep.c */ +extern struct simplelock imen_lock; +extern struct simplelock cpl_lock; +extern struct simplelock fast_intr_lock; +extern struct simplelock intr_lock; + +#ifdef SIMPLE_MPINTRLOCK +extern struct simplelock mpintr_lock; +extern struct simplelock clock_lock; +#endif/* SIMPLE_MPINTRLOCK */ + +#if !defined(SIMPLELOCK_DEBUG) && NCPUS > 1 +/* + * This set of defines turns on the real functions in i386/isa/apic_ipl.s. + */ +#define simple_lock_init(alp) s_lock_init(alp) +#define simple_lock(alp) s_lock(alp) +#define simple_lock_try(alp) s_lock_try(alp) +#define simple_unlock(alp) s_unlock(alp) + +#endif /* !SIMPLELOCK_DEBUG && NCPUS > 1 */ + +#endif /* LOCORE */ + +#endif /* !_MACHINE_LOCK_H_ */ diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h index d5ea71c..955a3a1 100644 --- a/sys/i386/include/mptable.h +++ b/sys/i386/include/mptable.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.46 1997/08/26 18:10:31 peter Exp $ + * $Id: mp_machdep.c,v 1.32 1997/08/30 01:25:13 smp Exp smp $ */ #include "opt_smp.h" @@ -1446,8 +1446,16 @@ struct simplelock fast_intr_lock; /* critical region around INTR() routines */ struct simplelock intr_lock; +#ifdef SIMPLE_MPINTRLOCK +/* critical region around INTR() routines */ +struct simplelock mpintr_lock; +struct simplelock clock_lock; +#endif + +#if 0 /* lock the com (tty) data structures */ struct simplelock com_lock; +#endif static void init_locks(void) @@ -1459,7 +1467,13 @@ init_locks(void) mp_lock = 0x00000001; /* ISR uses its own "giant lock" */ - isr_lock = 0x00000000; + isr_lock = FREE_LOCK; + +#ifdef SIMPLE_MPINTRLOCK + /* lock regions protected in UP kernel via cli/sti */ + s_lock_init((struct simplelock*)&mpintr_lock); + s_lock_init((struct simplelock*)&clock_lock); +#endif /* serializes FAST_INTR() accesses */ s_lock_init((struct simplelock*)&fast_intr_lock); @@ -1470,11 +1484,13 @@ init_locks(void) /* locks the IO APIC and apic_imen accesses */ s_lock_init((struct simplelock*)&imen_lock); - /* locks cpl accesses */ + /* locks cpl/cml/cim/ipending accesses */ s_lock_init((struct simplelock*)&cpl_lock); +#if 0 /* locks com (tty) data/hardware accesses: a FASTINTR() */ s_lock_init((struct simplelock*)&com_lock); +#endif } diff --git a/sys/i386/include/param.h b/sys/i386/include/param.h index 1eb4b34..2e8c637 100644 --- a/sys/i386/include/param.h +++ b/sys/i386/include/param.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)param.h 5.8 (Berkeley) 6/28/91 - * $Id: param.h,v 1.39 1997/08/29 11:01:14 kato Exp $ + * $Id: param.h,v 1.16 1997/08/30 01:22:01 smp Exp smp $ */ #ifndef _MACHINE_PARAM_H_ @@ -140,242 +140,4 @@ #endif /* !LOCORE */ - -#ifndef _SIMPLELOCK_H_ -#define _SIMPLELOCK_H_ - -/* - * XXX some temp debug control of cpl locks - */ -#define REAL_ECPL /* exception.s: SCPL_LOCK/SCPL_UNLOCK */ -#define REAL_ICPL /* ipl.s: CPL_LOCK/CPL_UNLOCK/FAST */ -#define REAL_AICPL /* apic_ipl.s: SCPL_LOCK/SCPL_UNLOCK */ -#define REAL_AVCPL /* apic_vector.s: CPL_LOCK/CPL_UNLOCK */ - -#define REAL_IFCPL /* ipl_funcs.c: SCPL_LOCK/SCPL_UNLOCK */ - -#define REAL_MCPL_NOT /* microtime.s: CPL_LOCK/movl $0,_cpl_lock */ - - -#ifdef LOCORE - -#ifdef SMP - -#define MPLOCKED lock ; - -/* - * Some handy macros to allow logical organization and - * convenient reassignment of various locks. - */ - -#define FPU_LOCK call _get_fpu_lock -#define ALIGN_LOCK call _get_align_lock -#define SYSCALL_LOCK call _get_syscall_lock -#define ALTSYSCALL_LOCK call _get_altsyscall_lock - -/* - * Protects INTR() ISRs. - */ -#define ISR_TRYLOCK \ - pushl $_mp_lock ; /* GIANT_LOCK */ \ - call _MPtrylock ; /* try to get lock */ \ - add $4, %esp - -#define ISR_RELLOCK \ - pushl $_mp_lock ; /* GIANT_LOCK */ \ - call _MPrellock ; \ - add $4, %esp - -/* - * Protects the IO APIC and apic_imen as a critical region. - */ -#define IMASK_LOCK \ - pushl $_imen_lock ; /* address of lock */ \ - call _s_lock ; /* MP-safe */ \ - addl $4, %esp - -#define IMASK_UNLOCK \ - pushl $_imen_lock ; /* address of lock */ \ - call _s_unlock ; /* MP-safe */ \ - addl $4, %esp - -/* - * Variations of CPL_LOCK protect spl updates as a critical region. - * Items within this 'region' include: - * cpl - * cil - * ipending - * ??? - */ - -/* - * Botom half routines, ie. those already protected from INTs. - * - * Used in: - * sys/i386/i386/microtime.s (XXX currently NOT used, possible race?) - * sys/i386/isa/ipl.s: _doreti - * sys/i386/isa/apic_vector.s: _Xintr0, ..., _Xintr23 - */ -#define CPL_LOCK \ - pushl $_cpl_lock ; /* address of lock */ \ - call _s_lock ; /* MP-safe */ \ - addl $4, %esp - -#define CPL_UNLOCK \ - pushl $_cpl_lock ; /* address of lock */ \ - call _s_unlock ; /* MP-safe */ \ - addl $4, %esp - -/* - * INT safe version for top half of kernel. - * - * Used in: - * sys/i386/i386/exception.s: _Xfpu, _Xalign, _Xsyscall, _Xint0x80_syscall - * sys/i386/isa/apic_ipl.s: splz() - */ -#define SCPL_LOCK \ - pushl $_cpl_lock ; \ - call _ss_lock ; \ - addl $4, %esp - -#define SCPL_UNLOCK \ - pushl $_cpl_lock ; \ - call _ss_unlock ; \ - addl $4, %esp - -#else /* SMP */ - -#define MPLOCKED /* NOP */ - -#define FPU_LOCK /* NOP */ -#define ALIGN_LOCK /* NOP */ -#define SYSCALL_LOCK /* NOP */ -#define ALTSYSCALL_LOCK /* NOP */ - -#endif /* SMP */ - -#else /* LOCORE */ - -#ifdef SMP - -/* - * Protects cpl/cil/ipending data as a critical region. - * - * Used in: - * sys/i386/isa/ipl_funcs.c: DO_SETBITS, softclockpending(), GENSPL, - * spl0(), splx(), splq() - */ - -/* Bottom half */ -#define CPL_LOCK() s_lock(&cpl_lock) -#define CPL_UNLOCK() s_unlock(&cpl_lock) - -/* INT safe version for top half of kernel */ -#define SCPL_LOCK() ss_lock(&cpl_lock) -#define SCPL_UNLOCK() ss_unlock(&cpl_lock) - -/* - * Protects com/tty data as a critical region. - */ -#define COM_LOCK() s_lock(&com_lock) -#define COM_UNLOCK() s_unlock(&com_lock) - -#else /* SMP */ - -#define CPL_LOCK() -#define CPL_UNLOCK() -#define SCPL_LOCK() -#define SCPL_UNLOCK() - -#define COM_LOCK() -#define COM_UNLOCK() - -#endif /* SMP */ - -/* - * A simple spin lock. - * - * This structure only sets one bit of data, but is sized based on the - * minimum word size that can be operated on by the hardware test-and-set - * instruction. It is only needed for multiprocessors, as uniprocessors - * will always run to completion or a sleep. It is an error to hold one - * of these locks while a process is sleeping. - */ -struct simplelock { - volatile int lock_data; -}; - -/* functions in simplelock.s */ -void s_lock_init __P((struct simplelock *)); -void s_lock __P((struct simplelock *)); -int s_lock_try __P((struct simplelock *)); -void s_unlock __P((struct simplelock *)); -void ss_lock __P((struct simplelock *)); -void ss_unlock __P((struct simplelock *)); - -/* global data in mp_machdep.c */ -extern struct simplelock imen_lock; -extern struct simplelock cpl_lock; -extern struct simplelock fast_intr_lock; -extern struct simplelock intr_lock; -extern struct simplelock com_lock; - -#if !defined(SIMPLELOCK_DEBUG) && NCPUS > 1 -/* - * The simple-lock routines are the primitives out of which the lock - * package is built. The machine-dependent code must implement an - * atomic test_and_set operation that indivisibly sets the simple lock - * to non-zero and returns its old value. It also assumes that the - * setting of the lock to zero below is indivisible. Simple locks may - * only be used for exclusive locks. - */ - -#ifdef the_original_code - -static __inline void -simple_lock_init(struct simplelock *lkp) -{ - - lkp->lock_data = 0; -} - -static __inline void -simple_lock(struct simplelock *lkp) -{ - - while (test_and_set(&lkp->lock_data)) - continue; -} - -static __inline int -simple_lock_try(struct simplelock *lkp) -{ - - return (!test_and_set(&lkp->lock_data)); -} - -static __inline void -simple_unlock(struct simplelock *lkp) -{ - - lkp->lock_data = 0; -} - -#else /* the_original_code */ - -/* - * This set of defines turns on the real functions in i386/isa/apic_ipl.s. - * It has never actually been tested. - */ -#define simple_lock_init(alp) s_lock_init(alp) -#define simple_lock(alp) s_lock(alp) -#define simple_lock_try(alp) s_lock_try(alp) -#define simple_unlock(alp) s_unlock(alp) - -#endif /* the_original_code */ - -#endif /* NCPUS > 1 */ -#endif /* LOCORE */ -#endif /* !_SIMPLELOCK_H_ */ - #endif /* !_MACHINE_PARAM_H_ */ diff --git a/sys/i386/include/profile.h b/sys/i386/include/profile.h index 50da5fe..d451245 100644 --- a/sys/i386/include/profile.h +++ b/sys/i386/include/profile.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)profile.h 8.1 (Berkeley) 6/11/93 - * $Id$ + * $Id: profile.h,v 1.11 1997/02/22 09:35:01 peter Exp $ */ #ifndef _MACHINE_PROFILE_H_ @@ -63,7 +63,11 @@ #else #define MCOUNT_DECL(s) u_long s; #define MCOUNT_ENTER(s) { s = read_eflags(); disable_intr(); } +#ifdef SMP +#define MCOUNT_EXIT(s) { MPINTR_UNLOCK(); write_eflags(s); } +#else #define MCOUNT_EXIT(s) (write_eflags(s)) +#endif #endif /* GUPROF */ #else /* !KERNEL */ diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index 276b838..a7051ff 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.29 1997/08/24 20:33:24 fsmp Exp $ + * $Id: smp.h,v 1.30 1997/08/26 18:10:37 peter Exp $ * */ @@ -60,11 +60,19 @@ void bootMP __P((void)); /* global data in mplock.s */ extern u_int mp_lock; extern u_int isr_lock; +#ifdef RECURSIVE_MPINTRLOCK +extern u_int mpintr_lock; +#endif /* RECURSIVE_MPINTRLOCK */ /* functions in mplock.s */ void get_mplock __P((void)); void rel_mplock __P((void)); void try_mplock __P((void)); +#ifdef RECURSIVE_MPINTRLOCK +void get_mpintrlock __P((void)); +void rel_mpintrlock __P((void)); +void try_mpintrlock __P((void)); +#endif /* RECURSIVE_MPINTRLOCK */ /* global data in apic_vector.s */ extern u_int ivectors[]; diff --git a/sys/i386/include/smptests.h b/sys/i386/include/smptests.h index f6b2ce9..c93cefd 100644 --- a/sys/i386/include/smptests.h +++ b/sys/i386/include/smptests.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: smptests.h,v 1.24 1997/08/29 07:23:37 smp Exp smp $ + * $Id: smptests.h,v 1.22 1997/08/29 17:58:30 fsmp Exp $ */ #ifndef _MACHINE_SMPTESTS_H_ @@ -42,6 +42,24 @@ /* + * There are places in the current kernel where it thinks it has exclusive + * access to the world by bracketing things with disable_intr()/enable_intr(). + * Now that we started letting multiple CPUs into the kernel this is no + * longer true. + * + * SIMPLE_MPINTRLOCK activates code that uses a simplelock to protect + * all code suppossedly protected by disable_intr()/enable_intr(). + * + * RECURSIVE_MPINTRLOCK is an attept to provide a recursive lock, doesn't work! + * + * Only define one of these (on neither, but FAST_HI is then problamatic): +#define SIMPLE_MPINTRLOCK +#define RECURSIVE_MPINTRLOCK + */ +#define SIMPLE_MPINTRLOCK + + +/* * Regular INTerrupts without the giant lock, NOT READY YET!!! * #define INTR_SIMPLELOCK diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s index d78d320..0652b69 100644 --- a/sys/i386/isa/apic_vector.s +++ b/sys/i386/isa/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.32 1997/08/29 18:37:23 smp Exp smp $ + * $Id: apic_vector.s,v 1.33 1997/08/30 01:23:40 smp Exp smp $ */ @@ -75,9 +75,10 @@ IDTVEC(vec_name) ; \ movl %ax,%ds ; \ MAYBE_MOVW_AX_ES ; \ FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \ - GET_FAST_INTR_LOCK ; \ pushl _intr_unit + (irq_num) * 4 ; \ + GET_FAST_INTR_LOCK ; \ call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \ + REL_FAST_INTR_LOCK ; \ addl $4, %esp ; \ movl $0, lapic_eoi ; \ lock ; \ @@ -86,7 +87,6 @@ IDTVEC(vec_name) ; \ lock ; \ incl (%eax) ; \ MEXITCOUNT ; \ - REL_FAST_INTR_LOCK ; \ MAYBE_POPL_ES ; \ popl %ds ; \ popl %edx ; \ diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index 28f6dc9..0755baf 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.99 1997/08/21 05:08:07 fsmp Exp $ + * $Id: clock.c,v 1.10 1997/08/30 01:23:40 smp Exp smp $ */ /* @@ -65,9 +65,9 @@ #include <machine/frame.h> #include <machine/ipl.h> #include <machine/limits.h> -#ifdef APIC_IO +#if defined(SMP) || defined(APIC_IO) #include <machine/smp.h> -#endif /* APIC_IO */ +#endif /* SMP || APIC_IO */ #include <i386/isa/icu.h> #include <i386/isa/isa.h> @@ -77,6 +77,34 @@ #include <i386/isa/intr_machdep.h> #include <sys/interrupt.h> +#ifdef SMP +#include <machine/smptests.h> + +#ifdef SIMPLE_MPINTRLOCK +#define DISABLE_INTR() \ + __asm __volatile("cli" : : : "memory"); \ + s_lock(&clock_lock); + +#define ENABLE_INTR() \ + s_unlock(&clock_lock); \ + __asm __volatile("sti"); + +#define CLOCK_UNLOCK() \ + s_unlock(&clock_lock); +#else /* SIMPLE_MPINTRLOCK */ +#define DISABLE_INTR() disable_intr() +#define ENABLE_INTR() enable_intr() +#define CLOCK_UNLOCK() +#endif /* SIMPLE_MPINTRLOCK */ + +#else /* SMP */ + +#define DISABLE_INTR() disable_intr() +#define ENABLE_INTR() enable_intr() +#define CLOCK_UNLOCK() + +#endif /* SMP */ + /* * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we * can use a simple formula for leap years. @@ -183,11 +211,11 @@ clkintr(struct clockframe frame) timer0_max_count = TIMER_DIV(new_rate); timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; - disable_intr(); + DISABLE_INTR(); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - enable_intr(); + ENABLE_INTR(); timer0_prescaler_count = 0; timer_func = new_function; timer0_state = ACQUIRED; @@ -201,12 +229,12 @@ clkintr(struct clockframe frame) timer0_max_count = hardclock_max_count; timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; - disable_intr(); + DISABLE_INTR(); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - enable_intr(); + ENABLE_INTR(); /* * See microtime.s for this magic. */ @@ -358,7 +386,7 @@ getit(void) int high, low; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -366,6 +394,7 @@ getit(void) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); + CLOCK_UNLOCK(); write_eflags(ef); return ((high << 8) | low); } @@ -480,10 +509,10 @@ sysbeep(int pitch, int period) splx(x); return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ } - disable_intr(); + DISABLE_INTR(); outb(TIMER_CNTR2, pitch); outb(TIMER_CNTR2, (pitch>>8)); - enable_intr(); + ENABLE_INTR(); if (!beeping) { /* enable counter2 output to speaker */ outb(IO_PPI, inb(IO_PPI) | 3); @@ -626,13 +655,14 @@ set_timer_freq(u_int freq, int intr_freq) u_long ef; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); timer_freq = freq; timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); + CLOCK_UNLOCK(); write_eflags(ef); } @@ -1002,10 +1032,11 @@ set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq) << I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq; multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); i586_ctr_freq = i586_freq; i586_ctr_comultiplier = comultiplier; i586_ctr_multiplier = multiplier; + CLOCK_UNLOCK(); write_eflags(ef); } diff --git a/sys/i386/isa/cy.c b/sys/i386/isa/cy.c index 65647d3..62a3598 100644 --- a/sys/i386/isa/cy.c +++ b/sys/i386/isa/cy.c @@ -27,7 +27,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: cy.c,v 1.49 1997/08/20 06:16:44 fsmp Exp $ + * $Id: cy.c,v 1.4 1997/08/30 01:23:40 smp Exp smp $ */ #include "cy.h" @@ -756,26 +756,22 @@ open_top: } disable_intr(); - COM_LOCK(); (void) inb(com->line_status_port); (void) inb(com->data_port); com->prev_modem_status = com->last_modem_status = inb(com->modem_status_port); outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC); - COM_UNLOCK(); enable_intr(); #else /* !0 */ /* XXX raise RTS too */ (void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET); disable_intr(); - COM_LOCK(); com->prev_modem_status = com->last_modem_status = cd_inb(iobase, CD1400_MSVR2, com->cy_align); cd_outb(iobase, CD1400_SRER, com->cy_align, com->intr_enable = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA); - COM_UNLOCK(); enable_intr(); #endif /* 0 */ /* @@ -877,9 +873,7 @@ comhardclose(com) outb(iobase + com_ier, 0); #else disable_intr(); - COM_LOCK(); cd_outb(iobase, CD1400_SRER, com->cy_align, com->intr_enable = 0); - COM_UNLOCK(); enable_intr(); #endif tp = com->tp; @@ -994,6 +988,8 @@ siointr(unit) int baseu, cyu, cy_align; u_char status; + MPINTR_LOCK(); /* XXX could this be placed down lower in the loop? */ + baseu = unit * CY_MAX_PORTS; cy_iobase = com_addr(baseu)->cy_iobase; cy_align = com_addr(baseu)->cy_align; @@ -1340,6 +1336,8 @@ cont: cd_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0); schedsofttty(); + + MPINTR_UNLOCK(); } #if 0 @@ -1537,7 +1535,6 @@ repeat: * loop. */ disable_intr(); - COM_LOCK(); incc = com->iptr - com->ibuf; com->iptr = com->ibuf; if (com->state & CS_CHECKMSR) { @@ -1545,7 +1542,6 @@ repeat: com->state &= ~CS_CHECKMSR; } com_events -= incc; - COM_UNLOCK(); enable_intr(); if (incc != 0) log(LOG_DEBUG, @@ -1561,7 +1557,6 @@ repeat: } else { buf = ibuf; disable_intr(); - COM_LOCK(); incc = com->iptr - buf; com_events -= incc; if (ibuf == com->ibuf1) @@ -1590,7 +1585,6 @@ repeat: cd_outb(iobase, CD1400_MSVR1, com->cy_align, com->mcr_image |= MCR_RTS); #endif - COM_UNLOCK(); enable_intr(); com->ibuf = ibuf; } @@ -1599,13 +1593,11 @@ repeat: u_char delta_modem_status; disable_intr(); - COM_LOCK(); delta_modem_status = com->last_modem_status ^ com->prev_modem_status; com->prev_modem_status = com->last_modem_status; com_events -= LOTS_OF_EVENTS; com->state &= ~CS_CHECKMSR; - COM_UNLOCK(); enable_intr(); if (delta_modem_status & MSR_DCD) (*linesw[tp->t_line].l_modem) @@ -1613,12 +1605,10 @@ repeat: } if (com->state & CS_ODONE) { disable_intr(); - COM_LOCK(); com_events -= LOTS_OF_EVENTS; com->state &= ~CS_ODONE; if (!(com->state & CS_BUSY)) com->tp->t_state &= ~TS_BUSY; - COM_UNLOCK(); enable_intr(); (*linesw[tp->t_line].l_start)(tp); } @@ -1961,7 +1951,6 @@ comparam(tp, t) * to change all atomically. */ disable_intr(); - COM_LOCK(); com->state &= ~CS_TTGO; if (!(tp->t_state & TS_TTSTOP)) @@ -2023,7 +2012,6 @@ comparam(tp, t) com->intr_enable &= ~CD1400_SRER_TXRDY); } - COM_UNLOCK(); enable_intr(); splx(s); comstart(tp); @@ -2053,7 +2041,6 @@ comstart(tp) #endif disable_intr(); - COM_LOCK(); cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN); if (tp->t_state & TS_TTSTOP) { com->state &= ~CS_TTGO; @@ -2085,7 +2072,6 @@ comstart(tp) com->mcr_image |= MCR_RTS); #endif } - COM_UNLOCK(); enable_intr(); if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { splx(s); @@ -2105,7 +2091,6 @@ comstart(tp) com->obufs[0].l_next = NULL; com->obufs[0].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2122,7 +2107,6 @@ comstart(tp) com->intr_enable |= CD1400_SRER_TXRDY); } - COM_UNLOCK(); enable_intr(); } if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { @@ -2135,7 +2119,6 @@ comstart(tp) com->obufs[1].l_next = NULL; com->obufs[1].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2152,7 +2135,6 @@ comstart(tp) com->intr_enable |= CD1400_SRER_TXRDY); } - COM_UNLOCK(); enable_intr(); } tp->t_state |= TS_BUSY; @@ -2163,10 +2145,8 @@ comstart(tp) #endif #if 0 disable_intr(); - COM_LOCK(); if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); /* fake interrupt to start output */ - COM_UNLOCK(); enable_intr(); #endif ttwwakeup(tp); @@ -2182,7 +2162,6 @@ siostop(tp, rw) com = com_addr(DEV_TO_UNIT(tp->t_dev)); disable_intr(); - COM_LOCK(); if (rw & FWRITE) { com->obufs[0].l_queued = FALSE; com->obufs[1].l_queued = FALSE; @@ -2195,7 +2174,6 @@ siostop(tp, rw) com_events -= (com->iptr - com->ibuf); com->iptr = com->ibuf; } - COM_UNLOCK(); enable_intr(); comstart(tp); @@ -2266,7 +2244,6 @@ commctl(com, bits, how) if (bits & TIOCM_RTS) mcr |= MCR_RTS; disable_intr(); - COM_LOCK(); switch (how) { case DMSET: com->mcr_image = mcr; @@ -2284,7 +2261,6 @@ commctl(com, bits, how) cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr); break; } - COM_UNLOCK(); enable_intr(); return (0); } @@ -2347,9 +2323,7 @@ comwakeup(chan) if (com != NULL && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { disable_intr(); - COM_LOCK(); siointr1(com); - COM_UNLOCK(); enable_intr(); } } @@ -2372,10 +2346,8 @@ comwakeup(chan) u_long total; disable_intr(); - COM_LOCK(); delta = com->delta_error_counts[errnum]; com->delta_error_counts[errnum] = 0; - COM_UNLOCK(); enable_intr(); if (delta == 0) continue; diff --git a/sys/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c index c9b5da5..fd836dd 100644 --- a/sys/i386/isa/intr_machdep.c +++ b/sys/i386/isa/intr_machdep.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.1 1997/08/29 18:38:35 smp Exp smp $ + * $Id: intr_machdep.c,v 1.5 1997/08/29 18:45:19 fsmp Exp $ */ #include "opt_auto_eoi.h" @@ -451,6 +451,7 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ INTREN(1 << intr); + MPINTR_UNLOCK(); write_eflags(ef); return (0); } @@ -487,8 +488,15 @@ icu_unset(intr, handler) intr_mptr[intr] = NULL; intr_mask[intr] = HWI_MASK | SWI_MASK; intr_unit[intr] = intr; +#ifdef FAST_HI_XXX + /* XXX how do I re-create dvp here? */ + setidt(flags & INTR_FAST ? TPR_FAST_INTS + intr : TPR_SLOW_INTS + intr, + slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#else /* FAST_HI */ setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* FAST_HI */ + MPINTR_UNLOCK(); write_eflags(ef); return (0); } diff --git a/sys/i386/isa/nmi.c b/sys/i386/isa/nmi.c index c9b5da5..fd836dd 100644 --- a/sys/i386/isa/nmi.c +++ b/sys/i386/isa/nmi.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.1 1997/08/29 18:38:35 smp Exp smp $ + * $Id: intr_machdep.c,v 1.5 1997/08/29 18:45:19 fsmp Exp $ */ #include "opt_auto_eoi.h" @@ -451,6 +451,7 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ INTREN(1 << intr); + MPINTR_UNLOCK(); write_eflags(ef); return (0); } @@ -487,8 +488,15 @@ icu_unset(intr, handler) intr_mptr[intr] = NULL; intr_mask[intr] = HWI_MASK | SWI_MASK; intr_unit[intr] = intr; +#ifdef FAST_HI_XXX + /* XXX how do I re-create dvp here? */ + setidt(flags & INTR_FAST ? TPR_FAST_INTS + intr : TPR_SLOW_INTS + intr, + slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#else /* FAST_HI */ setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); +#endif /* FAST_HI */ + MPINTR_UNLOCK(); write_eflags(ef); return (0); } diff --git a/sys/i386/isa/sio.c b/sys/i386/isa/sio.c index 62300b6..7555e2f 100644 --- a/sys/i386/isa/sio.c +++ b/sys/i386/isa/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.5 1997/08/21 06:08:45 smp Exp smp $ + * $Id: sio.c,v 1.8 1997/08/30 01:23:40 smp Exp smp $ */ #include "opt_comconsole.h" @@ -65,6 +65,11 @@ #endif #include <machine/clock.h> +#ifdef SMP +#include <machine/smp.h> +#else +#define POSTCODE_HI(X) +#endif #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> @@ -559,11 +564,11 @@ static int card_intr(struct pccard_dev *dp) { struct com_s *com; - COM_LOCK(); + MPINTR_LOCK(); com = com_addr(dp->isahd.id_unit); if (com && !com_addr(dp->isahd.id_unit)->gone) siointr1(com_addr(dp->isahd.id_unit)); - COM_UNLOCK(); + MPINTR_UNLOCK(); return(1); } #endif /* NCRD > 0 */ @@ -644,7 +649,9 @@ sioprobe(dev) * but mask them in the processor as well in case there are some * (misconfigured) shared interrupts. */ + POSTCODE_HI(0x8); disable_intr(); + POSTCODE_HI(0x9); /* EXTRA DELAY? */ /* @@ -750,7 +757,9 @@ sioprobe(dev) failures[8] = isa_irq_pending(idev) ? 1 : 0; failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND; + POSTCODE_HI(0xa); enable_intr(); + POSTCODE_HI(0xb); result = IO_COMSIZE; for (fn = 0; fn < sizeof failures; ++fn) @@ -1185,14 +1194,12 @@ open_top: } disable_intr(); - COM_LOCK(); (void) inb(com->line_status_port); (void) inb(com->data_port); com->prev_modem_status = com->last_modem_status = inb(com->modem_status_port); outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC); - COM_UNLOCK(); enable_intr(); /* * Handle initial DCD. Callout devices get a fake initial @@ -1421,9 +1428,9 @@ siointr(unit) int unit; { #ifndef COM_MULTIPORT - COM_LOCK(); + MPINTR_LOCK(); siointr1(com_addr(unit)); - COM_UNLOCK(); + MPINTR_UNLOCK(); #else /* COM_MULTIPORT */ struct com_s *com; bool_t possibly_more_intrs; @@ -1435,11 +1442,15 @@ siointr(unit) * devices, then the edge from one may be lost because another is * on. */ - COM_LOCK(); + MPINTR_LOCK(); do { possibly_more_intrs = FALSE; for (unit = 0; unit < NSIO; ++unit) { com = com_addr(unit); + /* + * XXX MPINTR_LOCK(); + * would it work here, or be counter-productive? + */ if (com != NULL && !com->gone && (inb(com->int_id_port) & IIR_IMASK) @@ -1447,9 +1458,10 @@ siointr(unit) siointr1(com); possibly_more_intrs = TRUE; } + /* XXX MPINTR_UNLOCK(); */ } } while (possibly_more_intrs); - COM_UNLOCK(); + MPINTR_UNLOCK(); #endif /* COM_MULTIPORT */ } @@ -1829,7 +1841,6 @@ repeat: * loop. */ disable_intr(); - COM_LOCK(); incc = com->iptr - com->ibuf; com->iptr = com->ibuf; if (com->state & CS_CHECKMSR) { @@ -1837,7 +1848,6 @@ repeat: com->state &= ~CS_CHECKMSR; } com_events -= incc; - COM_UNLOCK(); enable_intr(); if (incc != 0) log(LOG_DEBUG, @@ -1853,7 +1863,6 @@ repeat: } else { buf = ibuf; disable_intr(); - COM_LOCK(); incc = com->iptr - buf; com_events -= incc; if (ibuf == com->ibuf1) @@ -1874,7 +1883,6 @@ repeat: && !(tp->t_state & TS_TBLOCK)) outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); - COM_UNLOCK(); enable_intr(); com->ibuf = ibuf; } @@ -1883,13 +1891,11 @@ repeat: u_char delta_modem_status; disable_intr(); - COM_LOCK(); delta_modem_status = com->last_modem_status ^ com->prev_modem_status; com->prev_modem_status = com->last_modem_status; com_events -= LOTS_OF_EVENTS; com->state &= ~CS_CHECKMSR; - COM_UNLOCK(); enable_intr(); if (delta_modem_status & MSR_DCD) (*linesw[tp->t_line].l_modem) @@ -1897,10 +1903,8 @@ repeat: } if (com->state & CS_ODONE) { disable_intr(); - COM_LOCK(); com_events -= LOTS_OF_EVENTS; com->state &= ~CS_ODONE; - COM_UNLOCK(); enable_intr(); if (!(com->state & CS_BUSY) && !(com->extra_state & CSE_BUSYCHECK)) { @@ -2056,11 +2060,9 @@ comparam(tp, t) * error bits, but that is acceptable here. */ disable_intr(); - COM_LOCK(); retry: com->state &= ~CS_TTGO; txtimeout = tp->t_timeout; - COM_UNLOCK(); enable_intr(); while ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY)) != (LSR_TSRE | LSR_TXRDY)) { @@ -2077,9 +2079,7 @@ retry: if (error != 0 && error != EAGAIN) { if (!(tp->t_state & TS_TTSTOP)) { disable_intr(); - COM_LOCK(); com->state |= CS_TTGO; - COM_UNLOCK(); enable_intr(); } splx(s); @@ -2088,7 +2088,6 @@ retry: } disable_intr(); /* very important while com_data is hidden */ - COM_LOCK(); /* * XXX - clearing CS_TTGO is not sufficient to stop further output, @@ -2184,7 +2183,6 @@ retry: if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); - COM_UNLOCK(); enable_intr(); splx(s); comstart(tp); @@ -2203,7 +2201,6 @@ comstart(tp) com = com_addr(unit); s = spltty(); disable_intr(); - COM_LOCK(); if (tp->t_state & TS_TTSTOP) com->state &= ~CS_TTGO; else @@ -2216,7 +2213,6 @@ comstart(tp) && com->state & CS_RTS_IFLOW) outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); } - COM_UNLOCK(); enable_intr(); if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { splx(s); @@ -2233,7 +2229,6 @@ comstart(tp) com->obufs[0].l_next = NULL; com->obufs[0].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2245,7 +2240,6 @@ comstart(tp) com->obufq.l_next = &com->obufs[0]; com->state |= CS_BUSY; } - COM_UNLOCK(); enable_intr(); } if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { @@ -2255,7 +2249,6 @@ comstart(tp) com->obufs[1].l_next = NULL; com->obufs[1].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2267,16 +2260,13 @@ comstart(tp) com->obufq.l_next = &com->obufs[1]; com->state |= CS_BUSY; } - COM_UNLOCK(); enable_intr(); } tp->t_state |= TS_BUSY; } disable_intr(); - COM_LOCK(); if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); /* fake interrupt to start output */ - COM_UNLOCK(); enable_intr(); ttwwakeup(tp); splx(s); @@ -2293,7 +2283,6 @@ siostop(tp, rw) if (com->gone) return; disable_intr(); - COM_LOCK(); if (rw & FWRITE) { if (com->hasfifo) #ifdef COM_ESP @@ -2322,7 +2311,6 @@ siostop(tp, rw) com_events -= (com->iptr - com->ibuf); com->iptr = com->ibuf; } - COM_UNLOCK(); enable_intr(); comstart(tp); } @@ -2383,7 +2371,6 @@ commctl(com, bits, how) if (com->gone) return(0); disable_intr(); - COM_LOCK(); switch (how) { case DMSET: outb(com->modem_ctl_port, @@ -2396,7 +2383,6 @@ commctl(com, bits, how) outb(com->modem_ctl_port, com->mcr_image &= ~mcr); break; } - COM_UNLOCK(); enable_intr(); return (0); } @@ -2456,9 +2442,7 @@ comwakeup(chan) if (com != NULL && !com->gone && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { disable_intr(); - COM_LOCK(); siointr1(com); - COM_UNLOCK(); enable_intr(); } } @@ -2482,10 +2466,8 @@ comwakeup(chan) u_long total; disable_intr(); - COM_LOCK(); delta = com->delta_error_counts[errnum]; com->delta_error_counts[errnum] = 0; - COM_UNLOCK(); enable_intr(); if (delta == 0) continue; diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index 28f6dc9..0755baf 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.99 1997/08/21 05:08:07 fsmp Exp $ + * $Id: clock.c,v 1.10 1997/08/30 01:23:40 smp Exp smp $ */ /* @@ -65,9 +65,9 @@ #include <machine/frame.h> #include <machine/ipl.h> #include <machine/limits.h> -#ifdef APIC_IO +#if defined(SMP) || defined(APIC_IO) #include <machine/smp.h> -#endif /* APIC_IO */ +#endif /* SMP || APIC_IO */ #include <i386/isa/icu.h> #include <i386/isa/isa.h> @@ -77,6 +77,34 @@ #include <i386/isa/intr_machdep.h> #include <sys/interrupt.h> +#ifdef SMP +#include <machine/smptests.h> + +#ifdef SIMPLE_MPINTRLOCK +#define DISABLE_INTR() \ + __asm __volatile("cli" : : : "memory"); \ + s_lock(&clock_lock); + +#define ENABLE_INTR() \ + s_unlock(&clock_lock); \ + __asm __volatile("sti"); + +#define CLOCK_UNLOCK() \ + s_unlock(&clock_lock); +#else /* SIMPLE_MPINTRLOCK */ +#define DISABLE_INTR() disable_intr() +#define ENABLE_INTR() enable_intr() +#define CLOCK_UNLOCK() +#endif /* SIMPLE_MPINTRLOCK */ + +#else /* SMP */ + +#define DISABLE_INTR() disable_intr() +#define ENABLE_INTR() enable_intr() +#define CLOCK_UNLOCK() + +#endif /* SMP */ + /* * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we * can use a simple formula for leap years. @@ -183,11 +211,11 @@ clkintr(struct clockframe frame) timer0_max_count = TIMER_DIV(new_rate); timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; - disable_intr(); + DISABLE_INTR(); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - enable_intr(); + ENABLE_INTR(); timer0_prescaler_count = 0; timer_func = new_function; timer0_state = ACQUIRED; @@ -201,12 +229,12 @@ clkintr(struct clockframe frame) timer0_max_count = hardclock_max_count; timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; - disable_intr(); + DISABLE_INTR(); outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); - enable_intr(); + ENABLE_INTR(); /* * See microtime.s for this magic. */ @@ -358,7 +386,7 @@ getit(void) int high, low; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); /* Select timer0 and latch counter value. */ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); @@ -366,6 +394,7 @@ getit(void) low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); + CLOCK_UNLOCK(); write_eflags(ef); return ((high << 8) | low); } @@ -480,10 +509,10 @@ sysbeep(int pitch, int period) splx(x); return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */ } - disable_intr(); + DISABLE_INTR(); outb(TIMER_CNTR2, pitch); outb(TIMER_CNTR2, (pitch>>8)); - enable_intr(); + ENABLE_INTR(); if (!beeping) { /* enable counter2 output to speaker */ outb(IO_PPI, inb(IO_PPI) | 3); @@ -626,13 +655,14 @@ set_timer_freq(u_int freq, int intr_freq) u_long ef; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); timer_freq = freq; timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq); timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT; outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); outb(TIMER_CNTR0, timer0_max_count & 0xff); outb(TIMER_CNTR0, timer0_max_count >> 8); + CLOCK_UNLOCK(); write_eflags(ef); } @@ -1002,10 +1032,11 @@ set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq) << I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq; multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq; ef = read_eflags(); - disable_intr(); + DISABLE_INTR(); i586_ctr_freq = i586_freq; i586_ctr_comultiplier = comultiplier; i586_ctr_multiplier = multiplier; + CLOCK_UNLOCK(); write_eflags(ef); } diff --git a/sys/isa/sio.c b/sys/isa/sio.c index 62300b6..7555e2f 100644 --- a/sys/isa/sio.c +++ b/sys/isa/sio.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * $Id: sio.c,v 1.5 1997/08/21 06:08:45 smp Exp smp $ + * $Id: sio.c,v 1.8 1997/08/30 01:23:40 smp Exp smp $ */ #include "opt_comconsole.h" @@ -65,6 +65,11 @@ #endif #include <machine/clock.h> +#ifdef SMP +#include <machine/smp.h> +#else +#define POSTCODE_HI(X) +#endif #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> @@ -559,11 +564,11 @@ static int card_intr(struct pccard_dev *dp) { struct com_s *com; - COM_LOCK(); + MPINTR_LOCK(); com = com_addr(dp->isahd.id_unit); if (com && !com_addr(dp->isahd.id_unit)->gone) siointr1(com_addr(dp->isahd.id_unit)); - COM_UNLOCK(); + MPINTR_UNLOCK(); return(1); } #endif /* NCRD > 0 */ @@ -644,7 +649,9 @@ sioprobe(dev) * but mask them in the processor as well in case there are some * (misconfigured) shared interrupts. */ + POSTCODE_HI(0x8); disable_intr(); + POSTCODE_HI(0x9); /* EXTRA DELAY? */ /* @@ -750,7 +757,9 @@ sioprobe(dev) failures[8] = isa_irq_pending(idev) ? 1 : 0; failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND; + POSTCODE_HI(0xa); enable_intr(); + POSTCODE_HI(0xb); result = IO_COMSIZE; for (fn = 0; fn < sizeof failures; ++fn) @@ -1185,14 +1194,12 @@ open_top: } disable_intr(); - COM_LOCK(); (void) inb(com->line_status_port); (void) inb(com->data_port); com->prev_modem_status = com->last_modem_status = inb(com->modem_status_port); outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC); - COM_UNLOCK(); enable_intr(); /* * Handle initial DCD. Callout devices get a fake initial @@ -1421,9 +1428,9 @@ siointr(unit) int unit; { #ifndef COM_MULTIPORT - COM_LOCK(); + MPINTR_LOCK(); siointr1(com_addr(unit)); - COM_UNLOCK(); + MPINTR_UNLOCK(); #else /* COM_MULTIPORT */ struct com_s *com; bool_t possibly_more_intrs; @@ -1435,11 +1442,15 @@ siointr(unit) * devices, then the edge from one may be lost because another is * on. */ - COM_LOCK(); + MPINTR_LOCK(); do { possibly_more_intrs = FALSE; for (unit = 0; unit < NSIO; ++unit) { com = com_addr(unit); + /* + * XXX MPINTR_LOCK(); + * would it work here, or be counter-productive? + */ if (com != NULL && !com->gone && (inb(com->int_id_port) & IIR_IMASK) @@ -1447,9 +1458,10 @@ siointr(unit) siointr1(com); possibly_more_intrs = TRUE; } + /* XXX MPINTR_UNLOCK(); */ } } while (possibly_more_intrs); - COM_UNLOCK(); + MPINTR_UNLOCK(); #endif /* COM_MULTIPORT */ } @@ -1829,7 +1841,6 @@ repeat: * loop. */ disable_intr(); - COM_LOCK(); incc = com->iptr - com->ibuf; com->iptr = com->ibuf; if (com->state & CS_CHECKMSR) { @@ -1837,7 +1848,6 @@ repeat: com->state &= ~CS_CHECKMSR; } com_events -= incc; - COM_UNLOCK(); enable_intr(); if (incc != 0) log(LOG_DEBUG, @@ -1853,7 +1863,6 @@ repeat: } else { buf = ibuf; disable_intr(); - COM_LOCK(); incc = com->iptr - buf; com_events -= incc; if (ibuf == com->ibuf1) @@ -1874,7 +1883,6 @@ repeat: && !(tp->t_state & TS_TBLOCK)) outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); - COM_UNLOCK(); enable_intr(); com->ibuf = ibuf; } @@ -1883,13 +1891,11 @@ repeat: u_char delta_modem_status; disable_intr(); - COM_LOCK(); delta_modem_status = com->last_modem_status ^ com->prev_modem_status; com->prev_modem_status = com->last_modem_status; com_events -= LOTS_OF_EVENTS; com->state &= ~CS_CHECKMSR; - COM_UNLOCK(); enable_intr(); if (delta_modem_status & MSR_DCD) (*linesw[tp->t_line].l_modem) @@ -1897,10 +1903,8 @@ repeat: } if (com->state & CS_ODONE) { disable_intr(); - COM_LOCK(); com_events -= LOTS_OF_EVENTS; com->state &= ~CS_ODONE; - COM_UNLOCK(); enable_intr(); if (!(com->state & CS_BUSY) && !(com->extra_state & CSE_BUSYCHECK)) { @@ -2056,11 +2060,9 @@ comparam(tp, t) * error bits, but that is acceptable here. */ disable_intr(); - COM_LOCK(); retry: com->state &= ~CS_TTGO; txtimeout = tp->t_timeout; - COM_UNLOCK(); enable_intr(); while ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY)) != (LSR_TSRE | LSR_TXRDY)) { @@ -2077,9 +2079,7 @@ retry: if (error != 0 && error != EAGAIN) { if (!(tp->t_state & TS_TTSTOP)) { disable_intr(); - COM_LOCK(); com->state |= CS_TTGO; - COM_UNLOCK(); enable_intr(); } splx(s); @@ -2088,7 +2088,6 @@ retry: } disable_intr(); /* very important while com_data is hidden */ - COM_LOCK(); /* * XXX - clearing CS_TTGO is not sufficient to stop further output, @@ -2184,7 +2183,6 @@ retry: if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); - COM_UNLOCK(); enable_intr(); splx(s); comstart(tp); @@ -2203,7 +2201,6 @@ comstart(tp) com = com_addr(unit); s = spltty(); disable_intr(); - COM_LOCK(); if (tp->t_state & TS_TTSTOP) com->state &= ~CS_TTGO; else @@ -2216,7 +2213,6 @@ comstart(tp) && com->state & CS_RTS_IFLOW) outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); } - COM_UNLOCK(); enable_intr(); if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { splx(s); @@ -2233,7 +2229,6 @@ comstart(tp) com->obufs[0].l_next = NULL; com->obufs[0].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2245,7 +2240,6 @@ comstart(tp) com->obufq.l_next = &com->obufs[0]; com->state |= CS_BUSY; } - COM_UNLOCK(); enable_intr(); } if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { @@ -2255,7 +2249,6 @@ comstart(tp) com->obufs[1].l_next = NULL; com->obufs[1].l_queued = TRUE; disable_intr(); - COM_LOCK(); if (com->state & CS_BUSY) { qp = com->obufq.l_next; while ((next = qp->l_next) != NULL) @@ -2267,16 +2260,13 @@ comstart(tp) com->obufq.l_next = &com->obufs[1]; com->state |= CS_BUSY; } - COM_UNLOCK(); enable_intr(); } tp->t_state |= TS_BUSY; } disable_intr(); - COM_LOCK(); if (com->state >= (CS_BUSY | CS_TTGO)) siointr1(com); /* fake interrupt to start output */ - COM_UNLOCK(); enable_intr(); ttwwakeup(tp); splx(s); @@ -2293,7 +2283,6 @@ siostop(tp, rw) if (com->gone) return; disable_intr(); - COM_LOCK(); if (rw & FWRITE) { if (com->hasfifo) #ifdef COM_ESP @@ -2322,7 +2311,6 @@ siostop(tp, rw) com_events -= (com->iptr - com->ibuf); com->iptr = com->ibuf; } - COM_UNLOCK(); enable_intr(); comstart(tp); } @@ -2383,7 +2371,6 @@ commctl(com, bits, how) if (com->gone) return(0); disable_intr(); - COM_LOCK(); switch (how) { case DMSET: outb(com->modem_ctl_port, @@ -2396,7 +2383,6 @@ commctl(com, bits, how) outb(com->modem_ctl_port, com->mcr_image &= ~mcr); break; } - COM_UNLOCK(); enable_intr(); return (0); } @@ -2456,9 +2442,7 @@ comwakeup(chan) if (com != NULL && !com->gone && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { disable_intr(); - COM_LOCK(); siointr1(com); - COM_UNLOCK(); enable_intr(); } } @@ -2482,10 +2466,8 @@ comwakeup(chan) u_long total; disable_intr(); - COM_LOCK(); delta = com->delta_error_counts[errnum]; com->delta_error_counts[errnum] = 0; - COM_UNLOCK(); enable_intr(); if (delta == 0) continue; diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index d5ea71c..955a3a1 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.46 1997/08/26 18:10:31 peter Exp $ + * $Id: mp_machdep.c,v 1.32 1997/08/30 01:25:13 smp Exp smp $ */ #include "opt_smp.h" @@ -1446,8 +1446,16 @@ struct simplelock fast_intr_lock; /* critical region around INTR() routines */ struct simplelock intr_lock; +#ifdef SIMPLE_MPINTRLOCK +/* critical region around INTR() routines */ +struct simplelock mpintr_lock; +struct simplelock clock_lock; +#endif + +#if 0 /* lock the com (tty) data structures */ struct simplelock com_lock; +#endif static void init_locks(void) @@ -1459,7 +1467,13 @@ init_locks(void) mp_lock = 0x00000001; /* ISR uses its own "giant lock" */ - isr_lock = 0x00000000; + isr_lock = FREE_LOCK; + +#ifdef SIMPLE_MPINTRLOCK + /* lock regions protected in UP kernel via cli/sti */ + s_lock_init((struct simplelock*)&mpintr_lock); + s_lock_init((struct simplelock*)&clock_lock); +#endif /* serializes FAST_INTR() accesses */ s_lock_init((struct simplelock*)&fast_intr_lock); @@ -1470,11 +1484,13 @@ init_locks(void) /* locks the IO APIC and apic_imen accesses */ s_lock_init((struct simplelock*)&imen_lock); - /* locks cpl accesses */ + /* locks cpl/cml/cim/ipending accesses */ s_lock_init((struct simplelock*)&cpl_lock); +#if 0 /* locks com (tty) data/hardware accesses: a FASTINTR() */ s_lock_init((struct simplelock*)&com_lock); +#endif } diff --git a/sys/sys/smp.h b/sys/sys/smp.h index 276b838..a7051ff 100644 --- a/sys/sys/smp.h +++ b/sys/sys/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.29 1997/08/24 20:33:24 fsmp Exp $ + * $Id: smp.h,v 1.30 1997/08/26 18:10:37 peter Exp $ * */ @@ -60,11 +60,19 @@ void bootMP __P((void)); /* global data in mplock.s */ extern u_int mp_lock; extern u_int isr_lock; +#ifdef RECURSIVE_MPINTRLOCK +extern u_int mpintr_lock; +#endif /* RECURSIVE_MPINTRLOCK */ /* functions in mplock.s */ void get_mplock __P((void)); void rel_mplock __P((void)); void try_mplock __P((void)); +#ifdef RECURSIVE_MPINTRLOCK +void get_mpintrlock __P((void)); +void rel_mpintrlock __P((void)); +void try_mpintrlock __P((void)); +#endif /* RECURSIVE_MPINTRLOCK */ /* global data in apic_vector.s */ extern u_int ivectors[]; |