[OpenBIOS] [PATCH 06/10] pci: bus scan amendment

Igor V. Kovalenko igor.v.kovalenko at gmail.com
Tue May 25 14:38:21 CEST 2010


From: Igor V. Kovalenko <igor.v.kovalenko at gmail.com>

- refactor scan procedure to start with PCI host controller
- initiate scan of subordinate PCI bus from PCI host and PCI-to-PCI bridges
- find out PCI subordinate bus numbers and write them to bride devices
- automated assignment of "reg", "ranges", and "bus-range" properties

Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko at gmail.com>
---
 drivers/pci.c                  |  488 +++++++++++++++++++++++++++-------------
 drivers/pci.h                  |    4 
 drivers/pci_database.h         |    3 
 drivers/vga_vbe.c              |    6 
 include/libopenbios/bindings.h |    8 +
 libopenbios/bindings.c         |    6 
 6 files changed, 347 insertions(+), 168 deletions(-)

diff --git a/drivers/pci.c b/drivers/pci.c
index 5676749..f8d0b41 100644
--- a/drivers/pci.c
+++ b/drivers/pci.c
@@ -125,6 +125,18 @@ static int parent_size_cells(void)
 }
 */
 
+#if defined(CONFIG_DEBUG_PCI)
+static void dump_reg_property(const char* description, int nreg, u32 *reg)
+{
+    int i;
+    printk("%s reg", description);
+    for (i=0; i < nreg; ++i) {
+        printk(" %08X", reg[i]);
+    }
+    printk("\n");
+}
+#endif
+
 static void
 ob_pci_open(int *idx)
 {
@@ -153,6 +165,8 @@ ob_pci_decode_unit(int *idx)
 	int bus = 0;		/* no information */
 	char *ptr;
 
+	PCI_DPRINTF("ob_pci_decode_unit idx=%p\n", idx);
+
 	fn = 0;
 	reg = 0;
 	n = 0;
@@ -245,6 +259,10 @@ ob_pci_decode_unit(int *idx)
 	PUSH(lo);
 	PUSH(mid);
 	PUSH(hi);
+
+	PCI_DPRINTF("ob_pci_decode_unit idx=%p addr="
+	        FMT_ucellx " " FMT_ucellx " " FMT_ucellx "\n",
+	        idx, lo, mid, hi);
 }
 
 /*  ( phys.lo phy.mid phys.hi -- str len ) */
@@ -305,6 +323,9 @@ ob_pci_encode_unit(int *idx)
 		break;
 	}
 	push_str(buf);
+
+	PCI_DPRINTF("ob_pci_encode_unit space=%d dev=%d fn=%d buf=%s\n",
+	        ss, dev, fn, buf);
 }
 
 NODE_METHODS(ob_pci_bus_node) = {
@@ -323,11 +344,22 @@ NODE_METHODS(ob_pci_simple_node) = {
 
 static void pci_set_bus_range(const pci_config_t *config)
 {
-	phandle_t dev = get_cur_dev();
+	phandle_t dev = find_dev(config->path);
 	u32 props[2];
 
-	props[0] = (config->dev >> 16) & 0xFF;
-	props[1] = 1;
+	props[0] = config->secondary_bus;
+	props[1] = config->subordinate_bus;
+
+	PCI_DPRINTF("setting bus range for %s PCI device, "
+	        "package handle " FMT_ucellx " "
+            "bus primary=%d secondary=%d subordinate=%d\n",
+            config->path,
+            dev,
+            config->primary_bus,
+            config->secondary_bus,
+            config->subordinate_bus);
+
+
 	set_property(dev, "bus-range", (char *)props, 2 * sizeof(props[0]));
 }
 
@@ -372,9 +404,10 @@ static void pci_host_set_interrupt_map(const pci_config_t *config)
 #endif
 }
 
-static void pci_host_set_reg(const pci_config_t *config)
+static void pci_host_set_reg(phandle_t phandle)
 {
-    phandle_t dev = get_cur_dev();
+    phandle_t dev = phandle;
+
     /* at most 2 integers for address and size */
     u32 props[4];
     int ncells = 0;
@@ -386,6 +419,10 @@ static void pci_host_set_reg(const pci_config_t *config)
             arch->cfg_len);
 
     set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
+
+#if defined(CONFIG_DEBUG_PCI)
+    dump_reg_property("pci_host_set_reg", 4, props);
+#endif
 }
 
 /* child-phys : parent-phys : size */
