diff options
author | marius <marius@FreeBSD.org> | 2010-01-02 15:19:33 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2010-01-02 15:19:33 +0000 |
commit | 4cefbffb963b45c5b1c549db3abfef121be8ec64 (patch) | |
tree | 8aad0017d6861972903241dcf14484535f23541c | |
parent | 2cba096a290d9e965ded84bf606c6ef40a61d0b0 (diff) | |
download | FreeBSD-src-4cefbffb963b45c5b1c549db3abfef121be8ec64.zip FreeBSD-src-4cefbffb963b45c5b1c549db3abfef121be8ec64.tar.gz |
- Preserve the PROM IOMMU in order to allow OFW drivers to continue to
work.
- Sanity check the parameters passed to the implementations of the
pcib_{read,write}_config() methods. Using illegal values can cause
no real harm but it doesn't hurt to avoid unnecessary data error
traps requiring to flush and re-enable the level 1 caches.
-rw-r--r-- | sys/sparc64/pci/psycho.c | 14 | ||||
-rw-r--r-- | sys/sparc64/pci/psychovar.h | 1 | ||||
-rw-r--r-- | sys/sparc64/pci/schizo.c | 13 | ||||
-rw-r--r-- | sys/sparc64/pci/schizovar.h | 1 |
4 files changed, 25 insertions, 4 deletions
diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index 236f3de..486136a 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -556,6 +556,7 @@ psycho_attach(device_t dev) M_NOWAIT | M_ZERO); if (sc->sc_is == NULL) panic("%s: malloc iommu_state failed", __func__); + sc->sc_is->is_flags = IOMMU_PRESERVE_PROM; if (sc->sc_mode == PSYCHO_MODE_SABRE) sc->sc_is->is_pmaxaddr = IOMMU_MAXADDR(SABRE_IOMMU_BITS); @@ -593,10 +594,11 @@ psycho_attach(device_t dev) panic("%s: could not get bus-range", __func__); if (i != sizeof(prop_array)) panic("%s: broken bus-range (%d)", __func__, i); + sc->sc_pci_secbus = prop_array[0]; + sc->sc_pci_subbus = prop_array[1]; if (bootverbose) device_printf(dev, "bus range %u to %u; PCI bus %d\n", - prop_array[0], prop_array[1], prop_array[0]); - sc->sc_pci_secbus = prop_array[0]; + sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus); /* Clear any pending PCI error bits. */ PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC, @@ -925,6 +927,10 @@ psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, int i; sc = device_get_softc(dev); + if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus || + slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX) + return (-1); + bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG]; /* @@ -1005,6 +1011,10 @@ psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_long offset = 0; sc = device_get_softc(dev); + if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus || + slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX) + return; + offset = PSYCHO_CONF_OFF(bus, slot, func, reg); bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG]; switch (width) { diff --git a/sys/sparc64/pci/psychovar.h b/sys/sparc64/pci/psychovar.h index 04d81ad..e7c6980 100644 --- a/sys/sparc64/pci/psychovar.h +++ b/sys/sparc64/pci/psychovar.h @@ -75,6 +75,7 @@ struct psycho_softc { struct rman sc_pci_io_rman; uint8_t sc_pci_secbus; + uint8_t sc_pci_subbus; uint8_t sc_pci_hpbcfg[16]; diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c index d9ef5c8..f783b23 100644 --- a/sys/sparc64/pci/schizo.c +++ b/sys/sparc64/pci/schizo.c @@ -456,6 +456,7 @@ schizo_attach(device_t dev) * buffer, in Schizo version < 5 (i.e. revision < 2.3) it's * affected by several errata and basically unusable though. */ + sc->sc_is.is_flags = IOMMU_PRESERVE_PROM; sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(STX_IOMMU_BITS); sc->sc_is.is_sb[0] = sc->sc_is.is_sb[1] = 0; if (OF_getproplen(node, "no-streaming-cache") < 0 && @@ -550,10 +551,11 @@ schizo_attach(device_t dev) panic("%s: could not get bus-range", __func__); if (i != sizeof(prop_array)) panic("%s: broken bus-range (%d)", __func__, i); + sc->sc_pci_secbus = prop_array[0]; + sc->sc_pci_subbus = prop_array[1]; if (bootverbose) device_printf(dev, "bus range %u to %u; PCI bus %d\n", - prop_array[0], prop_array[1], prop_array[0]); - sc->sc_pci_secbus = prop_array[0]; + sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus); /* Clear any pending PCI error bits. */ PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC, @@ -929,6 +931,9 @@ schizo_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, uint8_t byte; sc = device_get_softc(dev); + if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus || + slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX) + return (-1); /* * The Schizo bridges contain a dupe of their header at 0x80. @@ -977,6 +982,10 @@ schizo_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_long offset = 0; sc = device_get_softc(dev); + if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus || + slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX) + return; + offset = STX_CONF_OFF(bus, slot, func, reg); bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG]; switch (width) { diff --git a/sys/sparc64/pci/schizovar.h b/sys/sparc64/pci/schizovar.h index 6b2bca9..144ace7 100644 --- a/sys/sparc64/pci/schizovar.h +++ b/sys/sparc64/pci/schizovar.h @@ -71,6 +71,7 @@ struct schizo_softc { bus_dma_tag_t sc_pci_dmat; uint8_t sc_pci_secbus; + uint8_t sc_pci_subbus; struct ofw_bus_iinfo sc_pci_iinfo; |