summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2010-01-02 15:19:33 +0000
committermarius <marius@FreeBSD.org>2010-01-02 15:19:33 +0000
commit4cefbffb963b45c5b1c549db3abfef121be8ec64 (patch)
tree8aad0017d6861972903241dcf14484535f23541c
parent2cba096a290d9e965ded84bf606c6ef40a61d0b0 (diff)
downloadFreeBSD-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.c14
-rw-r--r--sys/sparc64/pci/psychovar.h1
-rw-r--r--sys/sparc64/pci/schizo.c13
-rw-r--r--sys/sparc64/pci/schizovar.h1
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;
OpenPOWER on IntegriCloud