@@ -438,68 +475,18 @@ static unsigned long pci_bus_addr_to_host_addr(uint32_t ba)
 
 int host_config_cb(const pci_config_t *config)
 {
-	phandle_t aliases;
-
-	aliases = find_dev("/aliases");
-	if (aliases)
-		set_property(aliases, "pci",
-			     config->path, strlen(config->path) + 1);
-
 	//XXX this overrides "reg" property
-	pci_host_set_reg(config);
+	pci_host_set_reg(get_cur_dev());
 	pci_host_set_ranges(config);
-	pci_set_bus_range(config);
 	pci_host_set_interrupt_map(config);
 
 	return 0;
 }
 
-int sabre_config_cb(const pci_config_t *config)
+static int sabre_configure(phandle_t dev)
 {
-        phandle_t dev = get_cur_dev();
         uint32_t props[28];
 
-        props[0] = 0x00000000;
-        props[1] = 0x00000003;
-        set_property(dev, "bus-range", (char *)props, 2 * sizeof(props[0]));
-        props[0] = 0x000001fe;
-        props[1] = 0x00000000;
-        props[2] = 0x00000000;
-        props[3] = 0x00010000;
-        props[4] = 0x000001fe;
-        props[5] = 0x01000000;
-        props[6] = 0x00000000;
-        props[7] = 0x00000100;
-        set_property(dev, "reg", (char *)props, 8 * sizeof(props[0]));
-        props[0] = 0x00000000;
-        props[1] = 0x00000000;
-        props[2] = 0x00000000;
-        props[3] = 0x000001fe;
-        props[4] = 0x01000000;
-        props[5] = 0x00000000;
-        props[6] = 0x01000000;
-        props[7] = 0x01000000;
-        props[8] = 0x00000000;
-        props[9] = 0x00000000;
-        props[10] = 0x000001fe;
-        props[11] = 0x02000000;
-        props[12] = 0x00000000;
-        props[13] = 0x01000000;
-        props[14] = 0x02000000;
-        props[15] = 0x00000000;
-        props[16] = 0x00000000;
-        props[17] = 0x000001ff;
-        props[18] = 0x00000000;
-        props[19] = 0x00000001;
-        props[20] = 0x00000000;
-        props[21] = 0x03000000;
-        props[22] = 0x00000000;
-        props[23] = 0x00000000;
-        props[24] = 0x000001ff;
-        props[25] = 0x00000000;
-        props[26] = 0x00000001;
-        props[27] = 0x00000000;
-        set_property(dev, "ranges", (char *)props, 28 * sizeof(props[0]));
         props[0] = 0xc0000000;
         props[1] = 0x20000000;
         set_property(dev, "virtual-dma", (char *)props, 2 * sizeof(props[0]));
@@ -518,6 +505,13 @@ int sabre_config_cb(const pci_config_t *config)
         return 0;
 }
 
+int sabre_config_cb(const pci_config_t *config)
+{
+    host_config_cb(config);
+
+    return sabre_configure(get_cur_dev());
+}
+
 int bridge_config_cb(const pci_config_t *config)
 {
 	phandle_t aliases;
@@ -525,8 +519,6 @@ int bridge_config_cb(const pci_config_t *config)
 	aliases = find_dev("/aliases");
 	set_property(aliases, "bridge", config->path, strlen(config->path) + 1);
 
-	pci_set_bus_range(config);
-
 	return 0;
 }
 
@@ -599,9 +591,10 @@ static void pci_set_AAPL_address(const pci_config_t *config)
 			     ncells * sizeof(cell));
 }
 
