summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2012-08-17 20:41:28 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2012-08-17 20:41:28 +0000
commit795c9e7e841224f48581c52e1043a450f43efe02 (patch)
tree3e3e8eeea5570c16a950b7eaad66192ab6beb513 /sys
parent9819e27e37eb3f97de4c58e8adaf223b7947cf26 (diff)
Turns out interrupts for Ebus devices are wired to the *other* PCI Expres leaf
on the v445 (compared to the v215/v245). Generalize the code to allow for arbitrary wirings. Makes the serial console on the v445 work.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc64/dev/ebus_mainbus.c61
-rw-r--r--sys/arch/sparc64/dev/ebusvar.h8
2 files changed, 34 insertions, 35 deletions
diff --git a/sys/arch/sparc64/dev/ebus_mainbus.c b/sys/arch/sparc64/dev/ebus_mainbus.c
index 7b14a60537b..58e18357c1e 100644
--- a/sys/arch/sparc64/dev/ebus_mainbus.c
+++ b/sys/arch/sparc64/dev/ebus_mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ebus_mainbus.c,v 1.7 2010/11/11 17:58:23 miod Exp $ */
+/* $OpenBSD: ebus_mainbus.c,v 1.8 2012/08/17 20:41:27 kettenis Exp $ */
/*
* Copyright (c) 2007 Mark Kettenis
@@ -87,29 +87,7 @@ ebus_mainbus_attach(struct device *parent, struct device *self, void *aux)
struct ebus_interrupt_map_mask *immp;
int node, nmapmask, error;
struct pyro_softc *psc;
- int i;
-
- sc->sc_node = node = ma->ma_node;
- sc->sc_ign = INTIGN((ma->ma_upaid) << INTMAP_IGN_SHIFT);
-
- if (CPU_ISSUN4U) {
- printf(": ign %x", sc->sc_ign);
-
- for (i = 0; i < pyro_cd.cd_ndevs; i++) {
- psc = pyro_cd.cd_devs[i];
- if (psc && psc->sc_ign == sc->sc_ign) {
- sc->sc_bust = psc->sc_bust;
- sc->sc_csr = psc->sc_csr;
- sc->sc_csrh = psc->sc_csrh;
- break;
- }
- }
-
- if (sc->sc_csr == 0) {
- printf(": can't find matching host bridge leaf\n");
- return;
- }
- }
+ int i, j;
printf("\n");
@@ -117,6 +95,8 @@ ebus_mainbus_attach(struct device *parent, struct device *self, void *aux)
sc->sc_iotag = ebus_alloc_bus_tag(sc, ma->ma_bustag);
sc->sc_dmatag = ebus_alloc_dma_tag(sc, ma->ma_dmatag);
+ sc->sc_node = node = ma->ma_node;
+
/*
* fill in our softc with information from the prom
*/
@@ -143,6 +123,22 @@ ebus_mainbus_attach(struct device *parent, struct device *self, void *aux)
break;
}
+ /*
+ * Ebus interrupts may be connected to any of the PCI Express
+ * leafs. Here we add the appropriate IGN to the interrupt
+ * mappings such that we can use it to distingish between
+ * intterupts connected to PCIE-A and PCIE-B.
+ */
+ for (i = 0; i < sc->sc_nintmap; i++) {
+ for (j = 0; j < pyro_cd.cd_ndevs; j++) {
+ psc = pyro_cd.cd_devs[j];
+ if (psc && psc->sc_node == sc->sc_intmap[i].cnode) {
+ sc->sc_intmap[i].cintr |= psc->sc_ign;
+ break;
+ }
+ }
+ }
+
error = getprop(node, "ranges", sizeof(struct ebus_mainbus_ranges),
&sc->sc_nrange, (void **)&sc->sc_range);
if (error)
@@ -298,15 +294,24 @@ ebus_mainbus_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int ihandle,
}
#endif
- ihandle |= sc->sc_ign;
ino = INTINO(ihandle);
if ((flags & BUS_INTR_ESTABLISH_SOFTINTR) == 0) {
+ struct pyro_softc *psc = NULL;
u_int64_t *imap, *iclr;
+ int i;
+
+ for (i = 0; i < pyro_cd.cd_ndevs; i++) {
+ psc = pyro_cd.cd_devs[i];
+ if (psc && psc->sc_ign == INTIGN(ihandle)) {
+ break;
+ }
+ }
+ if (psc == NULL)
+ return (NULL);
- /* XXX */
- imap = bus_space_vaddr(sc->sc_bust, sc->sc_csrh) + 0x1000;
- iclr = bus_space_vaddr(sc->sc_bust, sc->sc_csrh) + 0x1400;
+ imap = bus_space_vaddr(psc->sc_bust, psc->sc_csrh) + 0x1000;
+ iclr = bus_space_vaddr(psc->sc_bust, psc->sc_csrh) + 0x1400;
intrmapptr = &imap[ino];
intrclrptr = &iclr[ino];
ino |= INTVEC(ihandle);
diff --git a/sys/arch/sparc64/dev/ebusvar.h b/sys/arch/sparc64/dev/ebusvar.h
index cf626495f3f..4fc58248bc9 100644
--- a/sys/arch/sparc64/dev/ebusvar.h
+++ b/sys/arch/sparc64/dev/ebusvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ebusvar.h,v 1.6 2007/04/04 18:38:54 kettenis Exp $ */
+/* $OpenBSD: ebusvar.h,v 1.7 2012/08/17 20:41:27 kettenis Exp $ */
/* $NetBSD: ebusvar.h,v 1.5 2001/07/20 00:07:13 eeh Exp $ */
/*
@@ -69,12 +69,6 @@ struct ebus_softc {
int sc_nrange; /* counters */
int sc_nintmap;
-
- int sc_ign;
-
- bus_space_tag_t sc_bust;
- bus_addr_t sc_csr;
- bus_space_handle_t sc_csrh;
};