summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/hppa/dev/apic.c58
-rw-r--r--sys/arch/hppa/dev/elroyvar.h3
-rw-r--r--sys/arch/hppa/hppa/intr.c14
-rw-r--r--sys/arch/hppa/include/autoconf.h3
4 files changed, 58 insertions, 20 deletions
diff --git a/sys/arch/hppa/dev/apic.c b/sys/arch/hppa/dev/apic.c
index 032afe8cbda..a52307c4033 100644
--- a/sys/arch/hppa/dev/apic.c
+++ b/sys/arch/hppa/dev/apic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: apic.c,v 1.1 2007/05/21 22:43:38 kettenis Exp $ */
+/* $OpenBSD: apic.c,v 1.2 2007/05/27 16:36:07 kettenis Exp $ */
/*
* Copyright (c) 2005 Michael Shalayeff
@@ -32,6 +32,13 @@
#include <hppa/dev/elroyreg.h>
#include <hppa/dev/elroyvar.h>
+#define APIC_INT_LINE_MASK 0x0000ff00
+#define APIC_INT_LINE_SHIFT 8
+#define APIC_INT_IRQ_MASK 0x0000001f
+
+#define APIC_INT_LINE(x) (((x) & APIC_INT_LINE_MASK) >> APIC_INT_LINE_SHIFT)
+#define APIC_INT_IRQ(x) ((x) & APIC_INT_IRQ_MASK)
+
struct apic_iv {
struct elroy_softc *sc;
pci_intr_handle_t ih;
@@ -72,6 +79,11 @@ apic_attach(struct elroy_softc *sc)
printf(" APIC ver %x, %d pins",
data & APIC_VERSION_MASK, sc->sc_nints);
+ sc->sc_irq = malloc(sc->sc_nints * sizeof(int), M_DEVBUF, M_NOWAIT);
+ if (sc->sc_irq == NULL)
+ panic("apic_attach: cannot allocate irq table\n");
+ memset(sc->sc_irq, 0, sc->sc_nints * sizeof(int));
+
#ifdef DEBUG
apic_dump(sc);
#endif
@@ -80,17 +92,22 @@ apic_attach(struct elroy_softc *sc)
int
apic_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
+ struct elroy_softc *sc = pa->pa_pc->_cookie;
pci_chipset_tag_t pc = pa->pa_pc;
pcitag_t tag = pa->pa_tag;
pcireg_t reg;
+ int line;
reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
#ifdef DEBUG
printf(" pin=%d line=%d ", PCI_INTERRUPT_PIN(reg),
PCI_INTERRUPT_LINE(reg));
#endif
- *ihp = PCI_INTERRUPT_LINE(reg) + 1;
- return (*ihp == 0);
+ line = PCI_INTERRUPT_LINE(reg);
+ if (sc->sc_irq[line] == 0)
+ sc->sc_irq[line] = cpu_intr_findirq();
+ *ihp = (line << APIC_INT_LINE_SHIFT) | sc->sc_irq[line];
+ return (APIC_INT_IRQ(*ihp) == 0);
}
const char *
@@ -98,7 +115,8 @@ apic_intr_string(void *v, pci_intr_handle_t ih)
{
static char buf[32];
- snprintf(buf, 32, "irq %ld", (ih + 8 - 1));
+ snprintf(buf, 32, "line %ld irq %ld",
+ APIC_INT_LINE(ih), APIC_INT_IRQ(ih));
return (buf);
}
@@ -110,12 +128,14 @@ apic_intr_establish(void *v, pci_intr_handle_t ih,
struct elroy_softc *sc = v;
volatile struct elroy_regs *r = sc->sc_regs;
hppa_hpa_t hpa = cpu_gethpa(0);
- u_int32_t ent0;
struct apic_iv *aiv, *biv;
void *iv;
+ int irq = APIC_INT_IRQ(ih);
+ int line = APIC_INT_LINE(ih);
+ u_int32_t ent0;
/* no mapping or bogus */
- if (ih <= 0 || ih > 31)
+ if (irq <= 0 || irq > 31)
return (NULL);
aiv = malloc(sizeof(struct apic_iv), M_DEVBUF, M_NOWAIT);
@@ -127,32 +147,34 @@ apic_intr_establish(void *v, pci_intr_handle_t ih,
aiv->handler = handler;
aiv->arg = arg;
aiv->next = NULL;
- if (apic_intr_list[(ih + 8 - 1)]) {
- biv = apic_intr_list[(ih + 8 - 1)];
+ if (apic_intr_list[irq]) {
+ biv = apic_intr_list[irq];
while (biv->next)
biv = biv->next;
biv->next = aiv;
return (arg);
}
- if ((iv = cpu_intr_establish(pri, (ih + 8 - 1), apic_intr, aiv, name))) {
- ent0 = (31 - (ih + 8 - 1)) & APIC_ENT0_VEC;
+ if ((iv = cpu_intr_establish(pri, irq, apic_intr, aiv, name))) {
+ ent0 = (31 - irq) & APIC_ENT0_VEC;
ent0 |= APIC_ENT0_LOW;
ent0 |= APIC_ENT0_LEV;
#if 0
if (cold) {
- sc->sc_imr |= (1 << (ih + 8 - 1));
+ sc->sc_imr |= (1 << irq);
ent0 |= APIC_ENT0_MASK;
}
#endif
- apic_write(sc->sc_regs, APIC_ENT0(ih - 1), APIC_ENT0_MASK);
- apic_write(sc->sc_regs, APIC_ENT1(ih - 1),
+ apic_write(sc->sc_regs, APIC_ENT0(line), APIC_ENT0_MASK);
+ apic_write(sc->sc_regs, APIC_ENT1(line),
((hpa & 0x0ff00000) >> 4) | ((hpa & 0x000ff000) << 12));
- apic_write(sc->sc_regs, APIC_ENT0(ih - 1), ent0);
+ apic_write(sc->sc_regs, APIC_ENT0(line), ent0);
- elroy_write32(&r->apic_eoi, htole32((31 - (ih + 8 - 1)) & APIC_ENT0_VEC));
+ /* Signal EOI. */
+ elroy_write32(&r->apic_eoi,
+ htole32((31 - irq) & APIC_ENT0_VEC));
- apic_intr_list[(ih + 8 - 1)] = aiv;
+ apic_intr_list[irq] = aiv;
}
return (arg);
@@ -176,7 +198,9 @@ apic_intr(void *v)
iv = iv->next;
}
- elroy_write32(&r->apic_eoi, htole32((31 - (iv->ih + 8 - 1)) & APIC_ENT0_VEC));
+ /* Signal EOI. */
+ elroy_write32(&r->apic_eoi,
+ htole32((31 - APIC_INT_IRQ(iv->ih)) & APIC_ENT0_VEC));
return (claimed);
}
diff --git a/sys/arch/hppa/dev/elroyvar.h b/sys/arch/hppa/dev/elroyvar.h
index 48b2f74d7b1..20c2ed86d70 100644
--- a/sys/arch/hppa/dev/elroyvar.h
+++ b/sys/arch/hppa/dev/elroyvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: elroyvar.h,v 1.1 2007/05/21 22:43:38 kettenis Exp $ */
+/* $OpenBSD: elroyvar.h,v 1.2 2007/05/27 16:36:07 kettenis Exp $ */
/*
* Copyright (c) 2005 Michael Shalayeff
@@ -29,6 +29,7 @@ struct elroy_softc {
u_int32_t sc_imr;
int sc_nints;
+ int *sc_irq;
struct hppa_pci_chipset_tag sc_pc;
struct hppa_bus_space_tag sc_iot;
diff --git a/sys/arch/hppa/hppa/intr.c b/sys/arch/hppa/hppa/intr.c
index e14d57e19f7..8a9dbbb7282 100644
--- a/sys/arch/hppa/hppa/intr.c
+++ b/sys/arch/hppa/hppa/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.22 2004/07/13 19:34:22 mickey Exp $ */
+/* $OpenBSD: intr.c,v 1.23 2007/05/27 16:36:07 kettenis Exp $ */
/*
* Copyright (c) 2002-2004 Michael Shalayeff
@@ -156,6 +156,18 @@ cpu_intr_init(void)
ssm(PSL_I, mask);
}
+int
+cpu_intr_findirq(void)
+{
+ int irq;
+
+ for (irq = 0; irq < CPU_NINTS; irq++)
+ if (intr_table[irq].handler == NULL)
+ return irq;
+
+ return -1;
+}
+
void *
cpu_intr_map(void *v, int pri, int irq, int (*handler)(void *), void *arg,
const char *name)
diff --git a/sys/arch/hppa/include/autoconf.h b/sys/arch/hppa/include/autoconf.h
index 9c5acb6c2de..9e6d923a8cb 100644
--- a/sys/arch/hppa/include/autoconf.h
+++ b/sys/arch/hppa/include/autoconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.h,v 1.21 2004/09/15 20:11:29 mickey Exp $ */
+/* $OpenBSD: autoconf.h,v 1.22 2007/05/27 16:36:07 kettenis Exp $ */
/*
* Copyright (c) 1998-2004 Michael Shalayeff
@@ -72,6 +72,7 @@ const char *hppa_mod_info(int, int);
void pdc_scanbus(struct device *, struct confargs *, int, hppa_hpa_t hpa);
int mbprint(void *, const char *);
int mbsubmatch(struct device *, void *, void *);
+int cpu_intr_findirq(void);
void *cpu_intr_map(void *v, int pri, int irq, int (*handler)(void *),
void *arg, const char *name);
void *cpu_intr_establish(int pri, int irq, int (*handler)(void *),