-static void pci_set_assigned_addresses(const pci_config_t *config, int num_bars)
+static void pci_set_assigned_addresses(phandle_t phandle,
+                                       const pci_config_t *config, int num_bars)
 {
-	phandle_t dev = get_cur_dev();
+	phandle_t dev = phandle;
 	u32 props[32];
 	int ncells;
 	int i;
@@ -628,9 +621,32 @@ static void pci_set_assigned_addresses(const pci_config_t *config, int num_bars)
 			     ncells * sizeof(props[0]));
 }
 
-static void pci_set_reg(const pci_config_t *config, int num_bars)
+/* call after writing "reg" property to update config->path */
+static void ob_pci_reload_device_path(phandle_t phandle, pci_config_t *config)
 {
-	phandle_t dev = get_cur_dev();
+    /* since "name" and "reg" are now assigned
+       we need to reload current node name */
+
+    PUSH(phandle);
+    fword("get-package-path");
+    char *new_path = pop_fstr_copy();
+    if (new_path) {
+        if (0 != strcmp(config->path, new_path)) {
+            PCI_DPRINTF("\n=== CHANGED === package path old=%s new=%s\n",
+                    config->path, new_path);
+            strncpy(config->path, new_path, sizeof(config->path));
+            config->path[sizeof(config->path)-1] = '\0';
+        }
+        free(new_path);
+    } else {
+        PCI_DPRINTF("\n=== package path old=%s new=NULL\n", config->path);
+    }
+}
+
+static void pci_set_reg(phandle_t phandle,
+                        pci_config_t *config, int num_bars)
+{
+	phandle_t dev = phandle;
 	u32 props[38];
 	int ncells;
 	int i;
@@ -662,6 +678,11 @@ static void pci_set_reg(const pci_config_t *config, int num_bars)
 	}
 
 	set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
+    ob_pci_reload_device_path(dev, config);
+
+#if defined(CONFIG_DEBUG_PCI)
+    dump_reg_property("pci_set_reg", ncells, props);
+#endif
 }
 
 
@@ -746,10 +767,13 @@ int ebus_config_cb(const pci_config_t *config)
     return 0;
 }
 
-static void ob_pci_add_properties(pci_addr addr, const pci_dev_t *pci_dev,
+static void ob_pci_add_properties(phandle_t phandle,
+                                  pci_addr addr, const pci_dev_t *pci_dev,
                                   const pci_config_t *config, int num_bars)
 {
-	phandle_t dev=get_cur_dev();
+	/* cannot use get_cur_dev() path resolution since "name" and "reg"
+	   properties are being changed */
+	phandle_t dev=phandle;
 	int status,id;
 	uint16_t vendor_id, device_id;
 	uint8_t rev;
@@ -760,6 +784,26 @@ static void ob_pci_add_properties(pci_addr addr, const pci_dev_t *pci_dev,
 	rev = pci_config_read8(addr, PCI_REVISION_ID);
 	class_code = pci_config_read16(addr, PCI_CLASS_DEVICE);
 
+    if (pci_dev) {
+        /**/
+        if (pci_dev->name) {
+            push_str(pci_dev->name);
+            fword("encode-string");
+            push_str("name");
+            fword("property");
+        } else {
+            char path[256];
+            snprintf(path, sizeof(path),
+                    "pci%x,%x", vendor_id, device_id);
+            push_str(path);
+            fword("encode-string");
+            push_str("name");
+            fword("property");
+        }
+    } else {
+        PCI_DPRINTF("*** missing pci_dev\n");
+    }
+
 	/* create properties as described in 2.5 */
 
 	set_int_property(dev, "vendor-id", vendor_id);
@@ -826,14 +870,10 @@ static void ob_pci_add_properties(pci_addr addr, const pci_dev_t *pci_dev,
 					      pci_dev->icells);
 	}
 
-	pci_set_reg(config, num_bars);
-	pci_set_assigned_addresses(config, num_bars);
+	pci_set_assigned_addresses(phandle, config, num_bars);
 	OLDWORLD(pci_set_AAPL_address(config));
 
 	PCI_DPRINTF("\n");
-
-	if (pci_dev && pci_dev->config_cb)
-		pci_dev->config_cb(config);
 }
 
 #ifdef CONFIG_XBOX
@@ -979,113 +1019,235 @@ ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar,
         pci_config_write16(addr, PCI_COMMAND, cmd);
 }
 
