summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2010-01-15 16:46:03 +0000
committermarius <marius@FreeBSD.org>2010-01-15 16:46:03 +0000
commit3d169bfebbd5c390dabaf09204486bd9d35e51ee (patch)
treef25366d992aebb8bbc624c006907724e62abe757 /sys/sparc64
parent686370214aa5dc433c3cbcc2c8e938a01977a5c7 (diff)
downloadFreeBSD-src-3d169bfebbd5c390dabaf09204486bd9d35e51ee.zip
FreeBSD-src-3d169bfebbd5c390dabaf09204486bd9d35e51ee.tar.gz
MFC: r201395
- 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.
Diffstat (limited to 'sys/sparc64')
-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 0aabb22..0eadc4b 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -554,6 +554,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);
@@ -591,10 +592,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,
@@ -923,6 +925,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];
/*
@@ -1003,6 +1009,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 75769f2..4703571 100644
--- a/sys/sparc64/pci/schizo.c
+++ b/sys/sparc64/pci/schizo.c
@@ -454,6 +454,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 &&
@@ -548,10 +549,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,
@@ -927,6 +929,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.
@@ -975,6 +980,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