diff options
author | jhb <jhb@FreeBSD.org> | 2008-08-20 18:29:59 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2008-08-20 18:29:59 +0000 |
commit | d2bd463b118070e22797bf3db3289d86418dcb13 (patch) | |
tree | efb548d5d344f8b45c84a43bbd5158cf2ce6bd8d /sys/dev/pci | |
parent | c2eea24c16c70f2e944cdd05fb36b842069fb39c (diff) | |
download | FreeBSD-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.c | 20 | ||||
-rw-r--r-- | sys/dev/pci/pcireg.h | 3 |
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 |