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

Blue Swirl blauwirbel at gmail.com
Wed May 26 21:02:56 CEST 2010


On Tue, May 25, 2010 at 12:38 PM, Igor V. Kovalenko
<igor.v.kovalenko at gmail.com> wrote:
> 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

Unfortunately this breaks the PPC Mac99 machine.

To test, simply run 'qemu-system-ppc -M mac99', the screen remains
black. 5/10 still works.

>
> 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;
>  }
>
>
> --
> OpenBIOS                 http://openbios.org/
> Mailinglist:  http://lists.openbios.org/mailman/listinfo
> Free your System - May the Forth be with you
>



More information about the OpenBIOS mailing list