diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2012-08-17 20:41:28 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2012-08-17 20:41:28 +0000 |
commit | 795c9e7e841224f48581c52e1043a450f43efe02 (patch) | |
tree | 3e3e8eeea5570c16a950b7eaad66192ab6beb513 /sys/arch/sparc64/dev | |
parent | 9819e27e37eb3f97de4c58e8adaf223b7947cf26 (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/arch/sparc64/dev')
-rw-r--r-- | sys/arch/sparc64/dev/ebus_mainbus.c | 61 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/ebusvar.h | 8 |
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; }; |