From 83b991afff40e12a8b6756af06a472842edb1a66 Mon Sep 17 00:00:00 2001 From: Eric Biederman Date: Sat, 11 Oct 2003 06:20:25 +0000 Subject: - O2, enums, and switch statements work in romcc - Support for compiling romcc on non x86 platforms - new romc options -msse and -mmmx for specifying extra registers to use - Bug fixes to device the device disable/enable framework and an amd8111 implementation - Move the link specification to the chip specification instead of the path - Allow specifying devices with internal bridges. - Initial via epia support - Opteron errata fixes git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1200 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/devices/chip.c | 30 ++++++++++++++++++++------ src/devices/device.c | 32 ++++++++++++++------------- src/devices/device_util.c | 15 ++++++++++--- src/devices/hypertransport.c | 16 +++++++++++--- src/devices/pci_device.c | 51 +++++++++++++++++++++----------------------- src/devices/root_device.c | 2 ++ 6 files changed, 92 insertions(+), 54 deletions(-) (limited to 'src/devices') diff --git a/src/devices/chip.c b/src/devices/chip.c index b7eace38f0..c9e1ac5643 100644 --- a/src/devices/chip.c +++ b/src/devices/chip.c @@ -46,16 +46,33 @@ void chip_enumerate(struct chip *chip) int identical_paths; identical_paths = (i > 0) && - (path_eq(&chip->path[i - 1].path, &chip->path[i].path)) && - (chip->path[i - 1].channel == chip->path[i].channel); + (path_eq(&chip->path[i - 1].path, &chip->path[i].path)); if (!identical_paths) { + struct bus *parent; + int bus; link = 0; dev = 0; + parent = chip->bus; switch(chip->path[i].path.type) { case DEVICE_PATH_NONE: break; + case DEVICE_PATH_PCI: + bus = chip->path[i].path.u.pci.bus; + if (bus != 0) { + device_t dev; + int i = 1; + dev = chip->dev; + while(dev && (i != bus)) { + dev = dev->next; + i++; + } + if ((i == bus) && dev) { + parent = &dev->link[0]; + } + } + /* Fall through */ default: - dev = alloc_dev(chip->bus, &chip->path[i].path); + dev = alloc_dev(parent, &chip->path[i].path); break; } } @@ -63,12 +80,13 @@ void chip_enumerate(struct chip *chip) link += 1; } if (dev) { - printk_spew("path %s %s\n", dev_path(dev), identical_paths?"identical":""); + printk_spew("path (%p) %s %s", dev, dev_path(dev), identical_paths?"identical":""); + printk_spew(" parent: (%p) %s\n",dev->bus->dev, dev_path(dev->bus->dev)); + dev->chip = chip; dev->enable = chip->path[i].enable; dev->links = link + 1; for(child = chip->children; child; child = child->next) { - if (!child->bus && - child->path[0].channel == i) { + if (!child->bus && child->link == i) { child->bus = &dev->link[link]; } } diff --git a/src/devices/device.c b/src/devices/device.c index 289c0766ea..c6dd5fc4ad 100644 --- a/src/devices/device.c +++ b/src/devices/device.c @@ -115,6 +115,9 @@ static void read_resources(struct bus *bus) dev_path(curdev)); continue; } + if (!curdev->enable) { + continue; + } curdev->ops->read_resources(curdev); /* Read in subtractive resources behind the current device */ links = 0; @@ -251,16 +254,12 @@ void compute_allocate_resource( min_align = 0; base = bridge->base; - printk_spew("%s: bus %p, bridge %p, type_mask 0x%x, type 0x%x\n", - __FUNCTION__, - bus, bridge, type_mask, type); - printk_spew("vendor 0x%x device 0x%x class 0x%x \n", - bus->dev->vendor, bus->dev->device, bus->dev->class); - printk_spew("%s compute_allocate_%s: base: %08lx size: %08lx align: %d gran: %d\n", - dev_path(bus->dev), - (bridge->flags & IORESOURCE_IO)? "io": - (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem", - base, bridge->size, bridge->align, bridge->gran); + printk_spew("%s compute_allocate_%s: base: %08lx size: %08lx align: %d gran: %d\n", + dev_path(bus->dev), + (bridge->flags & IORESOURCE_IO)? "io": + (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem", + base, bridge->size, bridge->align, bridge->gran); + /* We want different minimum alignments for different kinds of * resources. These minimums are not device type specific @@ -406,6 +405,9 @@ void assign_resources(struct bus *bus) dev_path(curdev)); continue; } + if (!curdev->enable) { + continue; + } curdev->ops->set_resources(curdev); } printk_debug("ASSIGNED RESOURCES, bus %d\n", bus->secondary); @@ -422,6 +424,9 @@ void enable_resources(struct device *dev) dev_path(dev)); return; } + if (!dev->enable) { + return; + } dev->ops->enable_resources(dev); } @@ -444,13 +449,12 @@ void dev_enumerate(void) void dev_configure(void) { struct device *root = &dev_root; - printk_info("%s: Allocating resources...", __FUNCTION__); + printk_info("Allocating resources..."); printk_debug("\n"); root->ops->read_resources(root); - printk_spew("%s: done reading resources...\n", __FUNCTION__); /* Make certain the io devices are allocated somewhere * safe. */ @@ -465,10 +469,8 @@ void dev_configure(void) root->resource[1].flags |= IORESOURCE_SET; // now just set things into registers ... we hope ... root->ops->set_resources(root); - printk_spew("%s: done setting resources...\n", __FUNCTION__); allocate_vga_resource(); - printk_spew("%s: done vga resources...\n", __FUNCTION__); printk_info("done.\n"); } @@ -494,7 +496,7 @@ void dev_initialize(void) printk_info("Initializing devices...\n"); for (dev = all_devices; dev; dev = dev->next) { - if (dev->ops && dev->ops->init) { + if (dev->enable && dev->ops && dev->ops->init) { printk_debug("%s init\n", dev_path(dev)); dev->ops->init(dev); } diff --git a/src/devices/device_util.c b/src/devices/device_util.c index 384a3be8e0..6652c86ea0 100644 --- a/src/devices/device_util.c +++ b/src/devices/device_util.c @@ -30,15 +30,17 @@ device_t alloc_find_dev(struct bus *parent, struct device_path *path) */ struct device *dev_find_slot(unsigned int bus, unsigned int devfn) { - struct device *dev; + struct device *dev, *result; + result = 0; for (dev = all_devices; dev; dev = dev->next) { if ((dev->bus->secondary == bus) && (dev->path.u.pci.devfn == devfn)) { + result = dev; break; } } - return dev; + return result; } /** Find a device of a given vendor and type @@ -88,6 +90,9 @@ const char *dev_path(device_t dev) } else { switch(dev->path.type) { + case DEVICE_PATH_ROOT: + memcpy(buffer, "Root Device", 12); + break; case DEVICE_PATH_PCI: sprintf(buffer, "PCI: %02x:%02x.%01x", dev->bus->secondary, @@ -116,8 +121,12 @@ int path_eq(struct device_path *path1, struct device_path *path2) switch(path1->type) { case DEVICE_PATH_NONE: break; + case DEVICE_PATH_ROOT: + equal = 1; + break; case DEVICE_PATH_PCI: - equal = path1->u.pci.devfn == path2->u.pci.devfn; + equal = (path1->u.pci.bus == path2->u.pci.bus) && + (path1->u.pci.devfn == path2->u.pci.devfn); break; case DEVICE_PATH_PNP: equal = (path1->u.pnp.port == path2->u.pnp.port) && diff --git a/src/devices/hypertransport.c b/src/devices/hypertransport.c index 0c1dc3959a..326f343662 100644 --- a/src/devices/hypertransport.c +++ b/src/devices/hypertransport.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -243,11 +244,19 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max) /* Add this device to the pci bus chain */ *chain_last = dev; /* Run the magice enable/disable sequence for the device */ - if (dev->ops && dev->ops->enable) { - dev->ops->enable(dev); + if (dev->chip && dev->chip->control && dev->chip->control->enable_dev) { + dev->chip->control->enable_dev(dev); } /* Now read the vendor and device id */ id = pci_read_config32(dev, PCI_VENDOR_ID); + + /* If the chain is fully enumerated quit */ + if (id == 0xffffffff || id == 0x00000000 || + id == 0x0000ffff || id == 0xffff0000) { + printk_err("Missing static device: %s\n", + dev_path(dev)); + break; + } } /* Update the device chain tail */ for(func = dev; func; func = func->sibling) { @@ -268,7 +277,8 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max) /* Find the hypertransport link capability */ pos = ht_lookup_slave_capability(dev); if (pos == 0) { - printk_err("Hypertransport link capability not found"); + printk_err("%s Hypertransport link capability not found", + dev_path(dev)); break; } diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c index 806734c18b..031d855fbf 100644 --- a/src/devices/pci_device.c +++ b/src/devices/pci_device.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -175,7 +176,6 @@ static void pci_bridge_read_bases(struct device *dev) /* FIXME handle bridges without some of the optional resources */ - printk_spew("%s: path %s\n", __FUNCTION__, dev_path(dev)); /* Initialize the io space constraints on the current bus */ dev->resource[reg].base = 0; dev->resource[reg].size = 0; @@ -215,7 +215,6 @@ static void pci_bridge_read_bases(struct device *dev) reg++; dev->resources = reg; - printk_spew("DONE %s: path %s\n", __FUNCTION__, dev_path(dev)); } @@ -455,11 +454,13 @@ static void set_pci_ops(struct device *dev) break; default: bad: - printk_err("%s [%04x/%04x/%06x] has unknown header " - "type %02x, ignoring.\n", - dev_path(dev), - dev->vendor, dev->device, - dev->class >> 8, dev->hdr_type); + if (dev->enable) { + printk_err("%s [%04x/%04x/%06x] has unknown header " + "type %02x, ignoring.\n", + dev_path(dev), + dev->vendor, dev->device, + dev->class >> 8, dev->hdr_type); + } } return; } @@ -556,17 +557,16 @@ unsigned int pci_scan_bus(struct bus *bus, } else { /* Run the magic enable/disable sequence for the device */ - if (dev->ops && dev->ops->enable) { - dev->ops->enable(dev); + if (dev->chip && dev->chip->control && dev->chip->control->enable_dev) { + dev->chip->control->enable_dev(dev); } /* Now read the vendor and device id */ id = pci_read_config32(dev, PCI_VENDOR_ID); } - /* Read the rest of the pci configuration information */ hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); class = pci_read_config32(dev, PCI_CLASS_REVISION); - + /* Store the interesting information in the device structure */ dev->vendor = id & 0xffff; dev->device = (id >> 16) & 0xffff; @@ -576,20 +576,19 @@ unsigned int pci_scan_bus(struct bus *bus, /* Look at the vendor and device id, or at least the * header type and class and figure out which set of configuration - * methods to use. + * methods to use. Unless we already have some pci ops. */ - if (!dev->ops) { - set_pci_ops(dev); - /* Error if we don't have some pci operations for it */ - if (!dev->ops) { - printk_err("%s No device operations\n", - dev_path(dev)); - continue; - } - /* Now run the magic enable/disable sequence for the device */ - if (dev->ops && dev->ops->enable) { - dev->ops->enable(dev); - } + set_pci_ops(dev); + /* Error if we don't have some pci operations for it */ + if (dev->enable && !dev->ops) { + printk_err("%s No device operations\n", + dev_path(dev)); + continue; + } + + /* Now run the magic enable/disable sequence for the device */ + if (dev->ops && dev->ops->enable) { + dev->ops->enable(dev); } printk_debug("%s [%04x/%04x] %s\n", @@ -632,8 +631,7 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max) struct bus *bus; uint32_t buses; uint16_t cr; - - printk_spew("%s: dev %p, max %d\n", __FUNCTION__, dev, max); + bus = &dev->link[0]; dev->links = 1; @@ -707,7 +705,6 @@ static void pci_level_irq(unsigned char intNum) } } - /* This function assigns IRQs for all functions contained within the indicated device address. If the device does not exist or does diff --git a/src/devices/root_device.c b/src/devices/root_device.c index ae02277363..4a076a1bb3 100644 --- a/src/devices/root_device.c +++ b/src/devices/root_device.c @@ -123,6 +123,8 @@ struct device_operations default_dev_ops_root = { struct device dev_root = { .ops = &default_dev_ops_root, .bus = &dev_root.link[0], + .path = { .type = DEVICE_PATH_ROOT }, + .enable = 1, .links = 1, .link = { [0] = { -- cgit v1.2.3