-static void ob_scan_pci_bus(int bus, unsigned long *mem_base,
-                            unsigned long *io_base, char **path)
+static void ob_configure_pci_device(const char* parent_path,
+        int *bus_num, unsigned long *mem_base, unsigned long *io_base,
+        int bus, int devnum, int fn, int *p_is_multi);
+
+static void ob_scan_pci_bus(int *bus_num, unsigned long *mem_base,
+                            unsigned long *io_base, const char *path,
+                            int bus)
 {
-	int devnum, fn, is_multi, vid, did;
-	unsigned int htype;
-	pci_addr addr;
-	pci_config_t config;
-        const pci_dev_t *pci_dev;
-	uint32_t ccode;
-        uint8_t class, subclass, iface;
-	int num_bars, rom_bar;
+	int devnum, fn, is_multi;
+
+	PCI_DPRINTF("\nScanning bus %d at %s...\n", bus, path);
 
-	activate_device("/");
 	for (devnum = 0; devnum < 32; devnum++) {
 		is_multi = 0;
 		for (fn = 0; fn==0 || (is_multi && fn<8); fn++) {
-#ifdef CONFIG_XBOX
-			if (pci_xbox_blacklisted (bus, devnum, fn))
-				continue;
-#endif
-			addr = PCI_ADDR(bus, devnum, fn);
-			vid = pci_config_read16(addr, PCI_VENDOR_ID);
-			did = pci_config_read16(addr, PCI_DEVICE_ID);
-
-			if (vid==0xffff || vid==0)
-				continue;
-
-			ccode = pci_config_read16(addr, PCI_CLASS_DEVICE);
-			class = ccode >> 8;
-			subclass = ccode;
-			iface = pci_config_read8(addr, PCI_CLASS_PROG);
-
-			pci_dev = pci_find_device(class, subclass, iface,
-						  vid, did);
-
-			PCI_DPRINTF("%x:%x.%x - %x:%x - ", bus, devnum, fn,
-					vid, did);
-
-			htype = pci_config_read8(addr, PCI_HEADER_TYPE);
-			if (fn == 0)
-				is_multi = htype & 0x80;
-
-			if (pci_dev == NULL || pci_dev->name == NULL)
-                            snprintf(config.path, sizeof(config.path),
-				     "%s/pci%x,%x", *path, vid, did);
-			else
-                            snprintf(config.path, sizeof(config.path),
-				     "%s/%s", *path, pci_dev->name);
-
-			PCI_DPRINTF("%s - ", config.path);
-
-			config.dev = addr & 0x00FFFFFF;
-
-                        if (class == PCI_BASE_CLASS_BRIDGE &&
-                            (subclass == PCI_SUBCLASS_BRIDGE_HOST ||
-                             subclass == PCI_SUBCLASS_BRIDGE_PCI))
-                            REGISTER_NAMED_NODE(ob_pci_bus_node, config.path);
-                        else
-                            REGISTER_NAMED_NODE(ob_pci_simple_node, config.path);
-
-			activate_device(config.path);
-
-			if (htype & PCI_HEADER_TYPE_BRIDGE) {
-				num_bars = 2;
-				rom_bar  = PCI_ROM_ADDRESS1;
-			} else {
-				num_bars = 6;
-				rom_bar  = PCI_ROM_ADDRESS;
-			}
-
-			ob_pci_configure(addr, &config, num_bars, rom_bar,
-                                         mem_base, io_base);
-			ob_pci_add_properties(addr, pci_dev, &config, num_bars);
-
-                        if (class == PCI_BASE_CLASS_BRIDGE &&
-                            (subclass == PCI_SUBCLASS_BRIDGE_HOST ||
-                             subclass == PCI_SUBCLASS_BRIDGE_PCI)) {
-				/* host or bridge */
-				free(*path);
-				*path = strdup(config.path);
-			}
+		    ob_configure_pci_device(path, bus_num, mem_base, io_base,
+		            bus, devnum, fn, &is_multi);
 
 		}
 	}
-	device_end();
+}
+
+static void ob_configure_pci_bridge(pci_addr addr,
+                                    int *bus_num, unsigned long *mem_base,
+                                    unsigned long *io_base,
+                                    int primary_bus, pci_config_t *config)
+{
+    config->primary_bus = primary_bus;
+    pci_config_write8(addr, PCI_PRIMARY_BUS, config->primary_bus);
+
+    config->secondary_bus = *bus_num;
+    pci_config_write8(addr, PCI_SECONDARY_BUS, config->secondary_bus);
+
+    config->subordinate_bus = 0xff;
+    pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus);
+
+    PCI_DPRINTF("scanning new pci bus %u under bridge %s\n",
+            config->secondary_bus, config->path);
+
+    /* make pci bridge parent device, prepare for recursion */
+
+    ob_scan_pci_bus(bus_num, mem_base, io_base,
+                    config->path, config->secondary_bus);
+
+    /* bus scan updates *bus_num to last revealed pci bus number */
+    config->subordinate_bus = *bus_num;
+    pci_config_write8(addr, PCI_SUBORDINATE_BUS, config->subordinate_bus);
+
+    PCI_DPRINTF("bridge %s PCI bus primary=%d secondary=%d subordinate=%d\n",
+            config->path, config->primary_bus, config->secondary_bus,
+            config->subordinate_bus);
+
+    pci_set_bus_range(config);
+}
+
+static void ob_configure_pci_device(const char* parent_path,
+        int *bus_num, unsigned long *mem_base, unsigned long *io_base,
+        int bus, int devnum, int fn, int *p_is_multi)
+{
+    int vid, did;
+    unsigned int htype;
+    pci_addr addr;
+    pci_config_t config = {};
+        const pci_dev_t *pci_dev;
+    uint32_t ccode;
+    uint8_t class, subclass, iface;
+    int num_bars, rom_bar;
+
+    phandle_t phandle = 0;
+    int is_host_bridge = 0;
+
+#ifdef CONFIG_XBOX
+    if (pci_xbox_blacklisted (bus, devnum, fn))
+        return;
+#endif
+    addr = PCI_ADDR(bus, devnum, fn);
+    vid = pci_config_read16(addr, PCI_VENDOR_ID);
+    did = pci_config_read16(addr, PCI_DEVICE_ID);
+
+    if (vid==0xffff || vid==0)
+        return;
+
+    ccode = pci_config_read16(addr, PCI_CLASS_DEVICE);
+    class = ccode >> 8;
+    subclass = ccode;
+
+    iface = pci_config_read8(addr, PCI_CLASS_PROG);
+
+    pci_dev = pci_find_device(class, subclass, iface,
+                  vid, did);
+
+    PCI_DPRINTF("%x:%x.%x - %x:%x - ", bus, devnum, fn,
+            vid, did);
+
+    htype = pci_config_read8(addr, PCI_HEADER_TYPE);
+
+    if (fn == 0) {
+        if (p_is_multi) {
+            *p_is_multi = htype & 0x80;
+        }
+    }
+
+    /* stop adding host bridge accessible from it's primary bus
+       PCI host bridge is to be added by host code
+    */
+    if (class == PCI_BASE_CLASS_BRIDGE &&
+            subclass == PCI_SUBCLASS_BRIDGE_HOST) {
+        is_host_bridge = 1;
+    }
+
+    if (is_host_bridge) {
+        /* reuse device tree node */
+        PCI_DPRINTF("host bridge found - ");
+        snprintf(config.path, sizeof(config.path),
+                "%s", parent_path);
+    } else if (pci_dev == NULL || pci_dev->name == NULL) {
+        snprintf(config.path, sizeof(config.path),
+                "%s/pci%x,%x", parent_path, vid, did);
+    }
+    else {
+        snprintf(config.path, sizeof(config.path),
+                "%s/%s", parent_path, pci_dev->name);
+    }
+
+    PCI_DPRINTF("%s - ", config.path);
+
+    config.dev = addr & 0x00FFFFFF;
+
+    switch (class) {
+    case PCI_BASE_CLASS_BRIDGE:
+        if (subclass != PCI_SUBCLASS_BRIDGE_HOST) {
+            REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle);
+        }
+        break;
+    default:
+        REGISTER_NAMED_NODE_PHANDLE(ob_pci_simple_node, config.path, phandle);
+        break;
+    }
+
+    if (is_host_bridge) {
+        phandle = find_dev(config.path);
+
+        if (get_property(phandle, "vendor-id", NULL)) {
+            PCI_DPRINTF("host bridge already configured\n");
+            return;
+        }
+    }
+
+    activate_dev(phandle);
+
+    if (htype & PCI_HEADER_TYPE_BRIDGE) {
+        num_bars = 2;
+        rom_bar  = PCI_ROM_ADDRESS1;
+    } else {
+        num_bars = 6;
+        rom_bar  = PCI_ROM_ADDRESS;
+    }
+
+    ob_pci_configure(addr, &config, num_bars, rom_bar,
+                     mem_base, io_base);
+
+    ob_pci_add_properties(phandle, addr, pci_dev, &config, num_bars);
+
+    if (!is_host_bridge) {
+        pci_set_reg(phandle, &config, num_bars);
+    }
+
+    /* call device-specific configuration callback */
+    if (pci_dev && pci_dev->config_cb) {
+        //activate_device(config.path);
+        pci_dev->config_cb(&config);
+    }
+
+    /* device is configured so we may move it out of scope */
+    device_end();
+
+    /* scan bus behind bridge device */
+    //if (htype & PCI_HEADER_TYPE_BRIDGE && class == PCI_BASE_CLASS_BRIDGE) {
+    if ( class == PCI_BASE_CLASS_BRIDGE &&
+            ( subclass == PCI_SUBCLASS_BRIDGE_PCI ||
+              subclass == PCI_SUBCLASS_BRIDGE_HOST ) ) {
+
+        if (subclass == PCI_SUBCLASS_BRIDGE_PCI) {
+            /* reserve next pci bus number for this PCI bridge */
+            ++(*bus_num);
+        }
+
+        ob_configure_pci_bridge(addr, bus_num, mem_base, io_base, bus, &config);
+    }
 }
 
 int ob_pci_init(void)
 {
-        int bus;
-        unsigned long mem_base, io_base;
-	char *path;
+    int bus;
+    unsigned long mem_base, io_base;
 
-	PCI_DPRINTF("Initializing PCI devices...\n");
+    pci_config_t config = {}; /* host bridge */
+    phandle_t phandle_host;
 
-	/* brute force bus scan */
+    PCI_DPRINTF("Initializing PCI host bridge...\n");
 
-	/* Find all PCI bridges */
+    activate_device("/");
 
-	mem_base = arch->mem_base;
-        /* I/O ports under 0x400 are used by devices mapped at fixed
-           location. */
-        io_base = arch->io_base + 0x400;
-	path = strdup("");
-	for (bus = 0; bus<0x100; bus++) {
-		ob_scan_pci_bus(bus, &mem_base, &io_base, &path);
-	}
-	free(path);
-	return 0;
+    /* Find all PCI bridges */
+
+    mem_base = arch->mem_base;
+    /* I/O ports under 0x400 are used by devices mapped at fixed
+       location. */
+    io_base = arch->io_base + 0x400;
+
+    bus = 0;
+
+    /* create root node for host PCI bridge */
+
+    /* configure  */
+    snprintf(config.path, sizeof(config.path), "/pci");
+
+    REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle_host);
+
+    pci_host_set_reg(phandle_host);
+
+    /* update device path after changing "reg" property */
+    ob_pci_reload_device_path(phandle_host, &config);
+
+    /* we expect host PCI bridge at pci0:0:0 but this may be machine-specific */
+
+    ob_configure_pci_device(config.path, &bus, &mem_base, &io_base, 0, 0, 0, 0);
+
+    device_end();
+
+    return 0;
 }
