summaryrefslogtreecommitdiffstats
path: root/sys/isa
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/isa
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/isa')
-rw-r--r--sys/isa/atrtc.c55
-rw-r--r--sys/isa/sio.c60
2 files changed, 64 insertions, 51 deletions
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;
OpenPOWER on IntegriCloud