diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-03-15 20:40:26 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-03-15 20:40:26 +0000 |
commit | a70ea7a0d41fc23f193e4cf52f9f81bf20011a83 (patch) | |
tree | d6b65e33edd85a3981e395f10b4fd50db5e2107e /sys/arch/mac68k | |
parent | 696ab5f08e3725e54a7b87f6c7f732871cea9473 (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.c | 73 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/if_sn.c | 3 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/z8530sc.c | 75 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/z8530sc.h | 4 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/z8530tty.c | 50 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/zs.c | 83 | ||||
-rw-r--r-- | sys/arch/mac68k/include/intr.h | 25 | ||||
-rw-r--r-- | sys/arch/mac68k/include/z8530var.h | 3 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/autoconf.c | 5 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/intr.c | 27 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/locore.s | 14 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/trap.c | 37 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/via.c | 5 |
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; |