summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/clock.c
diff options
context:
space:
mode:
authorfsmp <fsmp@FreeBSD.org>1997-08-30 08:08:10 +0000
committerfsmp <fsmp@FreeBSD.org>1997-08-30 08:08:10 +0000
commite2310cdbcf324f3bbeda76add82e773d37ee43cd (patch)
treeab2ac308116ca3f26a9055eae17d100d5901e501 /sys/i386/isa/clock.c
parent62dbf14e9ad4dbe9bc03c2657d854b47ef4b3f65 (diff)
downloadFreeBSD-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/i386/isa/clock.c')
-rw-r--r--sys/i386/isa/clock.c55
1 files changed, 43 insertions, 12 deletions
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);
}
OpenPOWER on IntegriCloud