[coreboot-gerrit] New patch to review for coreboot: 4ff54a5 PCI subsystem: Refactor PCI bridge register control
Kyösti Mälkki (kyosti.malkki@gmail.com)
gerrit at coreboot.org
Fri Feb 27 17:32:49 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 4ff54a5769341ea66f7557324a8114c292941b24
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