X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=coreboot.git;a=blobdiff_plain;f=src%2Fdevices%2Fdevice_util.c;h=5225938e192035ff385f7fda4edf65e2d6eda02e;hp=c5a2f6406fa076130af4edafb1a7cae4faa58845;hb=dc8448fd8be4768ef9d5f9b8cbcf28db0a2029be;hpb=0867062412dd4bfe5a556e5f3fd85ba5b682d79b diff --git a/src/devices/device_util.c b/src/devices/device_util.c index c5a2f6406..5225938e1 100644 --- a/src/devices/device_util.c +++ b/src/devices/device_util.c @@ -30,47 +30,45 @@ #include /** - * @brief See if a device structure exists for path + * See if a device structure exists for path. * - * @param bus The bus to find the device on - * @param path The relative path from the bus to the appropriate device - * @return pointer to a device structure for the device on bus at path - * or 0/NULL if no device is found + * @param parent The bus to find the device on. + * @param path The relative path from the bus to the appropriate device. + * @return Pointer to a device structure for the device on bus at path + * or 0/NULL if no device is found. */ device_t find_dev_path(struct bus *parent, struct device_path *path) { device_t child; - for(child = parent->children; child; child = child->sibling) { - if (path_eq(path, &child->path)) { + for (child = parent->children; child; child = child->sibling) { + if (path_eq(path, &child->path)) break; - } } return child; } /** - * @brief See if a device structure already exists and if not allocate it + * See if a device structure already exists and if not allocate it. * - * @param bus The bus to find the device on - * @param path The relative path from the bus to the appropriate device - * @return pointer to a device structure for the device on bus at path + * @param parent The bus to find the device on. + * @param path The relative path from the bus to the appropriate device. + * @return Pointer to a device structure for the device on bus at path. */ device_t alloc_find_dev(struct bus *parent, struct device_path *path) { device_t child; child = find_dev_path(parent, path); - if (!child) { + if (!child) child = alloc_dev(parent, path); - } return child; } /** - * @brief Given a PCI bus and a devfn number, find the device structure + * Given a PCI bus and a devfn number, find the device structure. * - * @param bus The bus number - * @param devfn a device/function number - * @return pointer to the device structure + * @param bus The bus number. + * @param devfn A device/function number. + * @return Pointer to the device structure (if found), 0 otherwise. */ struct device *dev_find_slot(unsigned int bus, unsigned int devfn) { @@ -79,8 +77,8 @@ struct device *dev_find_slot(unsigned int bus, unsigned int devfn) result = 0; for (dev = all_devices; dev; dev = dev->next) { if ((dev->path.type == DEVICE_PATH_PCI) && - (dev->bus->secondary == bus) && - (dev->path.pci.devfn == devfn)) { + (dev->bus->secondary == bus) && + (dev->path.pci.devfn == devfn)) { result = dev; break; } @@ -89,54 +87,79 @@ struct device *dev_find_slot(unsigned int bus, unsigned int devfn) } /** - * @brief Given a smbus bus and a device number, find the device structure + * Given an SMBus bus and a device number, find the device structure. * - * @param bus The bus number - * @param addr a device number - * @return pointer to the device structure + * @param bus The bus number. + * @param addr A device number. + * @return Pointer to the device structure (if found), 0 otherwise. */ struct device *dev_find_slot_on_smbus(unsigned int bus, unsigned int addr) { - struct device *dev, *result; - - result = 0; - for (dev = all_devices; dev; dev = dev->next) { - if ((dev->path.type == DEVICE_PATH_I2C) && - (dev->bus->secondary == bus) && - (dev->path.i2c.device == addr)) { - result = dev; - break; - } - } - return result; -} - -/** Find a device of a given vendor and type - * @param vendor Vendor ID (e.g. 0x8086 for Intel) - * @param device Device ID - * @param from Pointer to the device structure, used as a starting point - * in the linked list of all_devices, which can be 0 to start at the - * head of the list (i.e. all_devices) - * @return Pointer to the device struct + struct device *dev, *result; + + result = 0; + for (dev = all_devices; dev; dev = dev->next) { + if ((dev->path.type == DEVICE_PATH_I2C) && + (dev->bus->secondary == bus) && + (dev->path.i2c.device == addr)) { + result = dev; + break; + } + } + return result; +} + +/** + * Given a Local APIC ID, find the device structure. + * + * @param apic_id The Local APIC ID number. + * @return Pointer to the device structure (if found), 0 otherwise. + */ +device_t dev_find_lapic(unsigned apic_id) +{ + device_t dev, result = NULL; + + for (dev = all_devices; dev; dev = dev->next) { + if (dev->path.type == DEVICE_PATH_APIC && + dev->path.apic.apic_id == apic_id) { + result = dev; + break; + } + } + return result; +} + +/** + * Find a device of a given vendor and type. + * + * @param vendor A PCI vendor ID (e.g. 0x8086 for Intel). + * @param device A PCI device ID. + * @param from Pointer to the device structure, used as a starting point in + * the linked list of all_devices, which can be 0 to start at the + * head of the list (i.e. all_devices). + * @return Pointer to the device struct. */ -struct device *dev_find_device(unsigned int vendor, unsigned int device, struct device *from) +struct device *dev_find_device(u16 vendor, u16 device, struct device *from) { if (!from) from = all_devices; else from = from->next; - while (from && (from->vendor != vendor || from->device != device)) { + + while (from && (from->vendor != vendor || from->device != device)) from = from->next; - } + return from; } -/** Find a device of a given class - * @param class Class of the device - * @param from Pointer to the device structure, used as a starting point - * in the linked list of all_devices, which can be 0 to start at the - * head of the list (i.e. all_devices) - * @return Pointer to the device struct +/** + * Find a device of a given class. + * + * @param class Class of the device. + * @param from Pointer to the device structure, used as a starting point in + * the linked list of all_devices, which can be 0 to start at the + * head of the list (i.e. all_devices). + * @return Pointer to the device struct. */ struct device *dev_find_class(unsigned int class, struct device *from) { @@ -144,20 +167,25 @@ struct device *dev_find_class(unsigned int class, struct device *from) from = all_devices; else from = from->next; + while (from && (from->class & 0xffffff00) != class) from = from->next; + return from; } - +/* + * Warning: This function uses a static buffer. Don't call it more than once + * from the same print statement! + */ const char *dev_path(device_t dev) { static char buffer[DEVICE_PATH_MAX]; + buffer[0] = '\0'; if (!dev) { memcpy(buffer, "", 7); - } - else { + } else { switch(dev->path.type) { case DEVICE_PATH_ROOT: memcpy(buffer, "Root Device", 12); @@ -165,12 +193,15 @@ const char *dev_path(device_t dev) case DEVICE_PATH_PCI: #if CONFIG_PCI_BUS_SEGN_BITS sprintf(buffer, "PCI: %04x:%02x:%02x.%01x", - dev->bus->secondary>>8, dev->bus->secondary & 0xff, - PCI_SLOT(dev->path.pci.devfn), PCI_FUNC(dev->path.pci.devfn)); + dev->bus->secondary >> 8, + dev->bus->secondary & 0xff, + PCI_SLOT(dev->path.pci.devfn), + PCI_FUNC(dev->path.pci.devfn)); #else sprintf(buffer, "PCI: %02x:%02x.%01x", - dev->bus->secondary, - PCI_SLOT(dev->path.pci.devfn), PCI_FUNC(dev->path.pci.devfn)); + dev->bus->secondary, + PCI_SLOT(dev->path.pci.devfn), + PCI_FUNC(dev->path.pci.devfn)); #endif break; case DEVICE_PATH_PNP: @@ -201,7 +232,8 @@ const char *dev_path(device_t dev) sprintf(buffer, "CPU_BUS: %02x", dev->path.cpu_bus.id); break; default: - printk_err("Unknown device path type: %d\n", dev->path.type); + printk(BIOS_ERR, "Unknown device path type: %d\n", + dev->path.type); break; } } @@ -211,124 +243,179 @@ const char *dev_path(device_t dev) const char *bus_path(struct bus *bus) { static char buffer[BUS_PATH_MAX]; - sprintf(buffer, "%s,%d", - dev_path(bus->dev), bus->link); + sprintf(buffer, "%s,%d", dev_path(bus->dev), bus->link_num); return buffer; } int path_eq(struct device_path *path1, struct device_path *path2) { int equal = 0; - if (path1->type == path2->type) { - switch(path1->type) { - case DEVICE_PATH_NONE: - break; - case DEVICE_PATH_ROOT: - equal = 1; - break; - case DEVICE_PATH_PCI: - equal = (path1->pci.devfn == path2->pci.devfn); - break; - case DEVICE_PATH_PNP: - equal = (path1->pnp.port == path2->pnp.port) && - (path1->pnp.device == path2->pnp.device); - break; - case DEVICE_PATH_I2C: - equal = (path1->i2c.device == path2->i2c.device); - break; - case DEVICE_PATH_APIC: - equal = (path1->apic.apic_id == path2->apic.apic_id); - break; - case DEVICE_PATH_PCI_DOMAIN: - equal = (path1->pci_domain.domain == path2->pci_domain.domain); - break; - case DEVICE_PATH_APIC_CLUSTER: - equal = (path1->apic_cluster.cluster == path2->apic_cluster.cluster); - break; - case DEVICE_PATH_CPU: - equal = (path1->cpu.id == path2->cpu.id); - break; - case DEVICE_PATH_CPU_BUS: - equal = (path1->cpu_bus.id == path2->cpu_bus.id); - break; - default: - printk_err("Uknown device type: %d\n", path1->type); - break; - } + + if (path1->type != path2->type) + return 0; + + switch (path1->type) { + case DEVICE_PATH_NONE: + break; + case DEVICE_PATH_ROOT: + equal = 1; + break; + case DEVICE_PATH_PCI: + equal = (path1->pci.devfn == path2->pci.devfn); + break; + case DEVICE_PATH_PNP: + equal = (path1->pnp.port == path2->pnp.port) && + (path1->pnp.device == path2->pnp.device); + break; + case DEVICE_PATH_I2C: + equal = (path1->i2c.device == path2->i2c.device); + break; + case DEVICE_PATH_APIC: + equal = (path1->apic.apic_id == path2->apic.apic_id); + break; + case DEVICE_PATH_PCI_DOMAIN: + equal = (path1->pci_domain.domain == path2->pci_domain.domain); + break; + case DEVICE_PATH_APIC_CLUSTER: + equal = (path1->apic_cluster.cluster + == path2->apic_cluster.cluster); + break; + case DEVICE_PATH_CPU: + equal = (path1->cpu.id == path2->cpu.id); + break; + case DEVICE_PATH_CPU_BUS: + equal = (path1->cpu_bus.id == path2->cpu_bus.id); + break; + default: + printk(BIOS_ERR, "Uknown device type: %d\n", path1->type); + break; } + return equal; } +/** + * Allocate 64 more resources to the free list. + * + * @return TODO. + */ +static int allocate_more_resources(void) +{ + int i; + struct resource *new_res_list; + + new_res_list = malloc(64 * sizeof(*new_res_list)); + + if (new_res_list == NULL) + return 0; + + memset(new_res_list, 0, 64 * sizeof(*new_res_list)); + + for (i = 0; i < 64 - 1; i++) + new_res_list[i].next = &new_res_list[i+1]; + + free_resources = new_res_list; + return 1; +} + +/** + * Remove resource res from the device's list and add it to the free list. + * + * @param dev TODO + * @param res TODO + * @param prev TODO + * @return TODO. + */ +static void free_resource(device_t dev, struct resource *res, + struct resource *prev) +{ + if (prev) + prev->next = res->next; + else + dev->resource_list = res->next; + + res->next = free_resources; + free_resources = res; +} + /** * See if we have unused but allocated resource structures. + * * If so remove the allocation. - * @param dev The device to find the resource on + * + * @param dev The device to find the resource on. */ void compact_resources(device_t dev) { - struct resource *resource; - int i; + struct resource *res, *next, *prev = NULL; + /* Move all of the free resources to the end */ - for(i = 0; i < dev->resources;) { - resource = &dev->resource[i]; - if (!resource->flags) { - memmove(resource, resource + 1, (dev->resources - i) * - sizeof(*resource)); - dev->resources -= 1; - memset(&dev->resource[dev->resources], 0, sizeof(*resource)); - } else { - i++; - } + for (res = dev->resource_list; res; res = next) { + next = res->next; + if (!res->flags) + free_resource(dev, res, prev); + else + prev = res; } } - /** - * See if a resource structure already exists for a given index - * @param dev The device to find the resource on - * @param index The index of the resource on the device. - * @return the resource if it already exists + * See if a resource structure already exists for a given index. + * + * @param dev The device to find the resource on. + * @param index The index of the resource on the device. + * @return The resource, if it already exists. */ struct resource *probe_resource(device_t dev, unsigned index) { - struct resource *resource; - int i; + struct resource *res; + /* See if there is a resource with the appropriate index */ - resource = 0; - for(i = 0; i < dev->resources; i++) { - if (dev->resource[i].index == index) { - resource = &dev->resource[i]; + for (res = dev->resource_list; res; res = res->next) { + if (res->index == index) break; - } } - return resource; + + return res; } /** - * See if a resource structure already exists for a given index and if - * not allocate one. Then initialize the initialize the resource - * to default values. - * @param dev The device to find the resource on - * @param index The index of the resource on the device. + * See if a resource structure already exists for a given index and if not + * allocate one. + * + * Then initialize the initialize the resource to default values. + * + * @param dev The device to find the resource on. + * @param index The index of the resource on the device. + * @return TODO. */ struct resource *new_resource(device_t dev, unsigned index) { - struct resource *resource; + struct resource *resource, *tail; - /* First move all of the free resources to the end */ + /* First move all of the free resources to the end. */ compact_resources(dev); - /* See if there is a resource with the appropriate index */ + /* See if there is a resource with the appropriate index. */ resource = probe_resource(dev, index); if (!resource) { - if (dev->resources == MAX_RESOURCES) { - die("MAX_RESOURCES exceeded."); - } - resource = &dev->resource[dev->resources]; + if (free_resources == NULL && !allocate_more_resources()) + die("Couldn't allocate more resources."); + + resource = free_resources; + free_resources = free_resources->next; memset(resource, 0, sizeof(*resource)); - dev->resources++; + resource->next = NULL; + tail = dev->resource_list; + if (tail) { + while (tail->next) tail = tail->next; + tail->next = resource; + } else { + dev->resource_list = resource; + } } - /* Initialize the resource values */ + + /* Initialize the resource values. */ if (!(resource->flags & IORESOURCE_FIXED)) { resource->flags = 0; resource->base = 0; @@ -344,29 +431,31 @@ struct resource *new_resource(device_t dev, unsigned index) /** * Return an existing resource structure for a given index. - * @param dev The device to find the resource on - * @param index The index of the resource on the device. + * + * @param dev The device to find the resource on. + * @param index The index of the resource on the device. + * return TODO. */ struct resource *find_resource(device_t dev, unsigned index) { struct resource *resource; - /* See if there is a resource with the appropriate index */ + /* See if there is a resource with the appropriate index. */ resource = probe_resource(dev, index); if (!resource) { - printk_emerg("%s missing resource: %02x\n", - dev_path(dev), index); + printk(BIOS_EMERG, "%s missing resource: %02x\n", + dev_path(dev), index); die(""); } return resource; } - /** - * @brief round a number up to the next multiple of gran - * @param val the starting value - * @param gran granularity we are aligning the number to. - * @returns aligned value + * Round a number up to the next multiple of gran. + * + * @param val The starting value. + * @param gran Granularity we are aligning the number to. + * @return The aligned value. */ static resource_t align_up(resource_t val, unsigned long gran) { @@ -378,10 +467,11 @@ static resource_t align_up(resource_t val, unsigned long gran) } /** - * @brief round a number up to the previous multiple of gran - * @param val the starting value - * @param gran granularity we are aligning the number to. - * @returns aligned value + * Round a number up to the previous multiple of gran. + * + * @param val The starting value. + * @param gran Granularity we are aligning the number to. + * @return The aligned value. */ static resource_t align_down(resource_t val, unsigned long gran) { @@ -392,32 +482,36 @@ static resource_t align_down(resource_t val, unsigned long gran) } /** - * @brief Compute the maximum address that is part of a resource - * @param resource the resource whose limit is desired - * @returns the end + * Compute the maximum address that is part of a resource. + * + * @param resource The resource whose limit is desired. + * @return The end. */ resource_t resource_end(struct resource *resource) { resource_t base, end; - /* get the base address */ + + /* Get the base address. */ base = resource->base; - /* For a non bridge resource granularity and alignment are the same. + /* + * For a non bridge resource granularity and alignment are the same. * For a bridge resource align is the largest needed alignment below - * the bridge. While the granularity is simply how many low bits of the - * address cannot be set. + * the bridge. While the granularity is simply how many low bits of + * the address cannot be set. */ - - /* Get the end (rounded up) */ + + /* Get the end (rounded up). */ end = base + align_up(resource->size, resource->gran) - 1; return end; } /** - * @brief Compute the maximum legal value for resource->base - * @param resource the resource whose maximum is desired - * @returns the maximum + * Compute the maximum legal value for resource->base. + * + * @param resource The resource whose maximum is desired. + * @return The maximum. */ resource_t resource_max(struct resource *resource) { @@ -429,117 +523,132 @@ resource_t resource_max(struct resource *resource) } /** - * @brief return the resource type of a resource - * @param resource the resource type to decode. + * Return the resource type of a resource. + * + * @param resource The resource type to decode. + * @return TODO. */ const char *resource_type(struct resource *resource) { static char buffer[RESOURCE_TYPE_MAX]; sprintf(buffer, "%s%s%s%s", - ((resource->flags & IORESOURCE_READONLY)? "ro": ""), - ((resource->flags & IORESOURCE_PREFETCH)? "pref":""), - ((resource->flags == 0)? "unused": - (resource->flags & IORESOURCE_IO)? "io": - (resource->flags & IORESOURCE_DRQ)? "drq": - (resource->flags & IORESOURCE_IRQ)? "irq": - (resource->flags & IORESOURCE_MEM)? "mem":"??????"), - ((resource->flags & IORESOURCE_PCI64)?"64":"")); + ((resource->flags & IORESOURCE_READONLY) ? "ro" : ""), + ((resource->flags & IORESOURCE_PREFETCH) ? "pref" : ""), + ((resource->flags == 0) ? "unused" : + (resource->flags & IORESOURCE_IO) ? "io" : + (resource->flags & IORESOURCE_DRQ) ? "drq" : + (resource->flags & IORESOURCE_IRQ) ? "irq" : + (resource->flags & IORESOURCE_MEM) ? "mem" : "??????"), + ((resource->flags & IORESOURCE_PCI64) ? "64" : "")); return buffer; } /** - * @brief print the resource that was just stored. - * @param dev the device the stored resorce lives on - * @param resource the resource that was just stored. + * Print the resource that was just stored. + * + * @param dev The device the stored resorce lives on. + * @param resource The resource that was just stored. + * @param comment TODO */ -void report_resource_stored(device_t dev, struct resource *resource, const char *comment) -{ - if (resource->flags & IORESOURCE_STORED) { - char buf[10]; - unsigned long long base, end; - base = resource->base; - end = resource_end(resource); - buf[0] = '\0'; - if (resource->flags & IORESOURCE_PCI_BRIDGE) { +void report_resource_stored(device_t dev, struct resource *resource, + const char *comment) +{ + char buf[10]; + unsigned long long base, end; + + if (!(resource->flags & IORESOURCE_STORED)) + return; + + base = resource->base; + end = resource_end(resource); + buf[0] = '\0'; + + if (resource->flags & IORESOURCE_PCI_BRIDGE) { #if CONFIG_PCI_BUS_SEGN_BITS - sprintf(buf, "bus %04x:%02x ", dev->bus->secondary>>8, dev->link[0].secondary & 0xff); + sprintf(buf, "bus %04x:%02x ", dev->bus->secondary >> 8, + dev->link_list->secondary & 0xff); #else - sprintf(buf, "bus %02x ", dev->link[0].secondary); + sprintf(buf, "bus %02x ", dev->link_list->secondary); #endif - } - printk_debug( - "%s %02lx <- [0x%010Lx - 0x%010Lx] size 0x%08Lx gran 0x%02x %s%s%s\n", - dev_path(dev), - resource->index, - base, end, - resource->size, resource->gran, - buf, - resource_type(resource), - comment); } + printk(BIOS_DEBUG, "%s %02lx <- [0x%010llx - 0x%010llx] size 0x%08llx " + "gran 0x%02x %s%s%s\n", dev_path(dev), resource->index, + base, end, resource->size, resource->gran, buf, + resource_type(resource), comment); } -void search_bus_resources(struct bus *bus, - unsigned long type_mask, unsigned long type, - resource_search_t search, void *gp) +void search_bus_resources(struct bus *bus, unsigned long type_mask, + unsigned long type, resource_search_t search, + void *gp) { struct device *curdev; - for(curdev = bus->children; curdev; curdev = curdev->sibling) { - int i; - /* Ignore disabled devices */ - if (!curdev->have_resources) continue; - for(i = 0; i < curdev->resources; i++) { - struct resource *resource = &curdev->resource[i]; - /* If it isn't the right kind of resource ignore it */ - if ((resource->flags & type_mask) != type) { + + for (curdev = bus->children; curdev; curdev = curdev->sibling) { + struct resource *res; + + /* Ignore disabled devices. */ + if (!curdev->enabled) + continue; + + for (res = curdev->resource_list; res; res = res->next) { + /* If it isn't the right kind of resource ignore it. */ + if ((res->flags & type_mask) != type) continue; - } - /* If it is a subtractive resource recurse */ - if (resource->flags & IORESOURCE_SUBTRACTIVE) { + + /* If it is a subtractive resource recurse. */ + if (res->flags & IORESOURCE_SUBTRACTIVE) { struct bus * subbus; - subbus = &curdev->link[IOINDEX_SUBTRACTIVE_LINK(resource->index)]; - search_bus_resources(subbus, type_mask, type, search, gp); + for (subbus = curdev->link_list; subbus; + subbus = subbus->next) + if (subbus->link_num + == IOINDEX_SUBTRACTIVE_LINK(res->index)) + break; + if (!subbus) /* Why can subbus be NULL? */ + break; + search_bus_resources(subbus, type_mask, type, + search, gp); continue; } - search(gp, curdev, resource); + search(gp, curdev, res); } } } -void search_global_resources( - unsigned long type_mask, unsigned long type, - resource_search_t search, void *gp) +void search_global_resources(unsigned long type_mask, unsigned long type, + resource_search_t search, void *gp) { struct device *curdev; - for(curdev = all_devices; curdev; curdev = curdev->next) { - int i; - /* Ignore disabled devices */ - if (!curdev->have_resources) continue; - for(i = 0; i < curdev->resources; i++) { - struct resource *resource = &curdev->resource[i]; - /* If it isn't the right kind of resource ignore it */ - if ((resource->flags & type_mask) != type) { + + for (curdev = all_devices; curdev; curdev = curdev->next) { + struct resource *res; + + /* Ignore disabled devices. */ + if (!curdev->enabled) + continue; + + for (res = curdev->resource_list; res; res = res->next) { + /* If it isn't the right kind of resource ignore it. */ + if ((res->flags & type_mask) != type) continue; - } - /* If it is a subtractive resource ignore it */ - if (resource->flags & IORESOURCE_SUBTRACTIVE) { + + /* If it is a subtractive resource ignore it. */ + if (res->flags & IORESOURCE_SUBTRACTIVE) continue; - } - search(gp, curdev, resource); + + search(gp, curdev, res); } } } void dev_set_enabled(device_t dev, int enable) { - if (dev->enabled == enable) { + if (dev->enabled == enable) return; - } + dev->enabled = enable; if (dev->ops && dev->ops->enable) { dev->ops->enable(dev); - } - else if (dev->chip_ops && dev->chip_ops->enable_dev) { + } else if (dev->chip_ops && dev->chip_ops->enable_dev) { dev->chip_ops->enable_dev(dev); } } @@ -547,47 +656,48 @@ void dev_set_enabled(device_t dev, int enable) void disable_children(struct bus *bus) { device_t child; - for(child = bus->children; child; child = child->sibling) { - int link; - for(link = 0; link < child->links; link++) { - disable_children(&child->link[link]); - } + + for (child = bus->children; child; child = child->sibling) { + struct bus *link; + for (link = child->link_list; link; link = link->next) + disable_children(link); dev_set_enabled(child, 0); } } -void resource_tree(struct device *root, int debug_level, int depth) +static void resource_tree(struct device *root, int debug_level, int depth) { - int i = 0, link = 0; + int i = 0; struct device *child; + struct bus *link; + struct resource *res; char indent[30]; /* If your tree has more levels, it's wrong. */ for (i = 0; i < depth + 1 && i < 29; i++) indent[i] = ' '; indent[i] = '\0'; - do_printk(BIOS_DEBUG, "%s%s links %x child on link 0 %s\n", - indent, dev_path(root), root->links, - root->link[0].children ? dev_path(root->link[0].children) : - "NULL"); - for (i = 0; i < root->resources; i++) { - do_printk(BIOS_DEBUG, - "%s%s resource base %llx size %llx align %d gran %d limit %llx flags %lx index %lx\n", - indent, dev_path(root), root->resource[i].base, - root->resource[i].size, root->resource[i].align, - root->resource[i].gran, root->resource[i].limit, - root->resource[i].flags, root->resource[i].index); + do_printk(BIOS_DEBUG, "%s%s", indent, dev_path(root)); + if (root->link_list && root->link_list->children) + do_printk(BIOS_DEBUG, " child on link 0 %s", + dev_path(root->link_list->children)); + do_printk(BIOS_DEBUG, "\n"); + + for (res = root->resource_list; res; res = res->next) { + do_printk(debug_level, "%s%s resource base %llx size %llx " + "align %d gran %d limit %llx flags %lx index %lx\n", + indent, dev_path(root), res->base, res->size, + res->align, res->gran, res->limit, res->flags, + res->index); } - for (link = 0; link < root->links; link++) { - for (child = root->link[link].children; child; - child = child->sibling) + for (link = root->link_list; link; link = link->next) { + for (child = link->children; child; child = child->sibling) resource_tree(child, debug_level, depth + 1); } } -void print_resource_tree(struct device * root, int debug_level, - const char *msg) +void print_resource_tree(struct device *root, int debug_level, const char *msg) { /* Bail if root is null. */ if (!root) { @@ -597,8 +707,9 @@ void print_resource_tree(struct device * root, int debug_level, /* Bail if not printing to screen. */ if (!do_printk(debug_level, "Show resources in subtree (%s)...%s\n", - dev_path(root), msg)) + dev_path(root), msg)) return; + resource_tree(root, debug_level, 0); } @@ -607,13 +718,17 @@ void show_devs_tree(struct device *dev, int debug_level, int depth, int linknum) char depth_str[20] = ""; int i; struct device *sibling; + struct bus *link; + for (i = 0; i < depth; i++) depth_str[i] = ' '; depth_str[i] = '\0'; - do_printk(debug_level, "%s%s: enabled %d, %d resources\n", - depth_str, dev_path(dev), dev->enabled, dev->resources); - for (i = 0; i < dev->links; i++) { - for (sibling = dev->link[i].children; sibling; + + do_printk(debug_level, "%s%s: enabled %d\n", + depth_str, dev_path(dev), dev->enabled); + + for (link = dev->link_list; link; link = link->next) { + for (sibling = link->children; sibling; sibling = sibling->sibling) show_devs_tree(sibling, debug_level, depth + 1, i); } @@ -631,7 +746,7 @@ void show_devs_subtree(struct device *root, int debug_level, const char *msg) { /* Bail if not printing to screen. */ if (!do_printk(debug_level, "Show all devs in subtree %s...%s\n", - dev_path(root), msg)) + dev_path(root), msg)) return; do_printk(debug_level, "%s\n", msg); show_devs_tree(root, debug_level, 0, -1); @@ -645,10 +760,8 @@ void show_all_devs(int debug_level, const char *msg) if (!do_printk(debug_level, "Show all devs...%s\n", msg)) return; for (dev = all_devices; dev; dev = dev->next) { - do_printk(debug_level, - "%s: enabled %d, %d resources\n", - dev_path(dev), dev->enabled, - dev->resources); + do_printk(debug_level, "%s: enabled %d\n", + dev_path(dev), dev->enabled); } } @@ -660,6 +773,7 @@ void show_one_resource(int debug_level, struct device *dev, base = resource->base; end = resource_end(resource); buf[0] = '\0'; + /* if (resource->flags & IORESOURCE_BRIDGE) { #if CONFIG_PCI_BUS_SEGN_BITS @@ -670,28 +784,87 @@ void show_one_resource(int debug_level, struct device *dev, #endif } */ - do_printk(debug_level, "%s %02lx <- [0x%010llx - 0x%010llx] " - "size 0x%08Lx gran 0x%02x %s%s%s\n", - dev_path(dev), resource->index, base, end, - resource->size, resource->gran, buf, - resource_type(resource), comment); + do_printk(debug_level, "%s %02lx <- [0x%010llx - 0x%010llx] " + "size 0x%08llx gran 0x%02x %s%s%s\n", dev_path(dev), + resource->index, base, end, resource->size, resource->gran, + buf, resource_type(resource), comment); } void show_all_devs_resources(int debug_level, const char* msg) { struct device *dev; - if(!do_printk(debug_level, "Show all devs with resources...%s\n", msg)) + if (!do_printk(debug_level, "Show all devs with resources...%s\n", msg)) return; for (dev = all_devices; dev; dev = dev->next) { - int i; - do_printk(debug_level, - "%s: enabled %d, %d resources\n", - dev_path(dev), dev->enabled, - dev->resources); - for (i = 0; i < dev->resources; i++) - show_one_resource(debug_level, dev, &dev->resource[i], ""); + struct resource *res; + do_printk(debug_level, "%s: enabled %d\n", + dev_path(dev), dev->enabled); + for (res = dev->resource_list; res; res = res->next) + show_one_resource(debug_level, dev, res, ""); } } + +void ram_resource(device_t dev, unsigned long index, + unsigned long basek, unsigned long sizek) +{ + struct resource *resource; + + if (!sizek) + return; + + resource = new_resource(dev, index); + resource->base = ((resource_t)basek) << 10; + resource->size = ((resource_t)sizek) << 10; + resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \ + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + +void tolm_test(void *gp, struct device *dev, struct resource *new) +{ + struct resource **best_p = gp; + struct resource *best; + + best = *best_p; + + if (!best || (best->base > new->base)) + best = new; + + *best_p = best; +} + +u32 find_pci_tolm(struct bus *bus) +{ + struct resource *min = NULL; + u32 tolm; + + search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, + tolm_test, &min); + + tolm = 0xffffffffUL; + + if (min && tolm > min->base) + tolm = min->base; + + return tolm; +} + +/* Count of enabled CPUs */ +int dev_count_cpu(void) +{ + device_t cpu; + int count = 0; + + for (cpu = all_devices; cpu; cpu = cpu->next) { + if ((cpu->path.type != DEVICE_PATH_APIC) || + (cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER)) + continue; + if (!cpu->enabled) + continue; + count++; + } + + return count; +}