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/mvme68k | |
parent | 696ab5f08e3725e54a7b87f6c7f732871cea9473 (diff) |
Generic softinterrupt code for m68k platforms, now copied from m88k.
Diffstat (limited to 'sys/arch/mvme68k')
-rw-r--r-- | sys/arch/mvme68k/dev/cl.c | 10 | ||||
-rw-r--r-- | sys/arch/mvme68k/dev/zs.c | 194 | ||||
-rw-r--r-- | sys/arch/mvme68k/include/intr.h | 26 | ||||
-rw-r--r-- | sys/arch/mvme68k/mvme68k/locore.s | 14 | ||||
-rw-r--r-- | sys/arch/mvme68k/mvme68k/machdep.c | 27 | ||||
-rw-r--r-- | sys/arch/mvme68k/mvme68k/trap.c | 49 |
6 files changed, 125 insertions, 195 deletions
diff --git a/sys/arch/mvme68k/dev/cl.c b/sys/arch/mvme68k/dev/cl.c index dc47ddf252e..57b2baeeb36 100644 --- a/sys/arch/mvme68k/dev/cl.c +++ b/sys/arch/mvme68k/dev/cl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cl.c,v 1.45 2009/03/01 21:37:41 miod Exp $ */ +/* $OpenBSD: cl.c,v 1.46 2009/03/15 20:40:25 miod Exp $ */ /* * Copyright (c) 1995 Dale Rahn. All rights reserved. @@ -128,7 +128,7 @@ struct clsoftc { char sc_rxintrname[16 + 3]; char sc_txintrname[16 + 3]; int sc_flags; - u_int8_t ssir; + void *sc_softih; }; const struct { @@ -315,7 +315,7 @@ clattach(parent, self, aux) sc->sc_cl[i].psupply = sc->sc_cl[i].buffer; sc->sc_cl[i].nchar = 0; } - sc->ssir = allocate_sir(cl_softint, (void *)sc); + sc->sc_softih = softintr_establish(IPL_SOFTTTY, cl_softint, sc); #endif for (i = 0; i < CLCD_PORTS_PER_CHIP; i++) { #if 0 @@ -1973,7 +1973,7 @@ cl_appendbuf(sc, channel, c) sc->sc_cl[channel].psupply = sc->sc_cl[channel].buffer; } sc->sc_cl[channel].nchar ++; - setsoftint(sc->ssir); + softintr_schedule(sc->sc_softih); /* splx (s); */ } @@ -2004,7 +2004,7 @@ cl_appendbufn(sc, channel, buf, cnt) } sc->sc_cl[channel].nchar ++; } - setsoftint(sc->ssir); + softintr_schedule(sc->sc_softih); /* splx (s); */ } diff --git a/sys/arch/mvme68k/dev/zs.c b/sys/arch/mvme68k/dev/zs.c index c033c859a90..ac3e2a4fae8 100644 --- a/sys/arch/mvme68k/dev/zs.c +++ b/sys/arch/mvme68k/dev/zs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zs.c,v 1.26 2008/01/23 16:37:57 jsing Exp $ */ +/* $OpenBSD: zs.c,v 1.27 2009/03/15 20:40:25 miod Exp $ */ /* * Copyright (c) 2000 Steve Murphree, Jr. @@ -109,10 +109,11 @@ struct zs { #define ZH_RXOVF 8 /* receiver buffer overflow */ struct zssoftc { - struct device sc_dev; - struct zs sc_zs[2]; - struct intrhand sc_ih; - int sc_flags; + struct device sc_dev; + struct zs sc_zs[2]; + struct intrhand sc_ih; + void *sc_softih; + int sc_flags; }; #define ZSSF_85230 1 @@ -129,7 +130,6 @@ int zsirq(void *); int zsregs(vaddr_t, int, volatile u_char **, volatile u_char **); int zspclk(void); -u_int8_t sir_zs; void zs_softint(void *); #define zsunit(dev) (minor(dev) >> 1) @@ -159,9 +159,9 @@ void zscc_mset(struct sccregs *, int); void zscc_mclr(struct sccregs *, int); void zs_drain(struct zs *); void zs_unblock(struct tty *); -void zs_txint(struct zs *); -void zs_rxint(struct zs *); -void zs_extint(struct zs *); +void zs_txint(struct zssoftc *, struct zs *); +void zs_rxint(struct zssoftc *, struct zs *); +void zs_extint(struct zssoftc *, struct zs *); cons_decl(zs); int @@ -263,8 +263,7 @@ zsattach(parent, self, args) zp->scc.s_dr = scc_dr; zp->flags |= ZS_RESET; - if (sir_zs == 0) - sir_zs = allocate_sir(zs_softint, 0); + sc->sc_softih = softintr_establish(IPL_SOFTTTY, zs_softint, sc); printf("\n"); @@ -535,7 +534,7 @@ zsstart(tp) zp->send_ptr = tp->t_outq.c_cf; zp->send_count = n; zp->sent_count = 0; - zs_txint(zp); + zs_txint(sc, zp); spltty(); } } @@ -759,26 +758,25 @@ zsirq(arg) if (ipend == 0) return (0); if ((ipend & 0x20) != 0) - zs_rxint(zp); + zs_rxint(sc, zp); if ((ipend & 0x10) != 0) - zs_txint(zp); + zs_txint(sc, zp); if ((ipend & 0x8) != 0) - zs_extint(zp); + zs_extint(sc, zp); ++zp; /* now look for B side ints */ if ((ipend & 0x4) != 0) - zs_rxint(zp); + zs_rxint(sc, zp); if ((ipend & 0x2) != 0) - zs_txint(zp); + zs_txint(sc, zp); if ((ipend & 0x1) != 0) - zs_extint(zp); + zs_extint(sc, zp); ZWRITE0(&zp->scc, 0x38); /* reset highest IUS */ return (1); } void -zs_txint(zp) - register struct zs *zp; +zs_txint(struct zssoftc *sc, struct zs *zp) { struct sccregs *scc; int c; @@ -798,14 +796,13 @@ zs_txint(zp) if (zp->send_count == 0 && (zp->hflags & ZH_TXING) != 0) { zp->hflags &= ~ZH_TXING; zp->hflags |= ZH_SIRQ; - setsoftint(sir_zs); + softintr_schedule(sc->sc_softih); } } } void -zs_rxint(zp) - register struct zs *zp; +zs_rxint(struct zssoftc *sc, struct zs *zp) { register int stat, c, n, extra; u_char *put; @@ -846,14 +843,13 @@ zs_rxint(zp) zp->rcv_put = put; zp->rcv_count = n; zp->hflags |= ZH_SIRQ; - setsoftint(sir_zs); + softintr_schedule(sc->sc_softih); } } /* Ext/status interrupt */ void -zs_extint(zp) - register struct zs *zp; +zs_extint(struct zssoftc *sc, struct zs *zp) { int rr0; struct tty *tp = zp->tty; @@ -875,13 +871,13 @@ zs_extint(zp) else { zp->hflags &= ~ZH_OBLOCK; if ((rr0 & SCC_TXRDY) != 0) - zs_txint(zp); + zs_txint(sc, zp); } } zp->modem_change |= rr0 ^ zp->modem_state; zp->modem_state = rr0; zp->hflags |= ZH_SIRQ; - setsoftint(sir_zs); + softintr_schedule(sc->sc_softih); } /* ARGSUSED */ @@ -889,97 +885,93 @@ void zs_softint(arg) void *arg; { + struct zssoftc *sc = (struct zssoftc *)arg; int s, c, stat, rr0; struct zs *zp; struct tty *tp; u_char *get; - int unit, side; + int side; s = splzs(); - for (unit = 0; unit < zs_cd.cd_ndevs; ++unit) { - if (zs_cd.cd_devs[unit] == NULL) + zp = &sc->sc_zs[0]; + for (side = 0; side < 2; ++side, ++zp) { + if ((zp->hflags & ZH_SIRQ) == 0) continue; - zp = &((struct zssoftc *) zs_cd.cd_devs[unit])->sc_zs[0]; - for (side = 0; side < 2; ++side, ++zp) { - if ((zp->hflags & ZH_SIRQ) == 0) - continue; - zp->hflags &= ~ZH_SIRQ; - tp = zp->tty; + zp->hflags &= ~ZH_SIRQ; + tp = zp->tty; - /* check for tx done */ - spltty(); - if (tp != NULL && zp->send_count == 0 - && (tp->t_state & TS_BUSY) != 0) { - tp->t_state &= ~(TS_BUSY | TS_FLUSH); - ndflush(&tp->t_outq, zp->sent_count); - if (tp->t_outq.c_cc <= tp->t_lowat) { - if (tp->t_state & TS_ASLEEP) { - tp->t_state &= ~TS_ASLEEP; - wakeup((caddr_t) & tp->t_outq); - } - selwakeup(&tp->t_wsel); + /* check for tx done */ + spltty(); + if (tp != NULL && zp->send_count == 0 + && (tp->t_state & TS_BUSY) != 0) { + tp->t_state &= ~(TS_BUSY | TS_FLUSH); + ndflush(&tp->t_outq, zp->sent_count); + if (tp->t_outq.c_cc <= tp->t_lowat) { + if (tp->t_state & TS_ASLEEP) { + tp->t_state &= ~TS_ASLEEP; + wakeup((caddr_t) & tp->t_outq); } - if (tp->t_line != 0) - (*linesw[tp->t_line].l_start) (tp); - else - zsstart(tp); + selwakeup(&tp->t_wsel); } - splzs(); + if (tp->t_line != 0) + (*linesw[tp->t_line].l_start) (tp); + else + zsstart(tp); + } + splzs(); - /* check for received characters */ - get = zp->rcv_get; - while (zp->rcv_count > 0) { + /* check for received characters */ + get = zp->rcv_get; + while (zp->rcv_count > 0) { + c = *get++; + if (get >= zp->rcv_end) + get = zp->rcv_buf; + if (c == ERROR_DET) { + stat = *get++; + if (get >= zp->rcv_end) + get = zp->rcv_buf; c = *get++; if (get >= zp->rcv_end) get = zp->rcv_buf; - if (c == ERROR_DET) { - stat = *get++; - if (get >= zp->rcv_end) - get = zp->rcv_buf; - c = *get++; - if (get >= zp->rcv_end) - get = zp->rcv_buf; - zp->rcv_count -= 3; - } else { - stat = 0; - --zp->rcv_count; + zp->rcv_count -= 3; + } else { + stat = 0; + --zp->rcv_count; + } + spltty(); + if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0) + continue; + if (zp->nzs_open == 0) { + } else { + if ((stat & 0x10) != 0) + c |= TTY_PE; + if ((stat & 0x20) != 0) { + log(LOG_WARNING, "zs: fifo overflow\n"); + c |= TTY_FE; /* need some error for + * slip stuff */ } + if ((stat & 0x40) != 0) + c |= TTY_FE; + (*linesw[tp->t_line].l_rint) (c, tp); + } + splzs(); + } + zp->rcv_get = get; + + /* check for modem lines changing */ + while (zp->modem_change != 0 || zp->modem_state != zp->rr0) { + rr0 = zp->rr0 ^ zp->modem_change; + zp->modem_change = rr0 ^ zp->modem_state; + + /* Check if DCD (carrier detect) has changed */ + if (tp != NULL && (rr0 & 8) != (zp->rr0 & 8)) { spltty(); - if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0) - continue; - if (zp->nzs_open == 0) { - - } else { - if ((stat & 0x10) != 0) - c |= TTY_PE; - if ((stat & 0x20) != 0) { - log(LOG_WARNING, "zs: fifo overflow\n"); - c |= TTY_FE; /* need some error for - * slip stuff */ - } - if ((stat & 0x40) != 0) - c |= TTY_FE; - (*linesw[tp->t_line].l_rint) (c, tp); - } + ttymodem(tp, rr0 & 8); + /* XXX possibly should disable line if + * return value is 0 */ splzs(); } - zp->rcv_get = get; - - /* check for modem lines changing */ - while (zp->modem_change != 0 || zp->modem_state != zp->rr0) { - rr0 = zp->rr0 ^ zp->modem_change; - zp->modem_change = rr0 ^ zp->modem_state; - - /* Check if DCD (carrier detect) has changed */ - if (tp != NULL && (rr0 & 8) != (zp->rr0 & 8)) { - spltty(); - ttymodem(tp, rr0 & 8); - /* XXX possibly should disable line if - * return value is 0 */ - splzs(); - } - zp->rr0 = rr0; - } + zp->rr0 = rr0; } } splx(s); diff --git a/sys/arch/mvme68k/include/intr.h b/sys/arch/mvme68k/include/intr.h index c6f711cb9aa..bd16c4471f3 100644 --- a/sys/arch/mvme68k/include/intr.h +++ b/sys/arch/mvme68k/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.17 2009/03/01 21:40:49 miod Exp $ */ +/* $OpenBSD: intr.h,v 1.18 2009/03/15 20:40:25 miod Exp $ */ /* * Copyright (C) 2000 Steve Murphree, Jr. * All rights reserved. @@ -34,25 +34,6 @@ #ifdef _KERNEL /* - * Simulated software interrupt register. - */ -extern volatile u_int8_t ssir; - -#define SIR_NET 0x01 -#define SIR_CLOCK 0x02 - -#define siron(mask) \ - __asm __volatile ( "orb %1,%0" : "=m" (ssir) : "ir" (mask)) -#define siroff(mask) \ - __asm __volatile ( "andb %1,%0" : "=m" (ssir) : "ir" (~(mask))) - -#define setsoftint(s) siron(s) -#define setsoftnet() siron(SIR_NET) -#define setsoftclock() siron(SIR_CLOCK) - -u_int8_t allocate_sir(void (*proc)(void *), void *arg); - -/* * Interrupt "levels". These are a more abstract representation * of interrupt levels, and do not have the same meaning as m68k * CPU interrupt levels. They serve two purposes: @@ -61,8 +42,7 @@ u_int8_t allocate_sir(void (*proc)(void *), void *arg); * - 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_NET 3 #define IPL_TTY 5 @@ -86,6 +66,8 @@ u_int8_t allocate_sir(void (*proc)(void *), void *arg); /* watch out for side effects */ #define splx(s) ((s) & PSL_IPL ? _spl(s) : spl0()) +#include <m68k/intr.h> /* soft interrupt support */ + /* locore.s */ int spl0(void); diff --git a/sys/arch/mvme68k/mvme68k/locore.s b/sys/arch/mvme68k/mvme68k/locore.s index 56cdfa8f350..6dc91bbe290 100644 --- a/sys/arch/mvme68k/mvme68k/locore.s +++ b/sys/arch/mvme68k/mvme68k/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.60 2009/03/01 22:08:13 miod Exp $ */ +/* $OpenBSD: locore.s,v 1.61 2009/03/15 20:40:25 miod Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -1009,10 +1009,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 @@ -1197,7 +1197,7 @@ ENTRY_NOPROFILE(spurintr) * necessitating a stack cleanup. */ -BSS(ssir,1) +BSS(softpending,4) ASENTRY_NOPROFILE(rei) tstl _C_LABEL(astpending) | AST pending? @@ -1235,7 +1235,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 @@ -1244,7 +1244,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 @@ -1690,7 +1690,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/mvme68k/mvme68k/machdep.c b/sys/arch/mvme68k/mvme68k/machdep.c index 0a8d85d8df9..206d606a0da 100644 --- a/sys/arch/mvme68k/mvme68k/machdep.c +++ b/sys/arch/mvme68k/mvme68k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.113 2009/03/01 22:08:13 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.114 2009/03/15 20:40:25 miod Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -111,8 +111,6 @@ #include <dev/cons.h> -#include <net/netisr.h> - #ifdef DDB #include <machine/db_machdep.h> #include <ddb/db_extern.h> @@ -870,29 +868,6 @@ badvaddr(addr, size) return (0); } -int netisr; - -void -netintr(arg) - void *arg; -{ - int n; - - while ((n = netisr) != 0) { - atomic_clearbits_int(&netisr, n); - -#define DONETISR(bit, fn) \ - do { \ - if (n & (1 << (bit))) \ - (fn)(); \ - } while (0) - -#include <net/netisr_dispatch.h> - -#undef DONETISR - } -} - /* * Level 7 interrupts are normally caused by the ABORT switch, * drop into ddb. diff --git a/sys/arch/mvme68k/mvme68k/trap.c b/sys/arch/mvme68k/mvme68k/trap.c index 38fdc8d0811..aa9f371ebcf 100644 --- a/sys/arch/mvme68k/mvme68k/trap.c +++ b/sys/arch/mvme68k/mvme68k/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.67 2007/05/15 13:46:22 martin Exp $ */ +/* $OpenBSD: trap.c,v 1.68 2009/03/15 20:40:25 miod Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -158,11 +158,6 @@ int mmupid = -1; #define MDB_ISPID(p) (p) == mmupid #endif -#define NSIR 8 -void (*sir_routines[NSIR])(void *); -void *sir_args[NSIR]; -u_char next_sir; - void trap(int, u_int, u_int, struct frame); void syscall(register_t, struct frame); void init_intrs(void); @@ -238,7 +233,7 @@ trap(type, code, v, frame) register struct proc *p; register int i; u_int ucode; - int typ = 0, bit; + int typ = 0; #ifdef COMPAT_HPUX extern struct emul emul_hpux; #endif @@ -473,13 +468,19 @@ copyfault: case T_SSIR: /* software interrupt */ case T_SSIR|T_USER: - while ((bit = ffs(ssir))) { - --bit; - ssir &= ~(1 << bit); - uvmexp.softs++; - if (sir_routines[bit]) - sir_routines[bit](sir_args[bit]); + { + 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. */ @@ -1100,24 +1101,6 @@ bad: #endif } -/* - * Allocation routines for software interrupts. - */ -u_int8_t -allocate_sir(proc, arg) - void (*proc)(void *); - void *arg; -{ - int bit; - - if (next_sir >= NSIR) - panic("allocate_sir: none left"); - bit = next_sir++; - sir_routines[bit] = proc; - sir_args[bit] = arg; - return (1 << bit); -} - typedef SLIST_HEAD(,intrhand) intrhand_t; intrhand_t intrs[NVMEINTR]; @@ -1132,9 +1115,7 @@ init_intrs() SLIST_INIT(&intrs[i]); /* soft interrupts... */ - sir_routines[0] = netintr; - sir_routines[1] = (void (*)(void *))softclock; - next_sir = 2; + softintr_init(); } void |