diff --git a/drivers/pci.h b/drivers/pci.h
index 3ca71f3..0f6ae1f 100644
--- a/drivers/pci.h
+++ b/drivers/pci.h
@@ -34,7 +34,9 @@
 #define  PCI_HEADER_TYPE_NORMAL 0x00
 #define  PCI_HEADER_TYPE_BRIDGE 0x01
 #define  PCI_HEADER_TYPE_CARDBUS 0x02
-#define PCI_SECONDARY_BUS	0x19
+#define PCI_PRIMARY_BUS     0x18
+#define PCI_SECONDARY_BUS   0x19
+#define PCI_SUBORDINATE_BUS 0x1A
 #define PCI_BASE_ADDR_0		0x10
 #define PCI_BASE_ADDR_1		0x14
 #define PCI_BASE_ADDR_2		0x18
diff --git a/drivers/pci_database.h b/drivers/pci_database.h
index cdb0045..5ddbb20 100644
--- a/drivers/pci_database.h
+++ b/drivers/pci_database.h
@@ -8,6 +8,9 @@ struct pci_config_t {
 	uint32_t sizes[7];
 	int irq_pin;
 	int irq_line;
+	u32 primary_bus;
+	u32 secondary_bus;
+	u32 subordinate_bus;
 };
 
 typedef struct pci_dev_t pci_dev_t;
