summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2003-08-05 02:04:59 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2003-08-05 02:04:59 +0000
commita3ca7b36476bdcbdd7a97c40958306b27700b464 (patch)
tree9ca7855b7b5d450288fb17f9b5f8a2c7a2f7e937
parente0db354ad043d751e66fee43bb893034200737c1 (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.c68
-rw-r--r--sys/arch/hppa/hppa/intr.c53
-rw-r--r--sys/arch/hppa/hppa/locore.S37
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