summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>2000-12-12 13:20:35 +0000
committermsmith <msmith@FreeBSD.org>2000-12-12 13:20:35 +0000
commit3246f521daddcdd0cd1d7e634b58ab9043c0d7f9 (patch)
treedc3d07f60227cdeebf81d00cb3d37cf32abc8fd7
parent98070a71a38611a90a30345cff491368a1509f82 (diff)
downloadFreeBSD-src-3246f521daddcdd0cd1d7e634b58ab9043c0d7f9.zip
FreeBSD-src-3246f521daddcdd0cd1d7e634b58ab9043c0d7f9.tar.gz
- We have access to our own device_t here, so use pci_read_config
rather than finding our parent pcib and using its PCI_READ_CONFIG method. - Fix the defines for the 32-bit I/O decode registers, and properly process the 16-bit versions. Now we will correctly check that I/O resources behind the bridge are going to be decoded. - Bring the quirk for the Orion PCI:PCI bridge in here (since it seems to want to set the secondary/supplementary bus numbers). - Use PCI_SLOTMAX rather than a magic number.
-rw-r--r--sys/dev/pci/pci_pci.c94
-rw-r--r--sys/dev/pci/pcireg.h13
2 files changed, 77 insertions, 30 deletions
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
index 3341a20..6bcb15a 100644
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -132,31 +132,67 @@ static int
pcib_attach(device_t dev)
{
struct pcib_softc *sc;
- device_t pcib, child;
- int b, s, f;
+ device_t child;
+ u_int8_t iolow;
sc = device_get_softc(dev);
sc->dev = dev;
- pcib = device_get_parent(dev);
- b = pci_get_bus(dev);
- s = pci_get_slot(dev);
- f = pci_get_function(dev);
-
- sc->secbus = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECBUS_1, 1);
- sc->subbus = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SUBBUS_1, 1);
- sc->secstat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECSTAT_1, 2);
- sc->bridgectl = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_BRIDGECTL_1, 2);
- sc->seclat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECLAT_1, 1);
- sc->iobase = PCI_PPBIOBASE(PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOBASEH_1, 2),
- PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOBASEL_1, 1));
- sc->iolimit = PCI_PPBIOLIMIT(PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOLIMITH_1, 2),
- PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOLIMITL_1, 1));
- sc->membase = PCI_PPBMEMBASE(0, PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMBASE_1, 2));
- sc->memlimit = PCI_PPBMEMLIMIT(0, PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMLIMIT_1, 2));
- sc->pmembase = PCI_PPBMEMBASE((pci_addr_t)PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMBASEH_1, 4),
- PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMBASEL_1, 2));
- sc->pmemlimit = PCI_PPBMEMLIMIT((pci_addr_t)PCIB_READ_CONFIG(pcib, b, s, f,PCIR_PMLIMITH_1, 4),
- PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMLIMITL_1, 2));
+
+ /*
+ * Get current bridge configuration.
+ */
+ sc->secbus = pci_read_config(dev, PCIR_SECBUS_1, 1);
+ sc->subbus = pci_read_config(dev, PCIR_SUBBUS_1, 1);
+ sc->secstat = pci_read_config(dev, PCIR_SECSTAT_1, 2);
+ sc->bridgectl = pci_read_config(dev, PCIR_BRIDGECTL_1, 2);
+ sc->seclat = pci_read_config(dev, PCIR_SECLAT_1, 1);
+
+ /*
+ * Determine current I/O decode.
+ */
+ iolow = pci_read_config(dev, PCIR_IOBASEL_1, 1);
+ if ((iolow & PCIM_BRIO_MASK) == PCIM_BRIO_32) {
+ sc->iobase = PCI_PPBIOBASE(pci_read_config(dev, PCIR_IOBASEH_1, 2),
+ pci_read_config(dev, PCIR_IOBASEL_1, 1));
+ } else {
+ sc->iobase = PCI_PPBIOBASE(0, pci_read_config(dev, PCIR_IOBASEL_1, 1));
+ }
+
+ iolow = pci_read_config(dev, PCIR_IOLIMITL_1, 1);
+ if ((iolow & PCIM_BRIO_MASK) == PCIM_BRIO_32) {
+ sc->iolimit = PCI_PPBIOLIMIT(pci_read_config(dev, PCIR_IOLIMITH_1, 2),
+ pci_read_config(dev, PCIR_IOLIMITL_1, 1));
+ } else {
+ sc->iolimit = PCI_PPBIOLIMIT(0, pci_read_config(dev, PCIR_IOLIMITL_1, 1));
+ }
+
+ /*
+ * Determine current memory decode.
+ */
+ 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_addr_t)pci_read_config(dev, PCIR_PMBASEH_1, 4),
+ pci_read_config(dev, PCIR_PMBASEL_1, 2));
+ sc->pmemlimit = PCI_PPBMEMLIMIT((pci_addr_t)pci_read_config(dev, PCIR_PMLIMITH_1, 4),
+ pci_read_config(dev, PCIR_PMLIMITL_1, 2));
+
+ /*
+ * Quirk handling.
+ */
+ switch (pci_get_devid(dev)) {
+ case 0x12258086: /* Intel 82454KX/GX (Orion) */
+ {
+ u_int8_t supbus;
+
+ supbus = pci_read_config(dev, 0x41, 1);
+ if (supbus != 0xff) {
+ sc->secbus = supbus + 1;
+ sc->subbus = supbus + 1;
+ }
+ }
+ break;
+ }
+
if (bootverbose) {
device_printf(dev, " secondary bus %d\n", sc->secbus);
@@ -247,6 +283,9 @@ pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
sc->iobase, sc->iolimit);
return(NULL);
}
+ if (bootverbose)
+ device_printf(sc->dev, "device %s%d requested decoded I/O range 0x%lx-0x%lx\n",
+ device_get_name(child), device_get_unit(child), start, end);
break;
/*
@@ -264,11 +303,16 @@ pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
sc->membase, sc->memlimit, sc->pmembase, sc->pmemlimit);
return(NULL);
}
+ if (bootverbose)
+ device_printf(sc->dev, "device %s%d requested decoded memory range 0x%lx-0x%lx\n",
+ device_get_name(child), device_get_unit(child), start, end);
+ break;
+
default:
+ break;
}
}
- device_printf(sc->dev, "resource request type %d 0x%lx-0x%lx decodes OK\n",
- type, start, end);
+
/*
* Bridge is OK decoding this resource, so pass it up.
*/
@@ -281,7 +325,7 @@ pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
static int
pcib_maxslots(device_t dev)
{
- return(31);
+ return(PCI_SLOTMAX);
}
/*
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index eb5c471..35297e4 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -90,18 +90,21 @@
#define PCIR_IOBASEL_1 0x1c
#define PCIR_IOLIMITL_1 0x1d
-#define PCIR_IOBASEH_1 0 /**/
-#define PCIR_IOLIMITH_1 0 /**/
+#define PCIR_IOBASEH_1 0x30
+#define PCIR_IOLIMITH_1 0x32
+#define PCIM_BRIO_16 0x0
+#define PCIM_BRIO_32 0x1
+#define PCIM_BRIO_MASK 0xf
#define PCIR_MEMBASE_1 0x20
#define PCIR_MEMLIMIT_1 0x22
#define PCIR_PMBASEL_1 0x24
#define PCIR_PMLIMITL_1 0x26
-#define PCIR_PMBASEH_1 0 /**/
-#define PCIR_PMLIMITH_1 0 /**/
+#define PCIR_PMBASEH_1 0x28
+#define PCIR_PMLIMITH_1 0x2c
-#define PCIR_BRIDGECTL_1 0 /**/
+#define PCIR_BRIDGECTL_1 0x3e
#define PCIR_SUBVEND_1 0x34
#define PCIR_SUBDEV_1 0x36
OpenPOWER on IntegriCloud