diff --git a/drivers/vga_vbe.c b/drivers/vga_vbe.c
index b1a95df..2c229b4 100644
--- a/drivers/vga_vbe.c
+++ b/drivers/vga_vbe.c
@@ -155,7 +155,11 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size,
 
 	vga_vbe_set_mode(width, height, depth);
 
-	ph = find_dev(path);
+#if 0
+    ph = find_dev(path);
+#else
+    ph = get_cur_dev();
+#endif
 
 	set_int_property(ph, "width", width);
 	set_int_property(ph, "height", height);
diff --git a/include/libopenbios/bindings.h b/include/libopenbios/bindings.h
index 4c58159..de9c775 100644
--- a/include/libopenbios/bindings.h
+++ b/include/libopenbios/bindings.h
@@ -112,6 +112,12 @@ typedef struct {
 		path, name##_m, sizeof(name##_m)/sizeof(method_t)); \
 	} while(0)
 
+#define REGISTER_NAMED_NODE_PHANDLE( name, path, phandle )   do { \
+    phandle = \
+    bind_new_node( name##_flags_, name##_size_, \
+        path, name##_m, sizeof(name##_m)/sizeof(method_t)); \
+    } while(0)
+
 #define REGISTER_NODE_METHODS( name, path )   do {			\
 	const char *paths[1];						\
 									\
