[coreboot-gerrit] Patch set updated for coreboot: 8e17510 PCI subsystem: Refactor PCI bridge register control

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Fri Feb 27 17:52:44 CET 2015


Kyösti Mälkki (kyosti.malkki at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8536

-gerrit

commit 8e17510e472ec1b77a158a27a3000c3dbdda1b0c
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Mon Feb 23 06:58:26 2015 +0200

    PCI subsystem: Refactor PCI bridge register control
    
    Change-Id: I1766c92abe7a74326c49df74ba38930a502fcb5b
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
 src/device/pci_device.c     | 76 +++++++++++++++++++++++++++++----------------
 src/include/device/device.h |  1 +
 2 files changed, 51 insertions(+), 26 deletions(-)

diff --git a/src/device/pci_device.c b/src/device/pci_device.c
index 127ee32..d3a7865 100644
--- a/src/device/pci_device.c
+++ b/src/device/pci_device.c
@@ -1167,6 +1167,53 @@ unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn,
 	return max;
 }
 
+typedef enum {
+	PCI_ROUTE_CLOSE,
+	PCI_ROUTE_SCAN,
+	PCI_ROUTE_FINAL,
+} scan_state;
+
+static void pci_bridge_route(struct bus *link, scan_state state)
+{
+	struct device *dev = link->dev;
+	struct bus *parent = dev->bus;
+	u32 reg, buses = 0;
+
+	if (state == PCI_ROUTE_CLOSE) {
+		buses |= 0xfeff << 8;
+	} else if (state == PCI_ROUTE_SCAN) {
+		buses |= ((u32) link->secondary & 0xff) << 8;
+		buses |= ((u32) link->subordinate & 0xff) << 16;
+	} else if (state == PCI_ROUTE_FINAL) {
+		buses |= parent->secondary & 0xff;
+		buses |= ((u32) link->secondary & 0xff) << 8;
+		buses |= ((u32) link->subordinate & 0xff) << 16;
+	}
+
+	if (state == PCI_ROUTE_SCAN) {
+		/* Clear all status bits and turn off memory, I/O and master enables. */
+		link->bridge_cmd = pci_read_config16(dev, PCI_COMMAND);
+		pci_write_config16(dev, PCI_COMMAND, 0x0000);
+		pci_write_config16(dev, PCI_STATUS, 0xffff);
+	}
+
+	/*
+	 * Configure the bus numbers for this bridge: the configuration
+	 * transactions will not be propagated by the bridge if it is not
+	 * correctly configured.
+	 */
+
+	reg = pci_read_config32(dev, PCI_PRIMARY_BUS);
+	reg &= 0xff000000;
+	reg |= buses;
+	pci_write_config32(dev, PCI_PRIMARY_BUS, reg);
+
+	if (state == PCI_ROUTE_FINAL) {
+		pci_write_config16(dev, PCI_COMMAND, link->bridge_cmd);
+	}
+}
+
+
 /**
  * Scan a PCI bridge and the buses behind the bridge.
  *
@@ -1187,8 +1234,6 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
 							     unsigned int max))
 {
 	struct bus *bus;
-	u32 buses;
-	u16 cr;
 
 	printk(BIOS_SPEW, "%s for %s\n", __func__, dev_path(dev));
 
@@ -1212,27 +1257,7 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
 	bus->secondary = ++max;
 	bus->subordinate = 0xff;
 
-	/* Clear all status bits and turn off memory, I/O and master enables. */
-	cr = pci_read_config16(dev, PCI_COMMAND);
-	pci_write_config16(dev, PCI_COMMAND, 0x0000);
-	pci_write_config16(dev, PCI_STATUS, 0xffff);
-
-	/*
-	 * Read the existing primary/secondary/subordinate bus
-	 * number configuration.
-	 */
-	buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
-
-	/*
-	 * Configure the bus numbers for this bridge: the configuration
-	 * transactions will not be propagated by the bridge if it is not
-	 * correctly configured.
-	 */
-	buses &= 0xff000000;
-	buses |= (((unsigned int)(dev->bus->secondary) << 0) |
-		  ((unsigned int)(bus->secondary) << 8) |
-		  ((unsigned int)(bus->subordinate) << 16));
-	pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
+	pci_bridge_route(bus, PCI_ROUTE_SCAN);
 
 	/* Now we can scan all subordinate buses (those behind the bridge). */
 	max = do_scan_bus(bus, 0x00, 0xff, max);
@@ -1242,9 +1267,8 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
 	 * bus number to its real value.
 	 */
 	bus->subordinate = max;
-	buses = (buses & 0xff00ffff) | ((unsigned int)(bus->subordinate) << 16);
-	pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
-	pci_write_config16(dev, PCI_COMMAND, cr);
+
+	pci_bridge_route(bus, PCI_ROUTE_FINAL);
 
 	printk(BIOS_SPEW, "%s returns max %d\n", __func__, max);
 	return max;
diff --git a/src/include/device/device.h b/src/include/device/device.h
index 559557a..436420f 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -81,6 +81,7 @@ struct bus {
 	ROMSTAGE_CONST struct device * 	children;	/* devices behind this bridge */
 	ROMSTAGE_CONST struct bus	*next;		/* The next bridge on this device */
 	unsigned	bridge_ctrl;	/* Bridge control register */
+	uint16_t	bridge_cmd;		/* Bridge command register */
 	unsigned char	link_num;	/* The index of this link */
 	uint16_t	secondary; 	/* secondary bus number */
 	uint16_t	subordinate;	/* max subordinate bus number */



More information about the coreboot-gerrit mailing list