summaryrefslogtreecommitdiffstats
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2008-08-20 18:29:59 +0000
committerjhb <jhb@FreeBSD.org>2008-08-20 18:29:59 +0000
commitd2bd463b118070e22797bf3db3289d86418dcb13 (patch)
treeefb548d5d344f8b45c84a43bbd5158cf2ce6bd8d /sys/dev/pci
parentc2eea24c16c70f2e944cdd05fb36b842069fb39c (diff)
downloadFreeBSD-src-d2bd463b118070e22797bf3db3289d86418dcb13.zip
FreeBSD-src-d2bd463b118070e22797bf3db3289d86418dcb13.tar.gz
The config space registers holding the upper 32-bits of the prefetchable
memory area's base and limit are optional. The low 4-bits of the "low" prefetchable registers indicates whether or not a 32-bit or 64-bit region is supported. The PCI-PCI driver had been assuming that all bridges supported a 64-bit region (and thus the two upper 32-bit registers). Fix the driver to only use those registers if the low 4-bits of the "low" registers indicate that a 64-bit region is supported. The PCI-PCI bridge in the XBox happens to be a bridge that only supports a 32-bit region. Reported by: rink MFC after: 1 week
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/pci_pci.c20
-rw-r--r--sys/dev/pci/pcireg.h3
2 files changed, 19 insertions, 4 deletions
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
index 8c54188..ee60678 100644
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -198,10 +198,22 @@ pcib_attach_common(device_t dev)
if (sc->command & PCIM_CMD_MEMEN) {
sc->membase = PCI_PPBMEMBASE(0, pci_read_config(dev, PCIR_MEMBASE_1, 2));
sc->memlimit = PCI_PPBMEMLIMIT(0, pci_read_config(dev, PCIR_MEMLIMIT_1, 2));
- sc->pmembase = PCI_PPBMEMBASE(pci_read_config(dev, PCIR_PMBASEH_1, 4),
- pci_read_config(dev, PCIR_PMBASEL_1, 2));
- sc->pmemlimit = PCI_PPBMEMLIMIT(pci_read_config(dev, PCIR_PMLIMITH_1, 4),
- pci_read_config(dev, PCIR_PMLIMITL_1, 2));
+ iolow = pci_read_config(dev, PCIR_PMBASEL_1, 1);
+ if ((iolow & PCIM_BRPM_MASK) == PCIM_BRPM_64)
+ sc->pmembase = PCI_PPBMEMBASE(
+ pci_read_config(dev, PCIR_PMBASEH_1, 4),
+ pci_read_config(dev, PCIR_PMBASEL_1, 2));
+ else
+ sc->pmembase = PCI_PPBMEMBASE(0,
+ pci_read_config(dev, PCIR_PMBASEL_1, 2));
+ iolow = pci_read_config(dev, PCIR_PMLIMITL_1, 1);
+ if ((iolow & PCIM_BRPM_MASK) == PCIM_BRPM_64)
+ sc->pmemlimit = PCI_PPBMEMLIMIT(
+ pci_read_config(dev, PCIR_PMLIMITH_1, 4),
+ pci_read_config(dev, PCIR_PMLIMITL_1, 2));
+ else
+ sc->pmemlimit = PCI_PPBMEMLIMIT(0,
+ pci_read_config(dev, PCIR_PMLIMITL_1, 2));
}
/*
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index 6ec6600..b28dbb3 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -180,6 +180,9 @@
#define PCIR_PMLIMITL_1 0x26
#define PCIR_PMBASEH_1 0x28
#define PCIR_PMLIMITH_1 0x2c
+#define PCIM_BRPM_32 0x0
+#define PCIM_BRPM_64 0x1
+#define PCIM_BRPM_MASK 0xf
#define PCIR_BRIDGECTL_1 0x3e
OpenPOWER on IntegriCloud