@@ -140,7 +146,7 @@ static const method_t name##_m[]
 extern void 	bind_node( int flags, int size, const char * const *paths, int npaths,
 			   const method_t *methods, int nmethods );
 
-extern void 	bind_new_node( int flags, int size, const char *name,
+extern phandle_t	bind_new_node( int flags, int size, const char *name,
 			   const method_t *methods, int nmethods );
 
 #define INSTALL_OPEN	1	/* install trivial open and close methods */
diff --git a/libopenbios/bindings.c b/libopenbios/bindings.c
index 5067455..f6bc8de 100644
--- a/libopenbios/bindings.c
+++ b/libopenbios/bindings.c
@@ -507,16 +507,18 @@ bind_node( int flags, int size, const char * const *paths, int npaths,
 	activate_dev( save_ph );
 }
 
-void
+phandle_t
 bind_new_node( int flags, int size, const char *name,
 	   const method_t *methods, int nmet )
 {
 	phandle_t save_ph = get_cur_dev();
-
+	phandle_t new_ph;
 	/* create node */
 	push_str( name );
 	fword("create-node");
 	add_methods( flags, size, methods, nmet );
+    new_ph = get_cur_dev();
 
 	activate_dev( save_ph );
+	return new_ph;
 }




More information about the OpenBIOS mailing list