diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2003-08-05 02:04:59 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2003-08-05 02:04:59 +0000 |
commit | a3ca7b36476bdcbdd7a97c40958306b27700b464 (patch) | |
tree | 9ca7855b7b5d450288fb17f9b5f8a2c7a2f7e937 | |
parent | e0db354ad043d751e66fee43bb893034200737c1 (diff) |
support for shared interrupts as required by isa/eisa/pci. remove a gsckbc kludge; miod@ testing
-rw-r--r-- | sys/arch/hppa/gsc/gsckbc.c | 68 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/intr.c | 53 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/locore.S | 37 |
3 files changed, 66 insertions, 92 deletions
diff --git a/sys/arch/hppa/gsc/gsckbc.c b/sys/arch/hppa/gsc/gsckbc.c index 0cc1f6a6798..fce7a74a52f 100644 --- a/sys/arch/hppa/gsc/gsckbc.c +++ b/sys/arch/hppa/gsc/gsckbc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gsckbc.c,v 1.5 2003/05/25 16:32:59 mickey Exp $ */ +/* $OpenBSD: gsckbc.c,v 1.6 2003/08/05 02:04:57 mickey Exp $ */ /* * Copyright (c) 2003, Miodrag Vallat. * All rights reserved. @@ -99,8 +99,6 @@ struct gsckbc_softc { int sc_irq; void *sc_ih; int sc_type; - - struct device *sc_sibling; }; struct cfattach gsckbc_ca = { @@ -158,7 +156,7 @@ void pckbc_cleanqueue(struct pckbc_slotdata *); void pckbc_cleanup(void *); int pckbc_cmdresponse(struct pckbc_internal *, pckbc_slot_t, u_char); void pckbc_start(struct pckbc_internal *, pckbc_slot_t); -int gsckbcintr(struct gsckbc_softc *); +int gsckbcintr(void *); const char *pckbc_slot_names[] = { "kbd", "mouse" }; @@ -367,10 +365,9 @@ gsckbc_attach(struct device *parent, struct device *self, void *aux) struct gsckbc_softc *gsc = (void *)self; struct pckbc_softc *sc = &gsc->sc_pckbc; struct pckbc_internal *t; - struct device *tdev; bus_space_tag_t iot; bus_space_handle_t ioh; - int ident, dev; + int ident; iot = ga->ga_ca.ca_iot; gsc->sc_irq = ga->ga_ca.ca_irq; @@ -391,6 +388,8 @@ gsckbc_attach(struct device *parent, struct device *self, void *aux) return; } + printf("\n"); + sc->intr_establish = gsckbc_intr_establish; t = malloc(sizeof(struct pckbc_internal), M_DEVBUF, M_WAITOK); @@ -404,37 +403,6 @@ gsckbc_attach(struct device *parent, struct device *self, void *aux) sc->id = t; /* - * Several gsckbc attachments might share the same interrupt. - * Try to find existing gsckbc devices, and associate them - * together. We do not expect more than two gsckbc devices to - * share an interrupt. - */ - for (dev = 0; dev < gsckbc_cd.cd_ndevs; dev++) { - tdev = gsckbc_cd.cd_devs[dev]; - if (tdev != NULL && tdev != self && - tdev->dv_parent == parent && - strcmp(tdev->dv_cfdata->cf_driver->cd_name, - gsckbc_cd.cd_name) == 0) { - struct gsckbc_softc *alter = (void *)tdev; - if (alter->sc_irq == gsc->sc_irq) { -#ifdef PCKBCDEBUG - if (alter->sc_sibling != NULL) { - printf(": more than two ps/2 ports" - " sharing the same interrupt???\n"); - bus_space_unmap(iot, ioh, KBMAPSIZE); - return; - } -#endif - gsc->sc_sibling = (void *)alter; - alter->sc_sibling = self; - printf(" (shared with %s)", tdev->dv_xname); - } - } - } - - printf("\n"); - - /* * Reset port and probe device, if plugged */ ident = probe_ident(iot, ioh); @@ -461,7 +429,7 @@ gsckbc_intr_establish(struct pckbc_softc *sc, pckbc_slot_t slot) gsc->sc_ih = gsc_intr_establish( (struct gsc_softc *)sc->sc_dv.dv_parent, - IPL_TTY, gsc->sc_irq, pckbcintr, sc, &sc->sc_dv); + IPL_TTY, gsc->sc_irq, gsckbcintr, sc, &sc->sc_dv); } /* @@ -654,7 +622,7 @@ pckbc_set_poll(self, slot, on) */ if (t->t_sc) { s = spltty(); - pckbcintr(t->t_sc); + gsckbcintr(t->t_sc); splx(s); } } @@ -1012,8 +980,9 @@ pckbc_set_inputhandler(self, slot, func, arg, name) } int -gsckbcintr(struct gsckbc_softc *gsc) +gsckbcintr(void *v) { + struct gsckbc_softc *gsc = v; struct pckbc_softc *sc = (struct pckbc_softc *)gsc; struct pckbc_internal *t = sc->id; pckbc_slot_t slot; @@ -1055,22 +1024,3 @@ gsckbcintr(struct gsckbc_softc *gsc) return (served); } - -int -pckbcintr(void *vsc) -{ - struct gsckbc_softc *gsc = vsc; - int claimed; - - claimed = gsckbcintr(gsc); - - /* - * We also need to handle interrupts for the associated slot device, - * if any - */ - gsc = (struct gsckbc_softc *)gsc->sc_sibling; - if (gsc != NULL) - claimed |= gsckbcintr(gsc); - - return (claimed); -} diff --git a/sys/arch/hppa/hppa/intr.c b/sys/arch/hppa/hppa/intr.c index de854ab5590..636f62deacf 100644 --- a/sys/arch/hppa/hppa/intr.c +++ b/sys/arch/hppa/hppa/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.9 2003/06/23 18:24:32 mickey Exp $ */ +/* $OpenBSD: intr.c,v 1.10 2003/08/05 02:04:58 mickey Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff @@ -55,19 +55,27 @@ struct hppa_iv { int (*handler)(void *); void *arg; struct hppa_iv *next; + struct hppa_iv *share; + int pad2[3]; } __attribute__((__packed__)); register_t kpsw = PSL_Q | PSL_P | PSL_C | PSL_D; volatile int cpl = IPL_NESTED; -volatile u_long ipending, imask[NIPL]; u_long cpu_mask; -struct hppa_iv *intr_list, intr_store[8*CPU_NINTS], *intr_more = intr_store; +struct hppa_iv *intr_list, intr_store[8*2*CPU_NINTS], *intr_more = intr_store; struct hppa_iv intr_table[CPU_NINTS] = { { IPL_SOFTCLOCK, 0, HPPA_IV_SOFT, 0, (int (*)(void *))&softclock }, { IPL_SOFTNET , 0, HPPA_IV_SOFT, 0, (int (*)(void *))&softnet }, { 0 }, { 0 }, { IPL_SOFTTTY , 0, HPPA_IV_SOFT, 0, (int (*)(void *))&softtty } }; +volatile u_long ipending, imask[NIPL] = { + 0, + 1 << (IPL_SOFTCLOCK - 1), + 1 << (IPL_SOFTNET - 1), + 0, 0, + 1 << (IPL_SOFTTTY - 1) +}; #ifdef DIAGNOSTIC void @@ -101,21 +109,21 @@ void cpu_intr_init(void) { u_long mask = cpu_mask | SOFTINT_MASK; - int level; + struct hppa_iv *iv; + int level, bit; /* map the shared ints */ while (intr_list) { - struct hppa_iv *iv = intr_list; - int bit = ffs(imask[(int)iv->pri]); + iv = intr_list; intr_list = iv->next; - + bit = ffs(imask[(int)iv->pri]); if (!bit--) { bit = ffs(~mask); if (!bit--) panic("cpu_intr_init: out of bits"); - iv->next = NULL; iv->bit = 31 - bit; + iv->next = NULL; intr_table[bit] = *iv; mask |= (1 << bit); imask[(int)iv->pri] |= (1 << bit); @@ -126,11 +134,6 @@ cpu_intr_init(void) } } - /* match the init for intr_table */ - imask[IPL_SOFTCLOCK] = 1 << (IPL_SOFTCLOCK - 1); - imask[IPL_SOFTNET ] = 1 << (IPL_SOFTNET - 1); - imask[IPL_SOFTTTY ] = 1 << (IPL_SOFTTTY - 1); - for (level = 0; level < NIPL - 1; level++) imask[level + 1] |= imask[level]; @@ -157,10 +160,21 @@ cpu_intr_map(void *v, int pri, int irq, int (*handler)(void *), void *arg, { struct hppa_iv *iv, *pv = v, *ivb = pv->next; - if (irq < 0 || irq >= CPU_NINTS || ivb[irq].handler) + if (irq < 0 || irq >= CPU_NINTS) return (NULL); iv = &ivb[irq]; + if (iv->handler) { + if (!pv->share) + return (NULL); + else { + iv = pv->share; + pv->share = iv->share; + iv->share = ivb[irq].share; + ivb[irq].share = iv; + } + } + iv->pri = pri; iv->bit = irq; iv->flags = 0; @@ -176,7 +190,7 @@ void * cpu_intr_establish(int pri, int irq, int (*handler)(void *), void *arg, struct device *dv) { - struct hppa_iv *iv; + struct hppa_iv *iv, *ev; if (irq < 0 || irq >= CPU_NINTS || intr_table[irq].handler) return (NULL); @@ -190,13 +204,16 @@ cpu_intr_establish(int pri, int irq, int (*handler)(void *), void *arg, iv->flags = 0; iv->handler = handler; iv->arg = arg; + iv->next = NULL; + iv->share = NULL; if (pri == IPL_NESTED) { iv->flags = HPPA_IV_CALL; iv->next = intr_more; - intr_more += CPU_NINTS; - } else - iv->next = NULL; + intr_more += 2 * CPU_NINTS; + for (ev = iv->next + CPU_NINTS; ev < intr_more; ev++) + ev->share = iv->share, iv->share = ev; + } return (iv); } diff --git a/sys/arch/hppa/hppa/locore.S b/sys/arch/hppa/hppa/locore.S index 31a43224e25..f0187897e3c 100644 --- a/sys/arch/hppa/hppa/locore.S +++ b/sys/arch/hppa/hppa/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.109 2003/07/15 18:15:41 mickey Exp $ */ +/* $OpenBSD: locore.S,v 1.110 2003/08/05 02:04:58 mickey Exp $ */ /* * Copyright (c) 1998-2003 Michael Shalayeff @@ -1895,23 +1895,23 @@ ENTRY(TLABEL(intr),0) ldil L%intr_table, r1 ldo R%intr_table(r1), r1 $intr_ffs - addi 16, r1, r1 + addi 32, r1, r1 bb,>= r8, 31, $intr_ffs shd r0, r8, 1, r8 - ldb 2-16(r1), r17 - ldw 4-16(r1), r9 + ldb 2-32(r1), r17 + ldw 4-32(r1), r9 subi,<> 1, r17, r0 bv,n r0(r9) nop mfctl sar, r25 - ldb 1-16(r1), r9 + ldb 1-32(r1), r9 mtsar r9 vdepi 1, 1, r24 mtsar r25 - ldb 0-16(r1), r9 + ldb 0-32(r1), r9 ldil L%intrcnt, r25 ldo R%intrcnt(r25), r25 sh2add r9, r25, r25 @@ -1942,23 +1942,29 @@ EXIT(TLABEL(intr)) .export gsc_intr, entry LEAF_ENTRY(gsc_intr) - ldw 8-16(r1), r9 /* arg: ioreg */ + ldw 8-32(r1), r9 /* arg: ioreg */ mtctl r1, tr7 ldw 0(r9), r16 /* irr */ - ldw 12-16(r1), r1 /* next: sub-intr_table */ + ldw 12-32(r1), r1 /* next: sub-intr_table */ + +$gsc_intr_loop + comb,=,n r0, r16, $intr_cont + mfctl tr7, r1 $gsc_ffs - addi 16, r1, r1 + addi 32, r1, r1 bb,>= r16, 31, $gsc_ffs shd r0, r16, 1, r16 + copy r1, r9 +$gsc_share mfctl sar, r25 - ldb 1-16(r1), r17 + ldb 1-32(r1), r17 mtsar r17 vdepi 1, 1, r24 mtsar r25 - ldb 0-16(r1), r17 + ldb 0-32(r1), r17 ldil L%intrcnt, r25 ldo R%intrcnt(r25), r25 sh2add r17, r25, r25 @@ -1966,11 +1972,12 @@ $gsc_ffs addi 1, r17, r17 stw r17, 0(r25) - comb,<> r0, r16, $gsc_ffs - nop + ldw 16-32(r1), r17 + comb,<>,n r0, r17, $gsc_share + ldo 32(r17), r1 - b $intr_cont - mfctl tr7, r1 + b $gsc_intr_loop + copy r9, r1 EXIT(gsc_intr) .export TLABEL(ibrk), entry |