Index: sys/arch/sparc64/dev/ebus_mainbus.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/dev/ebus_mainbus.c,v retrieving revision 1.12 diff -u -r1.12 ebus_mainbus.c --- sys/arch/sparc64/dev/ebus_mainbus.c 16 Dec 2013 20:17:35 -0000 1.12 +++ sys/arch/sparc64/dev/ebus_mainbus.c 22 Aug 2014 20:12:07 -0000 @@ -56,6 +56,8 @@ #include #include +extern struct cfdriver pyro_cd; + int ebus_mainbus_match(device_t, cfdata_t, void *); void ebus_mainbus_attach(device_t, device_t, void *); @@ -93,34 +95,10 @@ struct ebus_interrupt_map_mask *immp; int node, nmapmask, error; struct pyro_softc *psc; - int i; + int i, j; sc->sc_dev = self; - 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); - /* XXX */ - extern struct cfdriver pyro_cd; - - for (i = 0; i < pyro_cd.cd_ndevs; i++) { - device_t dt = pyro_cd.cd_devs[i]; - psc = device_private(dt); - if (psc && psc->sc_ign == sc->sc_ign) { - sc->sc_bust = psc->sc_bustag; - 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; - } - } - + printf("\n"); sc->sc_memtag = ebus_mainbus_alloc_bus_tag(sc, ma->ma_bustag, @@ -130,6 +108,8 @@ sc->sc_childbustag = sc->sc_memtag; sc->sc_dmatag = ma->ma_dmatag; + sc->sc_node = node = ma->ma_node; + /* * fill in our softc with information from the prom */ @@ -158,6 +138,23 @@ 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 + * interrupts connected to PCIE-A and PCIE-B. + */ + for (i = 0; i < sc->sc_nintmap; i++) { + for (j = 0; j < pyro_cd.cd_ndevs; j++) { + device_t dt = pyro_cd.cd_devs[j]; + psc = device_private(dt); + if (psc && psc->sc_node == sc->sc_intmap[i].cnode) { + sc->sc_intmap[i].cintr |= psc->sc_ign; + break; + } + } + } + error = prom_getprop(node, "ranges", sizeof(struct ebus_mainbus_ranges), &sc->sc_nrange, (void **)&sc->sc_range); if (error) @@ -275,7 +272,6 @@ ebus_mainbus_intr_establish(bus_space_tag_t t, int ihandle, int level, int (*handler)(void *), void *arg, void (*fastvec)(void) /* ignored */) { - struct ebus_softc *sc = t->cookie; struct intrhand *ih = NULL; volatile u_int64_t *intrmapptr = NULL, *intrclrptr = NULL; u_int64_t *imap, *iclr; @@ -334,12 +330,24 @@ } #endif #endif - ihandle |= sc->sc_ign; + ino = INTINO(ihandle); - /* XXX */ - imap = (uint64_t *)((uintptr_t)bus_space_vaddr(sc->sc_bustag, sc->sc_csrh) + 0x1000); - iclr = (uint64_t *)((uintptr_t)bus_space_vaddr(sc->sc_bustag, sc->sc_csrh) + 0x1400); + struct pyro_softc *psc = NULL; + int i; + + for (i = 0; i < pyro_cd.cd_ndevs; i++) { + device_t dt = pyro_cd.cd_devs[i]; + psc = device_private(dt); + if (psc && psc->sc_ign == INTIGN(ihandle)) { + break; + } + } + if (psc == NULL) + return (NULL); + + imap = (uint64_t *)((uintptr_t)bus_space_vaddr(psc->sc_bustag, psc->sc_csrh) + 0x1000); + iclr = (uint64_t *)((uintptr_t)bus_space_vaddr(psc->sc_bustag, psc->sc_csrh) + 0x1400); intrmapptr = &imap[ino]; intrclrptr = &iclr[ino]; ino |= INTVEC(ihandle); Index: sys/arch/sparc64/dev/ebusvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/dev/ebusvar.h,v retrieving revision 1.11 diff -u -r1.11 ebusvar.h --- sys/arch/sparc64/dev/ebusvar.h 1 Jul 2011 18:48:36 -0000 1.11 +++ sys/arch/sparc64/dev/ebusvar.h 22 Aug 2014 20:12:07 -0000 @@ -61,12 +61,6 @@ 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; }; int ebus_setup_attach_args(struct ebus_softc *, int, Index: sys/arch/sparc64/dev/iommu.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/dev/iommu.c,v retrieving revision 1.107 diff -u -r1.107 iommu.c --- sys/arch/sparc64/dev/iommu.c 25 Mar 2012 03:51:33 -0000 1.107 +++ sys/arch/sparc64/dev/iommu.c 22 Aug 2014 20:12:07 -0000 @@ -134,7 +134,15 @@ * be hard-wired, so we read the start and size from the PROM and * just use those values. */ - is->is_cr = IOMMUCR_EN; + if (strncmp(name, "pyro", 4) == 0) { + is->is_cr = IOMMUREG_READ(is, iommu_cr); + is->is_cr &= ~IOMMUCR_FIRE_BE; + is->is_cr |= (IOMMUCR_FIRE_SE | IOMMUCR_FIRE_CM_EN | + IOMMUCR_FIRE_TE); + } else + is->is_cr = IOMMUCR_EN; is->is_tsbsize = tsbsize; if (iovabase == -1) { is->is_dvmabase = IOTSB_VSTART(is->is_tsbsize); Index: sys/arch/sparc64/dev/iommureg.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/dev/iommureg.h,v retrieving revision 1.19 diff -u -r1.19 iommureg.h --- sys/arch/sparc64/dev/iommureg.h 20 Mar 2011 20:42:06 -0000 1.19 +++ sys/arch/sparc64/dev/iommureg.h 22 Aug 2014 20:12:07 -0000 @@ -110,6 +110,11 @@ #define IOMMUCR_DE 0x000000000000000002LL /* Diag enable */ #define IOMMUCR_EN 0x000000000000000001LL /* Enable IOMMU */ +#define IOMMUCR_FIRE_SE 0x000000000000000400LL /* Snoop enable */ +#define IOMMUCR_FIRE_CM_EN 0x000000000000000300LL /* Cache mode enable */ +#define IOMMUCR_FIRE_BE 0x000000000000000002LL /* Bypass enable */ +#define IOMMUCR_FIRE_TE 0x000000000000000001LL /* Translation enabled */ + /* * IOMMU stuff */