summaryrefslogtreecommitdiff
path: root/sys/arch/mac68k
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-03-15 20:40:26 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-03-15 20:40:26 +0000
commita70ea7a0d41fc23f193e4cf52f9f81bf20011a83 (patch)
treed6b65e33edd85a3981e395f10b4fd50db5e2107e /sys/arch/mac68k
parent696ab5f08e3725e54a7b87f6c7f732871cea9473 (diff)
Generic softinterrupt code for m68k platforms, now copied from m88k.
Diffstat (limited to 'sys/arch/mac68k')
-rw-r--r--sys/arch/mac68k/dev/adb.c73
-rw-r--r--sys/arch/mac68k/dev/if_sn.c3
-rw-r--r--sys/arch/mac68k/dev/z8530sc.c75
-rw-r--r--sys/arch/mac68k/dev/z8530sc.h4
-rw-r--r--sys/arch/mac68k/dev/z8530tty.c50
-rw-r--r--sys/arch/mac68k/dev/zs.c83
-rw-r--r--sys/arch/mac68k/include/intr.h25
-rw-r--r--sys/arch/mac68k/include/z8530var.h3
-rw-r--r--sys/arch/mac68k/mac68k/autoconf.c5
-rw-r--r--sys/arch/mac68k/mac68k/intr.c27
-rw-r--r--sys/arch/mac68k/mac68k/locore.s14
-rw-r--r--sys/arch/mac68k/mac68k/trap.c37
-rw-r--r--sys/arch/mac68k/mac68k/via.c5
13 files changed, 175 insertions, 229 deletions
diff --git a/sys/arch/mac68k/dev/adb.c b/sys/arch/mac68k/dev/adb.c
index 0792b3b3e34..35e6700950b 100644
--- a/sys/arch/mac68k/dev/adb.c
+++ b/sys/arch/mac68k/dev/adb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: adb.c,v 1.26 2007/04/10 17:47:54 miod Exp $ */
+/* $OpenBSD: adb.c,v 1.27 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: adb.c,v 1.47 2005/06/16 22:43:36 jmc Exp $ */
/* $NetBSD: adb_direct.c,v 1.51 2005/06/16 22:43:36 jmc Exp $ */
@@ -113,6 +113,11 @@ int adb_polling; /* Are we polling? (Debugger mode) */
int adb_debug; /* Output debugging messages */
#endif /* ADB_DEBUG */
+struct adb_softc {
+ struct device sc_dev;
+ void *sc_softih;
+};
+
/* some misc. leftovers */
#define vPB 0x0000
#define vPB3 0x08
@@ -298,7 +303,7 @@ int adb_intr(void *);
int adb_intr_II(void *);
int adb_intr_IIsi(void *);
int adb_intr_cuda(void *);
-void adb_soft_intr(void);
+void adb_soft_intr(void *);
int send_adb_II(u_char *, u_char *, void *, void *, int);
int send_adb_IIsi(u_char *, u_char *, void *, void *, int);
int send_adb_cuda(u_char *, u_char *, void *, void *, int);
@@ -306,14 +311,14 @@ void adb_intr_cuda_test(void);
void adb_cuda_tickle(void);
void adb_pass_up(struct adbCommand *);
void adb_op_comprout(caddr_t, caddr_t, int);
-void adb_reinit(struct device *);
+void adb_reinit(struct adb_softc *);
int count_adbs(void);
int get_ind_adb_info(ADBDataBlock *, int);
int get_adb_info(ADBDataBlock *, int);
void adb_setup_hw_type(void);
int adb_op(Ptr, Ptr, Ptr, short);
void adb_read_II(u_char *);
-void adb_hw_setup(struct device *);
+void adb_hw_setup(struct adb_softc *);
void adb_hw_setup_IIsi(u_char *);
int adb_cmd_result(u_char *);
int adb_guess_next_device(void);
@@ -394,7 +399,7 @@ adb_intr_cuda(void *arg)
struct adbCommand packet;
s = splhigh(); /* can't be too careful - might be called */
- /* from a routine, NOT an interrupt */
+ /* from a routine, NOT an interrupt */
ADB_VIA_CLR_INTR(); /* clear interrupt */
ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
@@ -608,7 +613,7 @@ switch_start:
splx(s); /* restore */
return (1);
-} /* end adb_intr_cuda */
+}
int
@@ -696,12 +701,12 @@ send_adb_cuda(u_char *in, u_char *buffer, void *compRout, void *data, int
if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
adb_intr_cuda(NULL); /* go process it */
if (adb_polling)
- adb_soft_intr();
+ adb_soft_intr(NULL);
}
}
return 0;
-} /* send_adb_cuda */
+}
int
@@ -1139,7 +1144,7 @@ send_adb_II(u_char *in, u_char *buffer, void *compRout, void *data, int command)
if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
adb_intr_II(NULL); /* go process it */
if (adb_polling)
- adb_soft_intr();
+ adb_soft_intr(NULL);
}
}
@@ -1418,7 +1423,7 @@ switch_start:
splx(s); /* restore */
return (1);
-} /* end adb_intr_IIsi */
+}
/*****************************************************************************
@@ -1512,12 +1517,12 @@ send_adb_IIsi(u_char *in, u_char *buffer, void *compRout, void *data, int
if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
adb_intr_IIsi(NULL); /* go process it */
if (adb_polling)
- adb_soft_intr();
+ adb_soft_intr(NULL);
}
}
- return 0;
-} /* send_adb_IIsi */
+ return 0;
+}
/*
* adb_pass_up is called by the interrupt-time routines.
@@ -1546,6 +1551,8 @@ send_adb_IIsi(u_char *in, u_char *buffer, void *compRout, void *data, int
void
adb_pass_up(struct adbCommand *in)
{
+ extern struct cfdriver adb_cd;
+ struct adb_softc *sc;
int start = 0, len = 0, cmd = 0;
ADBDataBlock block;
@@ -1650,10 +1657,14 @@ adb_pass_up(struct adbCommand *in)
* If the debugger is running, call upper half manually.
* Otherwise, trigger a soft interrupt to handle the rest later.
*/
- if (adb_polling)
- adb_soft_intr();
+ if (adb_cd.cd_ndevs != 0)
+ sc = (struct adb_softc *)adb_cd.cd_devs[0];
+ else
+ sc = NULL;
+ if (adb_polling || sc == NULL || sc->sc_softih == NULL)
+ adb_soft_intr(NULL);
else
- setsoftadb();
+ softintr_schedule(sc->sc_softih);
}
@@ -1663,7 +1674,7 @@ adb_pass_up(struct adbCommand *in)
*
*/
void
-adb_soft_intr(void)
+adb_soft_intr(void *arg)
{
int s;
int cmd = 0;
@@ -1803,14 +1814,14 @@ adb_op(Ptr buffer, Ptr compRout, Ptr data, short command)
* config (mainly VIA settings) for the various models.
*/
void
-adb_hw_setup(struct device *self)
+adb_hw_setup(struct adb_softc *sc)
{
volatile int i;
u_char send_string[ADB_MAX_MSG_LENGTH];
switch (adbHardware) {
case ADB_HW_II:
- via1_register_irq(2, adb_intr_II, self, self->dv_xname);
+ via1_register_irq(2, adb_intr_II, sc, sc->sc_dev.dv_xname);
via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
* outputs */
@@ -1829,7 +1840,7 @@ adb_hw_setup(struct device *self)
break;
case ADB_HW_IISI:
- via1_register_irq(2, adb_intr_IIsi, self, self->dv_xname);
+ via1_register_irq(2, adb_intr_IIsi, sc, sc->sc_dev.dv_xname);
via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
* outputs */
via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */
@@ -1864,11 +1875,11 @@ adb_hw_setup(struct device *self)
* XXX - really PM_VIA_CLR_INTR - should we put it in
* pm_direct.h?
*/
- pm_hw_setup(self);
+ pm_hw_setup(&sc->sc_dev);
break;
case ADB_HW_CUDA:
- via1_register_irq(2, adb_intr_cuda, self, self->dv_xname);
+ via1_register_irq(2, adb_intr_cuda, sc, sc->sc_dev.dv_xname);
via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
* outputs */
via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */
@@ -1979,7 +1990,7 @@ adb_hw_setup_IIsi(u_char *buffer)
*
*/
void
-adb_reinit(struct device *self)
+adb_reinit(struct adb_softc *sc)
{
u_char send_string[ADB_MAX_MSG_LENGTH];
ADBDataBlock data; /* temp. holder for getting device info */
@@ -2012,7 +2023,7 @@ adb_reinit(struct device *self)
ADBDevTable[i].origAddr = ADBDevTable[i].currentAddr = 0;
}
- adb_hw_setup(self); /* init the VIA bits and hard reset ADB */
+ adb_hw_setup(sc); /* init the VIA bits and hard reset ADB */
delay(1000);
@@ -2494,7 +2505,6 @@ set_adb_info(ADBSetInfoBlock *info, int adbAddr)
}
return (-1); /* not found */
-
}
/* caller should really use machine-independant version: getPramTime */
@@ -2741,8 +2751,9 @@ void adb_attach_deferred(void *);
/*
* Driver definition.
*/
+
struct cfattach adb_ca = {
- sizeof(struct device), adbmatch, adbattach
+ sizeof(struct adb_softc), adbmatch, adbattach
};
int
@@ -2769,15 +2780,15 @@ adbattach(struct device *parent, struct device *self, void *aux)
void
adb_attach_deferred(void *v)
{
- struct device *self = v;
+ struct adb_softc *sc = v;
ADBDataBlock adbdata;
struct adb_attach_args aa_args;
int totaladbs;
int adbindex, adbaddr;
- printf("%s: ", self->dv_xname);
+ printf("%s: ", sc->sc_dev.dv_xname);
adb_polling = 1;
- adb_reinit(self);
+ adb_reinit(sc);
#ifdef ADB_DEBUG
if (adb_debug)
@@ -2797,7 +2808,9 @@ adb_attach_deferred(void *v)
aa_args.adbaddr = adbaddr;
aa_args.handler_id = (int)(adbdata.devType);
- (void)config_found(self, &aa_args, adbprint);
+ (void)config_found(&sc->sc_dev, &aa_args, adbprint);
}
+
+ sc->sc_softih = softintr_establish(IPL_SOFTTTY, adb_soft_intr, NULL);
adb_polling = 0;
}
diff --git a/sys/arch/mac68k/dev/if_sn.c b/sys/arch/mac68k/dev/if_sn.c
index 537eca51026..3a9bca02128 100644
--- a/sys/arch/mac68k/dev/if_sn.c
+++ b/sys/arch/mac68k/dev/if_sn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sn.c,v 1.50 2008/11/28 02:44:17 brad Exp $ */
+/* $OpenBSD: if_sn.c,v 1.51 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: if_sn.c,v 1.13 1997/04/25 03:40:10 briggs Exp $ */
/*
@@ -29,7 +29,6 @@
#include <net/if.h>
#include <net/if_dl.h>
-#include <net/netisr.h>
#ifdef INET
#include <netinet/in.h>
diff --git a/sys/arch/mac68k/dev/z8530sc.c b/sys/arch/mac68k/dev/z8530sc.c
index 6ec3fef5ac6..28976cb10dc 100644
--- a/sys/arch/mac68k/dev/z8530sc.c
+++ b/sys/arch/mac68k/dev/z8530sc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: z8530sc.c,v 1.7 2004/11/25 18:32:10 miod Exp $ */
+/* $OpenBSD: z8530sc.c,v 1.8 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: z8530sc.c,v 1.5 1996/12/17 20:42:40 gwr Exp $ */
/*
@@ -229,69 +229,60 @@ zsc_intr_hard(arg)
void *arg;
{
register struct zsc_softc *zsc = arg;
- register struct zs_chanstate *cs_a;
- register struct zs_chanstate *cs_b;
- register int rval;
- register u_char rr3, rr3a;
-
- cs_a = zsc->zsc_cs[0];
- cs_b = zsc->zsc_cs[1];
- rval = 0;
- rr3a = 0;
+ register struct zs_chanstate *cs;
+ register u_char rr3;
+ /* First look at channel A. */
+ cs = zsc->zsc_cs[0];
/* Note: only channel A has an RR3 */
- while ((rr3 = zs_read_reg(cs_a, 3)) != 0) {
+ rr3 = zs_read_reg(cs, 3);
- /* Handle receive interrupts first. */
+ /*
+ * Clear interrupt first to avoid a race condition.
+ * If a new interrupt condition happens while we are
+ * servicing this one, we will get another interrupt
+ * shortly. We can NOT just sit here in a loop, or
+ * we will cause horrible latency for other devices
+ * on this interrupt level (i.e. sun3x floppy disk).
+ */
+ if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
+ zs_write_csr(cs, ZSWR0_CLR_INTR);
if (rr3 & ZSRR3_IP_A_RX)
- (*cs_a->cs_ops->zsop_rxint)(cs_a);
- if (rr3 & ZSRR3_IP_B_RX)
- (*cs_b->cs_ops->zsop_stint)(cs_b);
-
- /* Handle status interrupts (i.e. flow control). */
+ (*cs->cs_ops->zsop_rxint)(cs);
if (rr3 & ZSRR3_IP_A_STAT)
- (*cs_a->cs_ops->zsop_stint)(cs_a);
- if (rr3 & ZSRR3_IP_B_STAT)
- (*cs_b->cs_ops->zsop_stint)(cs_b);
-
- /* Handle transmit done interrupts. */
+ (*cs->cs_ops->zsop_stint)(cs);
if (rr3 & ZSRR3_IP_A_TX)
- (*cs_a->cs_ops->zsop_txint)(cs_a);
- if (rr3 & ZSRR3_IP_B_TX)
- (*cs_b->cs_ops->zsop_txint)(cs_b);
-
- /* Accumulate so we know what needs to be cleared. */
- rr3a |= rr3;
+ (*cs->cs_ops->zsop_txint)(cs);
}
-
- /* Clear interrupt. */
- if (rr3a & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
- zs_write_csr(cs_a, ZSWR0_CLR_INTR);
- rval |= 1;
- }
- if (rr3a & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
- zs_write_csr(cs_b, ZSWR0_CLR_INTR);
- rval |= 2;
+ /* Now look at channel B. */
+ cs = zsc->zsc_cs[1];
+ if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
+ zs_write_csr(cs, ZSWR0_CLR_INTR);
+ if (rr3 & ZSRR3_IP_B_RX)
+ (*cs->cs_ops->zsop_stint)(cs);
+ if (rr3 & ZSRR3_IP_B_STAT)
+ (*cs->cs_ops->zsop_stint)(cs);
+ if (rr3 & ZSRR3_IP_B_TX)
+ (*cs->cs_ops->zsop_txint)(cs);
}
/* Note: caller will check cs_x->cs_softreq and DTRT. */
- return (rval);
+ return (rr3);
}
/*
* ZS software interrupt. Scan all channels for deferred interrupts.
*/
-int
+void
zsc_intr_soft(arg)
void *arg;
{
register struct zsc_softc *zsc = arg;
register struct zs_chanstate *cs;
- register int rval, chan;
+ register int chan;
- rval = 0;
for (chan = 0; chan < 2; chan++) {
cs = zsc->zsc_cs[chan];
@@ -303,10 +294,8 @@ zsc_intr_soft(arg)
if (cs->cs_softreq) {
cs->cs_softreq = 0;
(*cs->cs_ops->zsop_softint)(cs);
- rval++;
}
}
- return (rval);
}
/*
diff --git a/sys/arch/mac68k/dev/z8530sc.h b/sys/arch/mac68k/dev/z8530sc.h
index 6604c744bff..80a41ed7539 100644
--- a/sys/arch/mac68k/dev/z8530sc.h
+++ b/sys/arch/mac68k/dev/z8530sc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: z8530sc.h,v 1.6 2004/11/25 18:32:10 miod Exp $ */
+/* $OpenBSD: z8530sc.h,v 1.7 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: z8530sc.h,v 1.5 1996/12/17 20:42:42 gwr Exp $ */
/*
@@ -117,7 +117,7 @@ struct zsc_attach_args {
#define ZS_HWFLAG_RAW 8 /* advise raw mode */
int zsc_intr_hard(void *);
-int zsc_intr_soft(void *);
+void zsc_intr_soft(void *);
void zs_abort(struct zs_chanstate *);
void zs_break(struct zs_chanstate *, int);
diff --git a/sys/arch/mac68k/dev/z8530tty.c b/sys/arch/mac68k/dev/z8530tty.c
index c1fc0235e88..246485e76c1 100644
--- a/sys/arch/mac68k/dev/z8530tty.c
+++ b/sys/arch/mac68k/dev/z8530tty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: z8530tty.c,v 1.17 2006/04/14 09:36:49 martin Exp $ */
+/* $OpenBSD: z8530tty.c,v 1.18 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: z8530tty.c,v 1.14 1996/12/17 20:42:43 gwr Exp $ */
/*
@@ -163,20 +163,20 @@ struct zsops zsops_tty;
/* Routines called from other code. */
cdev_decl(zs); /* open, close, read, write, ioctl, stop, ... */
-static void zsstart(struct tty *);
-static int zsparam(struct tty *, struct termios *);
-static void zs_modem(struct zstty_softc *zst, int onoff);
-static int zshwiflow(struct tty *, int);
-static void zs_hwiflow(struct zstty_softc *, int);
-static void zstty_rxint(register struct zs_chanstate *);
-static void zstty_txint(register struct zs_chanstate *);
-static void zstty_stint(register struct zs_chanstate *);
-static void zstty_softint(struct zs_chanstate *);
-static void zsoverrun(struct zstty_softc *, long *, char *);
+void zsstart(struct tty *);
+int zsparam(struct tty *, struct termios *);
+void zs_modem(struct zstty_softc *zst, int onoff);
+int zshwiflow(struct tty *, int);
+void zs_hwiflow(struct zstty_softc *, int);
+void zstty_rxint(register struct zs_chanstate *);
+void zstty_txint(register struct zs_chanstate *);
+void zstty_stint(register struct zs_chanstate *);
+void zstty_softint(struct zs_chanstate *);
+void zsoverrun(struct zstty_softc *, long *, char *);
/*
* zstty_match: how is this zs channel configured?
*/
-int
+static int
zstty_match(parent, match, aux)
struct device *parent;
void *match, *aux;
@@ -195,7 +195,7 @@ zstty_match(parent, match, aux)
return 0;
}
-void
+static void
zstty_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
@@ -609,7 +609,7 @@ zsioctl(dev, cmd, data, flag, p)
/*
* Start or restart transmission.
*/
-static void
+void
zsstart(tp)
register struct tty *tp;
{
@@ -711,7 +711,7 @@ zsstop(tp, flag)
* XXX - Should just copy the whole termios after
* making sure all the changes could be done.
*/
-static int
+int
zsparam(tp, t)
register struct tty *tp;
register struct termios *t;
@@ -857,7 +857,7 @@ zsparam(tp, t)
* Raise or lower modem control (DTR/RTS) signals. If a character is
* in transmission, the change is deferred.
*/
-static void
+void
zs_modem(zst, onoff)
struct zstty_softc *zst;
int onoff;
@@ -941,7 +941,7 @@ zshwiflow(tp, stop)
* Internal version of zshwiflow
* called at splzs
*/
-static void
+void
zs_hwiflow(zst, stop)
register struct zstty_softc *zst;
int stop;
@@ -983,15 +983,15 @@ zs_hwiflow(zst, stop)
* Interface to the lower layer (zscc)
****************************************************************/
-static void zstty_rxint (struct zs_chanstate *);
-static void zstty_txint (struct zs_chanstate *);
-static void zstty_stint (struct zs_chanstate *);
+void zstty_rxint(struct zs_chanstate *);
+void zstty_txint(struct zs_chanstate *);
+void zstty_stint(struct zs_chanstate *);
/*
* receiver ready interrupt.
* called at splzs
*/
-static void
+void
zstty_rxint(cs)
register struct zs_chanstate *cs;
{
@@ -1058,7 +1058,7 @@ nextchar:
/*
* transmitter ready interrupt. (splzs)
*/
-static void
+void
zstty_txint(cs)
register struct zs_chanstate *cs;
{
@@ -1110,7 +1110,7 @@ zstty_txint(cs)
/*
* status change interrupt. (splzs)
*/
-static void
+void
zstty_stint(cs)
register struct zs_chanstate *cs;
{
@@ -1167,7 +1167,7 @@ zstty_stint(cs)
/*
* Print out a ring or fifo overrun error message.
*/
-static void
+void
zsoverrun(zst, ptime, what)
struct zstty_softc *zst;
long *ptime;
@@ -1193,7 +1193,7 @@ zsoverrun(zst, ptime, what)
* Note: an "input blockage" condition is assumed to exist if
* EITHER the TS_TBLOCK flag or zst_rx_blocked flag is set.
*/
-static void
+void
zstty_softint(cs)
struct zs_chanstate *cs;
{
diff --git a/sys/arch/mac68k/dev/zs.c b/sys/arch/mac68k/dev/zs.c
index b1af641730f..794471d5002 100644
--- a/sys/arch/mac68k/dev/zs.c
+++ b/sys/arch/mac68k/dev/zs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: zs.c,v 1.26 2008/01/23 16:37:56 jsing Exp $ */
+/* $OpenBSD: zs.c,v 1.27 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: zs.c,v 1.19 1998/01/12 19:22:18 thorpej Exp $ */
/*
@@ -135,8 +135,6 @@ static int zs_defspeed[NZSC][2] = {
};
void *zs_conschan = 0;
int zs_consunit;
-/* device to which the console is attached--if serial. */
-dev_t mac68k_zsdev;
/* Mac stuff */
volatile unsigned char *sccA = 0;
int nzsc_attached = 0; /* needed as long as we have spurious
@@ -231,7 +229,7 @@ struct cfdriver zsc_cd = {
};
int zshard(void *);
-int zssoft(void *);
+void zssoft(void *);
/*
@@ -415,6 +413,8 @@ zsc_attach(parent, self, aux)
}
}
+ /* XXX - Now safe to install interrupt handlers. */
+
if (current_mac_model->class == MACH_CLASSAV) {
add_psc_lev4_intr(PSCINTR_SCCA, zshard, zsc);
add_psc_lev4_intr(PSCINTR_SCCB, zshard, zsc);
@@ -422,7 +422,7 @@ zsc_attach(parent, self, aux)
intr_establish(zshard, zsc, ZSHARD_PRI, self->dv_xname);
}
- /* XXX - Now safe to install interrupt handlers. */
+ zsc->zsc_softih = softintr_establish(IPL_SOFTTTY, zssoft, zsc);
/*
* Set the master interrupt enable and interrupt vector.
@@ -482,8 +482,6 @@ zsmd_setclock(cs)
via_set_modem((xcs->cs_pclk_flag & ZSC_EXTERN) ? 1 : 0);
}
-static int zssoftpending;
-
/*
* Do the minimum work to pull data off of the chip and queue it up
* for later processing.
@@ -493,54 +491,49 @@ zshard(arg)
void *arg;
{
struct zsc_softc *zsc = (struct zsc_softc *)arg;
- int rval;
+ int rr3, rval;
+
+ /*
+ * The horror: the adb subsystem will invoke us directly.
+ * However if we were already servicing an interrupt,
+ * we'll lose bigtime. Don't allow such reentrancy.
+ */
+ static int zshard_busy = 0;
+
+ if (zshard_busy != 0)
+ return 0;
if (zsc == NULL)
return 0;
+ zshard_busy++;
+
rval = 0;
- rval |= zsc_intr_hard(zsc);
+ while ((rr3 = zsc_intr_hard(zsc)))
+ rval |= rr3;
+
if ((zsc->zsc_cs[0]->cs_softreq) || (zsc->zsc_cs[1]->cs_softreq)) {
/* zsc_req_softint(zsc); */
- /* We are at splzs here, so no need to lock. */
- if (zssoftpending == 0) {
- zssoftpending = 1;
- setsoftserial();
- }
+ softintr_schedule(zsc->zsc_softih);
}
+
+ zshard_busy--;
+
return (rval);
}
-/*
- * Similar scheme as for zshard (look at all of them)
- */
-int
+void
zssoft(arg)
void *arg;
{
- register struct zsc_softc *zsc;
- register int unit;
-
- /* This is not the only ISR on this IPL. */
- if (zssoftpending == 0)
- return (0);
-
- /*
- * The soft intr. bit will be set by zshard only if
- * the variable zssoftpending is zero.
- */
- zssoftpending = 0;
+ struct zsc_softc *zsc = (struct zsc_softc *)arg;
+ int s;
- for (unit = 0; unit < zsc_cd.cd_ndevs; ++unit) {
- zsc = zsc_cd.cd_devs[unit];
- if (zsc == NULL)
- continue;
- (void) zsc_intr_soft(zsc);
- }
- return (1);
+ s = spltty();
+ zsc_intr_soft(zsc);
+ splx(s);
}
-
#ifndef ZS_TOLERANCE
#define ZS_TOLERANCE 51
/* 5% in tenths of a %, plus 1 so that exactly 5% will be ok. */
@@ -837,7 +830,8 @@ zs_write_reg(cs, reg, val)
ZS_DELAY();
}
-u_char zs_read_csr(cs)
+u_char
+zs_read_csr(cs)
struct zs_chanstate *cs;
{
u_char val;
@@ -849,7 +843,8 @@ u_char zs_read_csr(cs)
return val;
}
-void zs_write_csr(cs, val)
+void
+zs_write_csr(cs, val)
struct zs_chanstate *cs;
register u_char val;
{
@@ -858,7 +853,8 @@ void zs_write_csr(cs, val)
ZS_DELAY();
}
-u_char zs_read_data(cs)
+u_char
+zs_read_data(cs)
struct zs_chanstate *cs;
{
register u_char val;
@@ -868,7 +864,8 @@ u_char zs_read_data(cs)
return val;
}
-void zs_write_data(cs, val)
+void
+zs_write_data(cs, val)
struct zs_chanstate *cs;
u_char val;
{
@@ -973,7 +970,7 @@ zscnprobe(struct consdev * cp)
zs_consunit = unit;
zs_conschan = (struct zschan *) -1; /* dummy flag for zs_init() */
- mac68k_zsdev = cp->cn_dev = makedev(maj, unit);
+ cp->cn_dev = makedev(maj, unit);
}
if (mac68k_machine.serial_boot_echo) {
/*
diff --git a/sys/arch/mac68k/include/intr.h b/sys/arch/mac68k/include/intr.h
index b29ee66d211..42d1140ef30 100644
--- a/sys/arch/mac68k/include/intr.h
+++ b/sys/arch/mac68k/include/intr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.h,v 1.18 2007/11/30 08:19:43 miod Exp $ */
+/* $OpenBSD: intr.h,v 1.19 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: intr.h,v 1.9 1998/08/12 06:58:42 scottr Exp $ */
/*
@@ -55,8 +55,7 @@ extern u_short mac68k_statclockipl;
* - compute CPU PSL values for the spl*() calls.
*/
#define IPL_NONE 0
-#define IPL_SOFTNET 1
-#define IPL_SOFTCLOCK 1
+#define IPL_SOFTINT 1
#define IPL_BIO 2
#define IPL_AUDIO PSLTOIPL(mac68k_audioipl)
#define IPL_NET PSLTOIPL(mac68k_netipl)
@@ -96,25 +95,7 @@ extern u_short mac68k_statclockipl;
/* watch out for side effects */
#define splx(s) ((s) & PSL_IPL ? _spl(s) : spl0())
-/*
- * simulated software interrupt register
- */
-extern volatile u_int8_t ssir;
-
-#define SIR_NET 0x01
-#define SIR_CLOCK 0x02
-#define SIR_SERIAL 0x04
-#define SIR_ADB 0x08
-
-#define siron(mask) \
- __asm __volatile ( "orb %1,%0" : "=m" (ssir) : "i" (mask))
-#define siroff(mask) \
- __asm __volatile ( "andb %1,%0" : "=m" (ssir) : "ir" (~(mask)))
-
-#define setsoftnet() siron(SIR_NET)
-#define setsoftclock() siron(SIR_CLOCK)
-#define setsoftserial() siron(SIR_SERIAL)
-#define setsoftadb() siron(SIR_ADB)
+#include <m68k/intr.h> /* soft interrupt support */
/* intr.c */
void intr_init(void);
diff --git a/sys/arch/mac68k/include/z8530var.h b/sys/arch/mac68k/include/z8530var.h
index 5bf9a0bb3a4..f031d38cda9 100644
--- a/sys/arch/mac68k/include/z8530var.h
+++ b/sys/arch/mac68k/include/z8530var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: z8530var.h,v 1.7 2004/11/25 18:32:10 miod Exp $ */
+/* $OpenBSD: z8530var.h,v 1.8 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: z8530var.h,v 1.2 1996/06/07 10:27:19 briggs Exp $ */
/*
@@ -97,6 +97,7 @@ struct zsc_softc {
struct zs_chanstate *zsc_cs[2]; /* channel A and B soft state */
/* Machine-dependent part follows... */
struct xzs_chanstate xzsc_xcs_store[2];
+ void *zsc_softih;
};
/*
diff --git a/sys/arch/mac68k/mac68k/autoconf.c b/sys/arch/mac68k/mac68k/autoconf.c
index ae2c49e962c..4e4d1235155 100644
--- a/sys/arch/mac68k/mac68k/autoconf.c
+++ b/sys/arch/mac68k/mac68k/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.31 2008/07/21 04:35:54 todd Exp $ */
+/* $OpenBSD: autoconf.c,v 1.32 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: autoconf.c,v 1.38 1996/12/18 05:46:09 scottr Exp $ */
/*
@@ -110,6 +110,9 @@ findbootdev()
void
cpu_configure()
{
+ /* this couldn't be done in intr_init() because this uses malloc() */
+ softintr_init();
+
startrtclock();
if (config_rootfound("mainbus", "mainbus") == NULL)
diff --git a/sys/arch/mac68k/mac68k/intr.c b/sys/arch/mac68k/mac68k/intr.c
index 45b725cfe99..9e2c2bbea58 100644
--- a/sys/arch/mac68k/mac68k/intr.c
+++ b/sys/arch/mac68k/mac68k/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.12 2008/06/26 05:42:12 ray Exp $ */
+/* $OpenBSD: intr.c,v 1.13 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: intr.c,v 1.2 1998/08/25 04:03:56 scottr Exp $ */
/*-
@@ -42,9 +42,6 @@
#include <uvm/uvm_extern.h>
-#include <net/netisr.h>
-
-#include <machine/atomic.h>
#include <machine/cpu.h>
#include <machine/intr.h>
@@ -204,28 +201,6 @@ intr_dispatch(int evec) /* format | vector offset */
}
}
-int netisr;
-
-void
-netintr()
-{
- int isr;
-
- while ((isr = netisr) != 0) {
- atomic_clearbits_int(&netisr, isr);
-
-#define DONETISR(bit, fn) \
- do { \
- if (isr & (1 << bit)) \
- (fn)(); \
- } while (0)
-
-#include <net/netisr_dispatch.h>
-
-#undef DONETISR
- }
-}
-
#ifdef DIAGNOSTIC
void
splassert_check(int wantipl, const char *func)
diff --git a/sys/arch/mac68k/mac68k/locore.s b/sys/arch/mac68k/mac68k/locore.s
index 5fe0927635b..9feb14dd59c 100644
--- a/sys/arch/mac68k/mac68k/locore.s
+++ b/sys/arch/mac68k/mac68k/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.61 2007/12/30 14:45:25 miod Exp $ */
+/* $OpenBSD: locore.s,v 1.62 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: locore.s,v 1.103 1998/07/09 06:02:50 scottr Exp $ */
/*
@@ -629,10 +629,10 @@ ENTRY_NOPROFILE(trap0)
addql #4,sp | pop syscall arg
tstl _C_LABEL(astpending)
jne Lrei2
- tstb _C_LABEL(ssir)
+ tstl _C_LABEL(softpending)
jeq Ltrap1
movw #SPL1,sr
- tstb _C_LABEL(ssir)
+ tstl _C_LABEL(softpending)
jne Lsir1
Ltrap1:
movl sp@(FR_SP),a0 | grab and restore
@@ -871,7 +871,7 @@ ENTRY_NOPROFILE(rtclock_intr)
* necessitating a stack cleanup.
*/
-BSS(ssir,1)
+BSS(softpending,4)
ASENTRY_NOPROFILE(rei)
tstl _C_LABEL(astpending) | AST pending?
@@ -909,7 +909,7 @@ Laststkadj:
movl sp@,sp | and our SP
rte | and do real RTE
Lchksir:
- tstb _C_LABEL(ssir) | SIR pending?
+ tstl _C_LABEL(softpending) | SIR pending?
jeq Ldorte | no, all done
movl d0,sp@- | need a scratch register
movw sp@(4),d0 | get SR
@@ -918,7 +918,7 @@ Lchksir:
movl sp@+,d0 | restore scratch register
Lgotsir:
movw #SPL1,sr | prevent others from servicing int
- tstb _C_LABEL(ssir) | too late?
+ tstl _C_LABEL(softpending) | too late?
jeq Ldorte | yes, oh well...
clrl sp@- | stack adjust
moveml #0xFFFF,sp@- | save all registers
@@ -1318,7 +1318,7 @@ ENTRY(spl0)
moveq #0,d0
movw sr,d0 | get old SR for return
movw #PSL_LOWIPL,sr | restore new SR
- tstb _C_LABEL(ssir) | software interrupt pending?
+ tstl _C_LABEL(softpending) | software interrupt pending?
jeq Lspldone | no, all done
subql #4,sp | make room for RTE frame
movl sp@(4),sp@(2) | position return address
diff --git a/sys/arch/mac68k/mac68k/trap.c b/sys/arch/mac68k/mac68k/trap.c
index 38d8e9d41ff..ddcb73577df 100644
--- a/sys/arch/mac68k/mac68k/trap.c
+++ b/sys/arch/mac68k/mac68k/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.55 2008/06/08 20:57:19 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.56 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: trap.c,v 1.68 1998/12/22 08:47:07 scottr Exp $ */
/*
@@ -476,30 +476,19 @@ copyfault:
case T_SSIR: /* Software interrupt */
case T_SSIR|T_USER:
- if (ssir & SIR_SERIAL) {
- void zssoft(int);
- siroff(SIR_SERIAL);
- uvmexp.softs++;
- zssoft(0);
- }
- if (ssir & SIR_NET) {
- void netintr(void);
- siroff(SIR_NET);
- uvmexp.softs++;
- netintr();
- }
- if (ssir & SIR_CLOCK) {
- void softclock(void);
- siroff(SIR_CLOCK);
- uvmexp.softs++;
- softclock();
- }
- if (ssir & SIR_ADB) {
- void adb_soft_intr(void);
- siroff(SIR_ADB);
- uvmexp.softs++;
- adb_soft_intr();
+ {
+ int sir, q, mask;
+
+ while ((sir = softpending) != 0) {
+ atomic_clearbits_int(&softpending, sir);
+
+ for (q = SI_NQUEUES - 1, mask = 1 << (SI_NQUEUES - 1);
+ mask != 0; q--, mask >>= 1)
+ if (mask & sir)
+ softintr_dispatch(q);
}
+ }
+
/*
* If this was not an AST trap, we are all done.
*/
diff --git a/sys/arch/mac68k/mac68k/via.c b/sys/arch/mac68k/mac68k/via.c
index 9042dc80b93..d6c0b3e5d6f 100644
--- a/sys/arch/mac68k/mac68k/via.c
+++ b/sys/arch/mac68k/mac68k/via.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: via.c,v 1.31 2007/09/10 20:29:50 miod Exp $ */
+/* $OpenBSD: via.c,v 1.32 2009/03/15 20:40:25 miod Exp $ */
/* $NetBSD: via.c,v 1.62 1997/09/10 04:38:48 scottr Exp $ */
/*-
@@ -198,8 +198,7 @@ via1_intr(void *arg)
return (0);
/*
- * Unflag interrupts here. If we do it after each interrupt,
- * the MRG ADB hangs up.
+ * Unflag interrupts here.
*/
via_reg(VIA1, vIFR) = intbits;