Author: myles Date: 2008-12-31 20:43:34 +0100 (Wed, 31 Dec 2008) New Revision: 1089
Modified: coreboot-v3/device/cardbus_device.c coreboot-v3/device/device.c coreboot-v3/device/device_util.c coreboot-v3/device/pci_device.c coreboot-v3/device/pci_ops.c coreboot-v3/device/root_device.c coreboot-v3/include/device/device.h coreboot-v3/include/device/resource.h Log: This patch simplifies the resource allocator by splitting it into distinct phases. One benefit of this is that it makes the call chain easier to follow.
device/device.c: Remove references to have_resources. Remove read_resources from compute allocate resources. Split compute_allocate_resources into two 1. compute_resource_needs A. Traverse the tree depth first B. Sum resources C. Adjust limits and bases D. Update bridge resources sizes 2. assign_resource_values A. Traverse the tree breadth first B. Assign resource values
device/device_util.c: Remove references to have_resources.
device/pci_device.c: Remove saved values stubs (they're not needed now.) 1. Sizing function restores values Fix 64-bit flag masking. Add an error message for an invalid value. Update pci_record_bridge_resource: 1. remove compute_allocate_resource call 2. remove pci_set_resource call Update pci_bus_read_resources to read children's too. Update pci_set_resource: 1. change logic for setting zero-size resources A. Set range to [limit->limit-2^gran] (Could have been any range with base > limit) 2. remove compute_allocate_resource calls 3. Change phase4_assign_resources ->phase4_set_resources
device/pci_ops.c: Change an error message to be more helpful.
device/root_device.c: Remove code for read_resources and set resources. Add a .id to the ops.
include/device/device.h: Remove have_resources. Comment out assign_resources. I think we could comment out more here. Add debugging function prototypes. Change phase4_assign_resources to phase4_set_resources.
include/device/resource.h Add a IORESOURCE_BRIDGE flag.
device/cardbus_device.c Remove compute_allocate_resource call. Use probe_resource (doesn't die) instead of find_resource.
Signed-off-by: Myles Watson mylesgw@gmail.com Acked-by: Ronald G. Minnich rminnich@gmail.com
Modified: coreboot-v3/device/cardbus_device.c =================================================================== --- coreboot-v3/device/cardbus_device.c 2008-12-30 07:02:52 UTC (rev 1088) +++ coreboot-v3/device/cardbus_device.c 2008-12-31 19:43:34 UTC (rev 1089) @@ -75,11 +75,10 @@ { struct resource *resource; resource_t min_size; - resource = find_resource(dev, index); + resource = probe_resource(dev, index); if (resource) { min_size = resource->size; - compute_allocate_resource(&dev->link[0], resource, - resource->flags, resource->flags); + /* Always allocate at least the minimum size to a * cardbus bridge in case a new card is plugged in. */
Modified: coreboot-v3/device/device.c =================================================================== --- coreboot-v3/device/device.c 2008-12-30 07:02:52 UTC (rev 1088) +++ coreboot-v3/device/device.c 2008-12-31 19:43:34 UTC (rev 1089) @@ -13,6 +13,7 @@ * (Written by Yinghai Lu for Tyan) * Copyright (C) 2005-2006 Stefan Reinauer stepan@openbios.org * Copyright (C) 2007 coresystems GmbH + * Copyright (C) 2008 Myles Watson mylesgw@gmail.com */
/* @@ -48,18 +49,6 @@ struct device **last_dev_p;
/** - * The upper limit of MEM resource of the devices. - * Reserve 20M for the system. - */ -#define DEVICE_MEM_HIGH 0xFEBFFFFFUL - -/** - * The lower limit of I/O resource of the devices. - * Reserve 4K for ISA/Legacy devices. - */ -#define DEVICE_IO_START 0x1000 - -/** * device memory. All the device tree wil live here */
@@ -110,7 +99,7 @@ /** * Given a path, locate the device_operations for it from all_device_operations. * - * @param id TODO + * @param id a device ID to match * @return Pointer to the ops or 0, if none found. * @see device_path */ @@ -127,7 +116,8 @@ printk(BIOS_SPEW, "%s: cons id %s\n", __func__, dev_id_string(&c->id)); if (id_eq(&c->id, id)) { - printk(BIOS_SPEW, "%s: match\n", __func__); + printk(BIOS_SPEW, "%s: match %s\n", + __func__, dev_id_string(&c->id)); return c; } } @@ -138,10 +128,9 @@ /** * Initialization tasks for the device tree code. * - * Sets up last_dev_p, which used to be done by - * Fucking Magic (FM) in the config tool. Also, for each of the - * devices, tries to find the constructor, and from there, the ops, - * for the device. + * Sets up last_dev_p, which used to be done by magic in the config tool. Also, + * for each of the devices, tries to find the constructor, and from there, the + * ops, for the device. */ void dev_init(void) { @@ -206,7 +195,7 @@ * * @param parent Parent bus the newly created device is attached to. * @param path Path to the device to be created. - * @param devid TODO + * @param devid ID of the device we want allocated. * @return Pointer to the newly created device structure. * @see device_path */ @@ -254,7 +243,7 @@ last_dev_p = &dev->next;
/* Give the device a name. */ - if (dev->id.type == DEVICE_ID_PNP && + if (dev->id.type == DEVICE_ID_PNP && parent->dev->id.type == DEVICE_ID_PNP) sprintf(dev->dtsname, "%s_pnp_child_%d", parent->dev->dtsname, dev->path.pnp.device); @@ -292,17 +281,12 @@
/* Walk through all devices and find which resources they need. */ for (curdev = bus->children; curdev; curdev = curdev->sibling) { - unsigned int links; int i; printk(BIOS_SPEW, - "%s: %s(%s) dtsname %s have_resources %d enabled %d\n", + "%s: %s(%s) dtsname %s enabled %d\n", __func__, bus->dev ? bus->dev->dtsname : "NOBUSDEV", bus->dev ? dev_path(bus->dev) : "NOBUSDEV", - curdev->dtsname, - curdev->have_resources, curdev->enabled); - if (curdev->have_resources) { - continue; - } + curdev->dtsname, curdev->enabled); if (!curdev->enabled) { continue; } @@ -313,28 +297,10 @@ continue; } curdev->ops->phase4_read_resources(curdev); - curdev->have_resources = 1;
- /* Read in subtractive resources behind the current device. */ - links = 0; - for (i = 0; i < curdev->resources && (curdev->links > 0); i++) { - struct resource *resource; - unsigned int link; - resource = &curdev->resource[i]; - if (!(resource->flags & IORESOURCE_SUBTRACTIVE)) - continue; - link = IOINDEX_SUBTRACTIVE_LINK(resource->index); - if (link > MAX_LINKS) { - printk(BIOS_ERR, - "%s subtractive index on link: %d\n", - dev_path(curdev), link); - continue; - } - if (!(links & (1 << link))) { - links |= (1 << link); - read_resources(&curdev->link[link]); - } - } + /* Read in children's resources behind the current device. */ + for (i = 0; i< curdev->links; i++) + read_resources(&curdev->link[i]); } printk(BIOS_SPEW, "%s: %s(%s) read_resources bus %d link: %d done\n", __func__, bus->dev->dtsname, dev_path(bus->dev), bus->secondary, @@ -398,7 +364,7 @@ }
/** - * This function is the guts of the resource allocator. + * This function is the first part of the resource allocator. * * The problem. * - Allocate resource locations for every device. @@ -424,85 +390,199 @@ * a device with a couple of resources, and not need to special case it in * the allocator. Also this allows handling of other types of bridges. * - * @param bus TODO - * @param bridge TODO - * @param type_mask TODO - * @param type TODO + * - This function calculates how large the resources are behind the bridges. + * + * @param bus The bus we are traversing. + * @param bridge The bridge resource which will contain the bus' resources. + * @param type_mask This value gets anded with the resource type. + * @param type This value must match the result of the and. */ -void compute_allocate_resource(struct bus *bus, struct resource *bridge, +void compute_resource_needs(struct bus *bus, struct resource *bridge, unsigned long type_mask, unsigned long type) { struct device *dev; struct resource *resource; resource_t base; - unsigned long align, min_align; - min_align = 0; - base = bridge->base; + base = align_up(bridge->base, bridge->align);
printk(BIOS_SPEW, - "%s compute_allocate_%s: base: %08llx size: %08llx align: %d gran: %d limit: %08llx\n", - dev_path(bus->dev), - (bridge->flags & IORESOURCE_IO) ? "io" : (bridge->flags & - IORESOURCE_PREFETCH) ? - "prefmem" : "mem", base, bridge->size, bridge->align, + "%s %s_%s: base: %llx size: %llx align: %d gran: %d limit: %llx\n", + dev_path(bus->dev), __func__, + (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ? + "prefmem" : "mem", + base, bridge->size, bridge->align, bridge->gran, bridge->limit);
- /* We want different minimum alignments for different kinds of - * resources. These minimums are not device type specific but - * resource type specific. - */ - if (bridge->flags & IORESOURCE_IO) { - min_align = log2c(DEVICE_IO_ALIGN); + /* For each child which is a bridge, compute_resource_needs. */ + for (dev = bus->children; dev; dev = dev->sibling) { + unsigned i; + struct resource *child_bridge; + + if (!dev->links) + continue; + + /* Find the resources with matching type flags. */ + for (i=0; i< dev->resources; i++){ + child_bridge = &dev->resource[i]; + + if (!(child_bridge->flags & IORESOURCE_BRIDGE) || + (child_bridge->flags & type_mask) != type) + continue; + + /* Split prefetchable memory if combined. Many domains + * use the same address space for prefetchable memory + * and non-prefetchable memory. Bridges below them + * need it separated. Add the PREFETCH flag to the + * type_mask and type. + */ + compute_resource_needs(&dev->link[0], child_bridge, + type_mask | IORESOURCE_PREFETCH, + type | (child_bridge->flags & + IORESOURCE_PREFETCH)); + } } - if (bridge->flags & IORESOURCE_MEM) { - min_align = log2c(DEVICE_MEM_ALIGN); - }
- /* Make certain we have read in all of the resources. */ - read_resources(bus); - /* Remember we haven't found anything yet. */ resource = NULL;
- /* Walk through all the devices on the current bus and - * compute the addresses. + /* Walk through all the resources on the current bus and compute the + * amount of address space taken by them. Take granularity and + * alignment into account. */ while ((dev = largest_resource(bus, &resource, type_mask, type))) { - resource_t size;
- /* Do NOT, I repeat do not, ignore resources which have zero - * size. If they need to be ignored dev->read_resources should - * not even return them. Some resources must be set even when - * they have no size. PCI bridge resources are a good example - * of this. - */ - - /* Make certain we are dealing with a good minimum size. */ - size = resource->size; - align = resource->align; - if (align < min_align) { - align = min_align; + /* Size 0 resources can be skipped. */ + if (!resource->size) { + continue; }
- /* Propagate the resource alignment to the bridge register */ - if (align > bridge->align) { - bridge->align = align; + /* Propagate the resource alignment to the bridge resource. */ + if (resource->align > bridge->align) { + bridge->align = resource->align; }
- if (resource->flags & IORESOURCE_FIXED) { - continue; - } - /* Propagate the resource limit to the bridge register. */ if (bridge->limit > resource->limit) { bridge->limit = resource->limit; }
- /* Artificially deny limits between DEVICE_MEM_HIGH and 0xffffffff. */ - if ((bridge->limit > DEVICE_MEM_HIGH) - && (bridge->limit <= 0xffffffff)) { - bridge->limit = DEVICE_MEM_HIGH; + /* I'm not sure what to do here. I'd really like this to go + * away into some PCI-specific file, but I don't see how to do + * it. I'm also not sure how to guarantee that larger + * allocations don't conflict with this address set. + * The example is 0x1000-0x13ff overlaps, but since the base + * doesn't, then this check doesn't trigger. It wouldn't do + * any good, though, since you can't move it to avoid the + * conflict. + */ + if (resource->flags & IORESOURCE_IO) { + /* Don't allow potential aliases over the legacy PCI + * expansion card addresses. The legacy PCI decodes + * only 10 bits, uses 0x100 - 0x3ff. Therefore, only + * 0x00 - 0xff can be used out of each 0x400 block of + * I/O space. + */ + if ((base & 0x300) != 0) { + base = (base & ~0x3ff) + 0x400; + } + /* Don't allow allocations in the VGA I/O range. + * PCI has special cases for that. + */ + else if ((base >= 0x3b0) && (base <= 0x3df)) { + base = 0x3e0; + } } + /* Base must be aligned. */ + base = align_up(base, resource->align); + resource->base = base; + base += resource->size; + + printk(BIOS_SPEW, "%s %02lx * [0x%llx - 0x%llx] %s\n", + dev_path(dev), resource->index, resource->base, + resource->base + resource->size - 1, + (resource->flags & IORESOURCE_IO) ? "io" : + (resource-> flags & IORESOURCE_PREFETCH) ? "prefmem" : + "mem"); + } + /* Bridge resources have a minimum granularity. Round the size up to + * that minimum granularity so we know not to place something else at + * an address positively decoded by the bridge. + */ + bridge->size = align_up(base, bridge->gran) - + align_up(bridge->base, bridge->align); + + printk(BIOS_SPEW, + "%s %s_%s: base: %llx size: %llx align: %d gran: %d limit: %llx done\n", + dev_path(bus->dev), __func__, + (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ? + "prefmem" : "mem", + base, bridge->size, bridge->align, + bridge->gran, bridge->limit); +} + +/** + * This function is the second part of the resource allocator. + * + * The problem. + * - Allocate resource locations for every device. + * - Don't overlap, and follow the rules of bridges. + * - Don't overlap with resources in fixed locations. + * - Be efficient so we don't have ugly strategies. + * + * The strategy. + * - Devices that have fixed addresses are the minority so don't + * worry about them too much. Instead only use part of the address + * space for devices with programmable addresses. This easily handles + * everything except bridges. + * + * - PCI devices are required to have their sizes and their alignments + * equal. In this case an optimal solution to the packing problem + * exists. Allocate all devices from highest alignment to least + * alignment or vice versa. Use this. + * + * - So we can handle more than PCI run two allocation passes on bridges. The + * first to see how large the resources are behind the bridge, and what + * their alignment requirements are. The second to assign a safe address to + * the devices behind the bridge. This allows us to treat a bridge as just + * a device with a couple of resources, and not need to special case it in + * the allocator. Also this allows handling of other types of bridges. + * + * - This function assigns the resources a value. + * + * @param bus The bus we are traversing. + * @param bridge The bridge resource which must contain the bus' resources. + * @param type_mask This value gets anded with the resource type. + * @param type This value must match the result of the and. + */ +void assign_resource_values(struct bus *bus, struct resource *bridge, + unsigned long type_mask, unsigned long type) +{ + struct device *dev; + struct resource *resource; + resource_t base; + base = bridge->base; + + printk(BIOS_SPEW, + "%s %s_%s: base:%llx size:%llx align:%d gran:%d limit:%llx\n", + dev_path(bus->dev), __func__, + (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ? + "prefmem" : "mem", + base, bridge->size, bridge->align, + bridge->gran, bridge->limit); + + /* Remember we haven't found anything yet. */ + resource = NULL; + + /* Walk through all the resources on the current bus and allocate them + * address space. + */ + while ((dev = largest_resource(bus, &resource, type_mask, type))) { + + /* Size 0 resources can be skipped. */ + if (!resource->size) { + continue; + } + if (resource->flags & IORESOURCE_IO) { /* Don't allow potential aliases over the legacy PCI * expansion card addresses. The legacy PCI decodes @@ -520,42 +600,210 @@ base = 0x3e0; } } - if (((align_up(base, align) + size) - 1) <= resource->limit) { - /* Base must be aligned to size. */ - base = align_up(base, align); + + + if ((align_up(base, resource->align) + resource->size - 1) <= + resource->limit) { + /* Base must be aligned. */ + base = align_up(base, resource->align); resource->base = base; resource->flags |= IORESOURCE_ASSIGNED; resource->flags &= ~IORESOURCE_STORED; - base += size; + base += resource->size; + } else { + printk(BIOS_ERR, "!! Resource didn't fit !!\n"); + printk(BIOS_ERR, " aligned base %llx size %llx limit %llx\n", + align_up(base, resource->align), resource->size, resource->limit); + printk(BIOS_ERR, " %llx needs to be <= %llx (limit)\n", + (align_up(base, resource->align)+resource->size)-1, resource->limit); + printk(BIOS_ERR, " %s%s %02lx * [0x%llx - 0x%llx] %s\n", + (resource->flags & IORESOURCE_ASSIGNED) ? "Assigned: " + : "", + dev_path(dev), resource->index, resource->base, + resource->base + resource->size - 1, + (resource->flags & IORESOURCE_IO) ? "io" : + (resource-> flags & IORESOURCE_PREFETCH) ? "prefmem" : + "mem"); + }
- printk(BIOS_SPEW, - "%s %02lx * [0x%08llx - 0x%08llx] %s\n", - dev_path(dev), - resource->index, - resource->base, - resource->base + resource->size - 1, - (resource->flags & IORESOURCE_IO) ? "io" : - (resource-> - flags & IORESOURCE_PREFETCH) ? "prefmem" : - "mem"); - } + printk(BIOS_SPEW, "%s%s %02lx * [0x%llx - 0x%llx] %s\n", + (resource->flags & IORESOURCE_ASSIGNED) ? "Assigned: " + : "", + dev_path(dev), resource->index, resource->base, + + resource->size? resource->base + resource->size - 1 : + resource->base, + + (resource->flags & IORESOURCE_IO) ? "io" : + (resource-> flags & IORESOURCE_PREFETCH) ? "prefmem" : + "mem"); } /* A PCI bridge resource does not need to be a power of two size, but * it does have a minimum granularity. Round the size up to that * minimum granularity so we know not to place something else at an * address positively decoded by the bridge. */ - bridge->size = align_up(base, bridge->gran) - bridge->base;
+ bridge->flags |= IORESOURCE_ASSIGNED; + printk(BIOS_SPEW, - "%s compute_allocate_%s: base: %08llx size: %08llx align: %d gran: %d done\n", - dev_path(bus->dev), - (bridge->flags & IORESOURCE_IO) ? "io" : (bridge->flags & - IORESOURCE_PREFETCH) ? - "prefmem" : "mem", base, bridge->size, bridge->align, + "%s %s_%s: next_base: %llx size: %llx align: %d gran: %d done\n", + dev_path(bus->dev), __func__, + (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ? + "prefmem" : "mem", + base, bridge->size, bridge->align, bridge->gran); + + /* For each child which is a bridge, assign_resource_values. */ + for (dev = bus->children; dev; dev = dev->sibling) { + unsigned i; + struct resource *child_bridge; + + if (!dev->links) + continue; + + /* Find the resources with matching type flags. */ + for (i=0; i< dev->resources; i++){ + child_bridge = &dev->resource[i]; + + if (!(child_bridge->flags & IORESOURCE_BRIDGE) || + (child_bridge->flags & type_mask) != type) + continue; + + /* Split prefetchable memory if combined. Many domains + * use the same address space for prefetchable memory + * and non-prefetchable memory. Bridges below them + * need it separated. Add the PREFETCH flag to the + * type_mask and type. + */ + assign_resource_values(&dev->link[0], child_bridge, + type_mask | IORESOURCE_PREFETCH, + type | (child_bridge->flags & + IORESOURCE_PREFETCH)); + } + } }
+struct constraints { + struct resource pref, io, mem; +}; + +static void constrain_resources(struct device *dev, struct constraints* limits) +{ + struct device *child; + struct resource *res; + struct resource *lim; + int i; + +#ifdef CONFIG_PCI_64BIT_PREF_MEM + #define MEM_MASK (IORESOURCE_PREFETCH | IORESOURCE_MEM) +#else + #define MEM_MASK (IORESOURCE_MEM) +#endif +#define IO_MASK (IORESOURCE_IO) +#define PREF_TYPE (IORESOURCE_PREFETCH | IORESOURCE_MEM) +#define MEM_TYPE (IORESOURCE_MEM) +#define IO_TYPE (IORESOURCE_IO) + + /* Descend into every child and look for fixed resources. */ + for (child=dev->link[0].children; child; child = child->sibling) { + constrain_resources(child, limits); + for (i = 0; i<child->resources; i++) { + res = &child->resource[i]; + if (!(res->flags & IORESOURCE_FIXED)) + continue; + + /* PREFETCH, MEM, or I/O - skip any others. */ + if ((res->flags & MEM_MASK) == PREF_TYPE) + lim = &limits->pref; + else if ((res->flags & MEM_MASK) == MEM_TYPE) + lim = &limits->mem; + else if ((res->flags & IO_MASK) == IO_TYPE) + lim = &limits->io; + else + continue; + + /* Is it already outside the limits? */ + if (res->size && + (((res->base + res->size -1) < lim->base) || + (res->base > lim->limit))) + continue; + + /* Choose to be above or below fixed resources. This + * check is signed so that "negative" amounts of space + * are handled correctly. + */ + if ((s64)(lim->limit - (res->base + res->size -1)) > + (s64)(res->base - lim->base)) + lim->base = res->base + res->size; + else + lim->limit = res->base -1; + } + } +} + +static void avoid_fixed_resources(struct device *dev) +{ + struct constraints limits; + struct resource *res; + int i; + + /* Initialize constraints to maximum size. */ + + limits.pref.base = 0; + limits.pref.limit = 0xffffffffffffffffULL; + limits.io.base = 0; + limits.io.limit = 0xffffffffffffffffULL; + limits.mem.base = 0; + limits.mem.limit = 0xffffffffffffffffULL; + + /* Constrain the limits to dev's initial resources. */ + for (i = 0; i<dev->resources; i++) { + res = &dev->resource[i]; + if ((res->flags & IORESOURCE_FIXED) || + !(res->flags & IORESOURCE_BRIDGE)) + continue; + if ((res->flags & MEM_MASK) == PREF_TYPE && + (res->limit < limits.pref.limit)) + limits.pref.limit = res->limit; + if ((res->flags & MEM_MASK) == MEM_TYPE && + (res->limit < limits.mem.limit)) + limits.mem.limit = res->limit; + if ((res->flags & IO_MASK) == IO_TYPE && + (res->limit < limits.io.limit)) + limits.io.limit = res->limit; + } + + /* Look through the tree for fixed resources and update the limits. */ + constrain_resources(dev, &limits); + + /* Update dev's resources with new limits. */ + for (i = 0; i<dev->resources; i++) { + struct resource *lim; + res = &dev->resource[i]; + + if ((res->flags & IORESOURCE_FIXED) || + !(res->flags & IORESOURCE_BRIDGE)) + continue; + + /* PREFETCH, MEM, or I/O - skip any others. */ + if ((res->flags & MEM_MASK) == PREF_TYPE) + lim = &limits.pref; + else if ((res->flags & MEM_MASK) == MEM_TYPE) + lim = &limits.mem; + else if ((res->flags & IO_MASK) == IO_TYPE) + lim = &limits.io; + else + continue; + + /* Is the resource outside the limits? */ + if ( lim->base > res->base ) + res->base = lim->base; + if ( res->limit > lim->limit ) + res->limit = lim->limit; + } +} + #ifdef CONFIG_PCI_OPTION_ROM_RUN struct device *vga_pri = 0; int vga_inited = 0; @@ -639,16 +887,16 @@ * has to recurse into every down stream buses. * * Mutual recursion: - * assign_resources() -> device_operation::set_resources() - * device_operation::set_resources() -> assign_resources() + * phase4_set_resources() -> device_operation::set_resources() + * device_operation::set_resources() -> phase4_set_resources() * * @param bus Pointer to the structure for this bus. */ -void phase4_assign_resources(struct bus *bus) +void phase4_set_resources(struct bus *bus) { struct device *curdev;
- printk(BIOS_SPEW, "%s(%s) assign_resources, bus %d link: %d\n", + printk(BIOS_SPEW, "%s(%s) %s, bus %d link: %d\n", __func__, bus->dev->dtsname, dev_path(bus->dev), bus->secondary, bus->link);
@@ -669,7 +917,7 @@ } curdev->ops->phase4_set_resources(curdev); } - printk(BIOS_SPEW, "%s(%s) assign_resources done, bus %d link: %d\n", + printk(BIOS_SPEW, "%s(%s) %s done, bus %d link: %d\n", __func__, bus->dev->dtsname, dev_path(bus->dev), bus->secondary, bus->link); } @@ -895,7 +1143,7 @@ dtsname : "NULL"); for (i = 0; i < root->resources; i++) { printk(BIOS_DEBUG, - "%s%s resource base %llx size %llx align %x gran %x limit %llx flags %lx index %lx\n", + "%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, @@ -919,129 +1167,140 @@ }
/* Bail if not printing to screen. */ - if (!printk(debug_level, "Show all resources in tree form...%s\n", msg)) + if (!printk(debug_level, "Show resources in subtree (%s)...%s\n", + root->dtsname, msg)) return; resource_tree(root, debug_level, 0); }
/** - * Configure devices on the device tree. + * Allocate resources. * - * Starting at the root of the device tree, travel it recursively in two - * passes. In the first pass, we compute and allocate resources (ranges) - * required by each device. In the second pass, the resources ranges are - * relocated to their final position and stored to the hardware. + * Starting at the root of the device tree, travel it recursively in four + * passes. In the first pass, we read all the resources. In the second pass we + * compute the resource needs. In the third pass we assign final values to the + * resources. In the fourth pass we set them. * - * I/O resources start at DEVICE_IO_START and grow upward. MEM resources start - * at DEVICE_MEM_START and grow downward. + * I/O resources start at the bottom of the domain's resource and grow upward. + * MEM resources start at the top of the domain's resource and grow downward. * - * Since the assignment is hierarchical we set the values into the dev_root - * struct. */ void dev_phase4(void) { - struct resource *io, *mem; + struct resource *res; struct device *root; + struct device * child; + int i;
printk(BIOS_INFO, "Phase 4: Allocating resources...\n");
root = &dev_root; - if (!root->ops) { - printk(BIOS_ERR, - "Phase 4: dev_root missing ops initialization\nPhase 4: Failed.\n"); - return; - } - if (!root->ops->phase4_read_resources) { - printk(BIOS_ERR, - "dev_root ops missing read_resources\nPhase 4: Failed.\n"); - return; - }
- if (!root->ops->phase4_set_resources) { - printk(BIOS_ERR, - "dev_root ops missing set_resources\nPhase 4: Failed.\n"); - return; - } + /* Each domain should create resources which contain the entire address + * space for IO, MEM, and PREFMEM resources in the domain. The + * allocation of device resources will be done from this address space. + */
printk(BIOS_INFO, "Phase 4: Reading resources...\n"); - root->ops->phase4_read_resources(root); + + /* Read the resources for the entire tree. */ + read_resources(&root->link[0]); + printk(BIOS_INFO, "Phase 4: Done reading resources.\n");
- /* We have read the resources. We now compute the global allocation of - * resources. We have to create a root resource for the base of the - * tree. The root resource should contain the entire address space for - * IO and MEM resources. The allocation of device resources will be done - * from this resource address space. - */ + printk(BIOS_INFO, "Phase 4: Constrain resources.\n");
- /* Allocate a resource from the root device resource pool and initialize - * the system-wide I/O space constraints. - */ - io = new_resource(root, 0); - io->base = 0x400; - io->size = 0; - io->align = 0; - io->gran = 0; - io->limit = 0xffffUL; - io->flags = IORESOURCE_IO; + /* For all domains. */ + for (child = root->link[0].children; child; + child=child->sibling) + if (child->path.type == DEVICE_PATH_PCI_DOMAIN) + avoid_fixed_resources(child);
- /* Allocate a resource from the root device resource pool and initialize - * the system-wide memory resources constraints. - */ - mem = new_resource(root, 1); - mem->base = 0; - mem->size = 0; - mem->align = 0; - mem->gran = 0; - mem->limit = 0xffffffffUL; - mem->flags = IORESOURCE_MEM; + print_resource_tree(root, BIOS_DEBUG, "Original.");
- compute_allocate_resource(&root->link[0], io, - IORESOURCE_IO, IORESOURCE_IO); + /* Compute resources for all domains. */ + for (child = root->link[0].children; child; child=child->sibling) { + if (!(child->path.type == DEVICE_PATH_PCI_DOMAIN)) + continue; + for (i=0; i< child->resources; i++) { + res = &child->resource[i]; + if ( res->flags & IORESOURCE_FIXED ) + continue; + if ( res->flags & IORESOURCE_PREFETCH ) { + compute_resource_needs(&child->link[0], + res, MEM_MASK, PREF_TYPE); + continue; + } + if ( res->flags & IORESOURCE_MEM ) { + compute_resource_needs(&child->link[0], + res, MEM_MASK, MEM_TYPE); + continue; + } + if ( res->flags & IORESOURCE_IO ) { + compute_resource_needs(&child->link[0], + res, IO_MASK, IO_TYPE); + continue; + } + } + }
- compute_allocate_resource(&root->link[0], mem, - IORESOURCE_MEM, IORESOURCE_MEM); + print_resource_tree(root, BIOS_DEBUG, "After summations.");
- print_resource_tree(root, BIOS_DEBUG, "After first compute_allocate."); - /* Now we need to adjust the resources. The issue is that mem grows - * downward. + * downward. Reallocate the MEM resources with the highest addresses + * I can manage. */ - /* Make certain the I/O devices are allocated somewhere safe. */ - io->base = DEVICE_IO_START; - io->flags |= IORESOURCE_ASSIGNED; - io->flags &= ~IORESOURCE_STORED; + for (child = root->link[0].children; child; child=child->sibling) { + if (child->path.type != DEVICE_PATH_PCI_DOMAIN) + continue; + for (i=0; i< child->resources; i++) { + res = &child->resource[i]; + if (!(res->flags & IORESOURCE_MEM) || + res->flags & IORESOURCE_FIXED ) + continue; + res->base = resource_max(res); + } + }
- /* Now reallocate the PCI resources memory with the - * highest addresses I can manage. - */ - mem->base = resource_max(&root->resource[1]); - mem->flags |= IORESOURCE_ASSIGNED; - mem->flags &= ~IORESOURCE_STORED; - #ifdef CONFIG_PCI_OPTION_ROM_RUN /* Allocate the VGA I/O resource. */ allocate_vga_resource(); + print_resource_tree(root, BIOS_DEBUG, "After VGA."); #endif
- /* now rerun the compute allocate with the adjusted resources */ - compute_allocate_resource(&root->link[0], io, - IORESOURCE_IO, IORESOURCE_IO); + /* Assign values to the resources for all domains. */ + /* If the domain has a prefetchable memory resource, use it. */ + for (child = root->link[0].children; child; child=child->sibling) { + if (!(child->path.type == DEVICE_PATH_PCI_DOMAIN)) + continue; + for (i=0; i< child->resources; i++) { + res = &child->resource[i]; + if ( res->flags & IORESOURCE_FIXED ) + continue; + if ( res->flags & IORESOURCE_PREFETCH ) { + assign_resource_values(&child->link[0], + res, MEM_MASK, PREF_TYPE); + continue; + } + if ( res->flags & IORESOURCE_MEM ) { + assign_resource_values(&child->link[0], + res, MEM_MASK, MEM_TYPE); + continue; + } + if ( res->flags & IORESOURCE_IO ) { + assign_resource_values(&child->link[0], + res, IO_MASK, IO_TYPE); + continue; + } + } + }
- compute_allocate_resource(&root->link[0], mem, - IORESOURCE_MEM, IORESOURCE_MEM); + print_resource_tree(root, BIOS_DEBUG, "After assigning values.");
- print_resource_tree(root, BIOS_DEBUG, "After second compute_allocate."); - /* Store the computed resource allocations into device registers. */ printk(BIOS_INFO, "Phase 4: Setting resources...\n"); - root->ops->phase4_set_resources(root); + phase4_set_resources(&root->link[0]); print_resource_tree(root, BIOS_DEBUG, "After setting resources."); - printk(BIOS_INFO, "Phase 4: Done setting resources.\n"); -#if 0 - mem->flags |= IORESOURCE_STORED; - report_resource_stored(root, mem, ""); -#endif
printk(BIOS_INFO, "Phase 4: Done allocating resources.\n"); } @@ -1132,21 +1391,21 @@ return; for (dev = all_devices; dev; dev = dev->next) { printk(debug_level, - "%s(%s): enabled %d have_resources %d\n", + "%s(%s): enabled %d, %d resources\n", dev->dtsname, dev_path(dev), dev->enabled, - dev->have_resources); + dev->resources); } }
-void show_one_resource(struct device *dev, struct resource *resource, - const char *comment) +void show_one_resource(int debug_level, struct device *dev, + struct resource *resource, const char *comment) { char buf[10]; unsigned long long base, end; base = resource->base; end = resource_end(resource); buf[0] = '\0'; - if (resource->flags & IORESOURCE_PCI_BRIDGE) { + if (resource->flags & IORESOURCE_BRIDGE) { #if PCI_BUS_SEGN_BITS sprintf(buf, "bus %04x:%02x ", dev->bus->secondary >> 8, dev->link[0].secondary & 0xff); @@ -1154,7 +1413,7 @@ sprintf(buf, "bus %02x ", dev->link[0].secondary); #endif } - printk(BIOS_DEBUG, "%s %02lx <- [0x%010llx - 0x%010llx] " + 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, @@ -1162,18 +1421,20 @@
}
-void show_all_devs_resources(void) +void show_all_devs_resources(int debug_level, const char* msg) { struct device *dev;
- printk(BIOS_INFO, "Show all devs...\n"); + if(!printk(debug_level, "Show all devs with resources...%s\n", msg)) + return; + for (dev = all_devices; dev; dev = dev->next) { int i; - printk(BIOS_SPEW, - "%s(%s): enabled %d have_resources %d\n", + printk(debug_level, + "%s(%s): enabled %d, %d resources\n", dev->dtsname, dev_path(dev), dev->enabled, - dev->have_resources); + dev->resources); for (i = 0; i < dev->resources; i++) - show_one_resource(dev, &dev->resource[i], ""); + show_one_resource(debug_level, dev, &dev->resource[i], ""); } }
Modified: coreboot-v3/device/device_util.c =================================================================== --- coreboot-v3/device/device_util.c 2008-12-30 07:02:52 UTC (rev 1088) +++ coreboot-v3/device/device_util.c 2008-12-31 19:43:34 UTC (rev 1089) @@ -241,7 +241,7 @@ dev->path.ioport.iobase); break; default: - printk(BIOS_ERR, "%s: Unknown device path type: %d\n", + printk(BIOS_ERR, "%s: Unknown device path type: %x\n", dev->dtsname, dev->path.type); break; } @@ -293,7 +293,7 @@ id->cpu_bus.vendor, id->cpu_bus.device); break; default: - printk(BIOS_ERR, "%s: Unknown device ID type: %d\n", + printk(BIOS_ERR, "%s: Unknown device ID type: %x\n", __func__, id->type); memcpy(buffer, "Unknown", 8); break; @@ -349,8 +349,8 @@ equal = (path1->cpu_bus.id == path2->cpu_bus.id); break; default: - printk(BIOS_ERR, "Unknown device type: %d\n", - path1->type); + printk(BIOS_ERR, "%s: Unknown device type: %x\n", + __func__, path1->type); break; } } @@ -403,8 +403,8 @@ && (path1->cpu_bus.device == path2->cpu_bus.device); break; default: - printk(BIOS_ERR, "Unknown device type: %d\n", - path1->type); + printk(BIOS_ERR, "%s: Unknown device type: %x\n", + __func__, path1->type); break; } } @@ -615,26 +615,29 @@ void report_resource_stored(struct device *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) { + char buf[10]; + unsigned long long base, end; + base = resource->base; + end = resource_end(resource); + buf[0] = '\0'; + + if (!(resource->flags & IORESOURCE_STORED)) + printk(BIOS_DEBUG, "%s lying: %s(%s) %02lx\n", + __func__, dev_path(dev), dev->dtsname, resource->index); + + if (resource->flags & IORESOURCE_BRIDGE) { #if 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[0].secondary & 0xff); #else - sprintf(buf, "bus %02x ", dev->link[0].secondary); + sprintf(buf, "bus %02x ", dev->link[0].secondary); #endif - } - printk(BIOS_DEBUG, "%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); } + printk(BIOS_DEBUG, "%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); }
void search_bus_resources(struct bus *bus, @@ -644,9 +647,6 @@ 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. */ @@ -676,12 +676,8 @@ for (curdev = all_devices; curdev; curdev = curdev->next) { int i; printk(BIOS_SPEW, - "%s: dev %s, have_resources %d #resources %d\n", - __func__, curdev->dtsname, curdev->have_resources, - curdev->resources); - /* Ignore disabled devices. */ - if (!curdev->have_resources) - continue; + "%s: dev %s, #resources %d\n", + __func__, curdev->dtsname, curdev->resources); for (i = 0; i < curdev->resources; i++) { struct resource *resource = &curdev->resource[i]; printk(BIOS_SPEW,
Modified: coreboot-v3/device/pci_device.c =================================================================== --- coreboot-v3/device/pci_device.c 2008-12-30 07:02:52 UTC (rev 1088) +++ coreboot-v3/device/pci_device.c 2008-12-31 19:43:34 UTC (rev 1089) @@ -11,6 +11,7 @@ * Copyright (C) 2005-2006 Tyan * (Written by Yinghai Lu yhlu@tyan.com for Tyan) * Copyright (C) 2005-2007 Stefan Reinauer stepan@openbios.org + * Copyright (C) 2008 Myles Watson mylesgw@gmail.com */
/* @@ -153,7 +154,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) { struct resource *resource; - unsigned long value, attr, base; + unsigned long value, attr; resource_t moving, limit;
/* Initialize the resources to nothing. */ @@ -162,15 +163,9 @@ /* Get the initial value. */ value = pci_read_config32(dev, index);
- /* save the base address */ - if (value & PCI_BASE_ADDRESS_SPACE_IO) - base = value & ~PCI_BASE_ADDRESS_IO_ATTR_MASK; - else - base = value & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK; - /* See which bits move. */ moving = pci_moving_config32(dev, index); - /* Next step: save the base in the dev struct. For later next week */ + /* Initialize attr to the bits that do not move. */ attr = value & ~moving;
@@ -222,7 +217,7 @@ * Shouldn't zero because we'll get off with 64-bit BARs. * Are there any others to save? */ - resource->flags &= ~IORESOURCE_PCI64; + resource->flags &= IORESOURCE_PCI64; } else if (attr & PCI_BASE_ADDRESS_SPACE_IO) { /* An I/O mapped base address. */ attr &= PCI_BASE_ADDRESS_IO_ATTR_MASK; @@ -248,6 +243,8 @@ resource->limit = 0xffffffffffffffffULL; } else { /* Invalid value. */ + printk(BIOS_ERR,"Broken BAR with value %lx\n",attr); + printk(BIOS_ERR," on dev %s at index %02lx\n",dev->dtsname,index); resource->flags = 0; } } @@ -347,15 +344,12 @@ compact_resources(dev); }
-static void pci_set_resource(struct device *dev, struct resource *resource); - static void pci_record_bridge_resource(struct device *dev, resource_t moving, - unsigned int index, unsigned long mask, - unsigned long type) + unsigned int index, unsigned long type) { /* Initialize the constraints on the current bus. */ struct resource *resource; - resource = 0; + resource = NULL; if (moving) { unsigned long gran; resource_t step; @@ -370,18 +364,7 @@ resource->gran = gran; resource->align = gran; resource->limit = moving | (step - 1); - resource->flags = type | IORESOURCE_PCI_BRIDGE; - compute_allocate_resource(&dev->link[0], resource, mask, type); - /* If there is nothing behind the resource, - * clear it and forget it. - */ - if (resource->size == 0) { - resource->base = moving; - resource->flags |= IORESOURCE_ASSIGNED; - resource->flags &= ~IORESOURCE_STORED; - pci_set_resource(dev, resource); - resource->flags = 0; - } + resource->flags = type | IORESOURCE_PCI_BRIDGE | IORESOURCE_BRIDGE; } return; } @@ -402,8 +385,7 @@ moving = moving_base & moving_limit;
/* Initialize the I/O space constraints on the current bus. */ - pci_record_bridge_resource(dev, moving, PCI_IO_BASE, - IORESOURCE_IO, IORESOURCE_IO); + pci_record_bridge_resource(dev, moving, PCI_IO_BASE, IORESOURCE_IO);
/* See if the bridge prefmem resources are implemented. */ moving_base = @@ -416,7 +398,6 @@ moving = moving_base & moving_limit; /* Initialize the prefetchable memory constraints on the current bus. */ pci_record_bridge_resource(dev, moving, PCI_PREF_MEMORY_BASE, - IORESOURCE_MEM | IORESOURCE_PREFETCH, IORESOURCE_MEM | IORESOURCE_PREFETCH);
/* See if the bridge mem resources are implemented. */ @@ -427,7 +408,6 @@
/* Initialize the memory resources on the current bus. */ pci_record_bridge_resource(dev, moving, PCI_MEMORY_BASE, - IORESOURCE_MEM | IORESOURCE_PREFETCH, IORESOURCE_MEM);
compact_resources(dev); @@ -441,9 +421,24 @@
void pci_bus_read_resources(struct device *dev) { + struct device *child; + + printk(BIOS_DEBUG, "%s: %s bus %s\n", + __func__, dev_path(dev), dev->bus? dev_path(dev->bus->dev):"NULL"); pci_bridge_read_bases(dev); pci_read_bases(dev, 2); pci_get_rom_resource(dev, PCI_ROM_ADDRESS1); + if (!dev->bus){ + printk(BIOS_ERR, "%s: %s bus %s\n", + __func__, dev_path(dev), dev->bus? dev_path(dev->bus->dev):"NULL"); + } + + for (child = dev->link[0].children; child; child = child->sibling) + if (child->ops && child->ops->phase4_read_resources) + child->ops->phase4_read_resources(child); + else + printk(BIOS_ERR, "%s: %s missing Phase4\n", + __func__, dev_path(child)); }
/** @@ -462,22 +457,22 @@ /* Initialize the system-wide I/O space constraints. */ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0)); res->limit = 0xffffUL; - res->flags = - IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | + IORESOURCE_ASSIGNED | IORESOURCE_BRIDGE;
/* Initialize the system-wide memory resources constraints. */ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0)); res->limit = 0xffffffffULL; - res->flags = - IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | + IORESOURCE_ASSIGNED | IORESOURCE_BRIDGE; }
static void pci_set_resource(struct device *dev, struct resource *resource) { resource_t base, end;
- /* Make certain the resource has actually been set. */ - if (!(resource->flags & IORESOURCE_ASSIGNED)) { + /* Make certain the resource has actually been assigned a value. */ + if (!(resource->flags & IORESOURCE_ASSIGNED) && resource->size!=0) { printk(BIOS_ERR, "ERROR: %s %02lx %s size: 0x%010llx not assigned\n", dev_path(dev), resource->index, resource_type(resource), @@ -519,6 +514,16 @@
/* Now store the resource. */ resource->flags |= IORESOURCE_STORED; + /* PCI Bridges have no enable bit. They are disabled if the base of + * the range is greater than the limit. If the size is zero, disable + * by setting the base = limit and end = limit - 2^gran. + */ + if (resource->size == 0 && (resource->flags & IORESOURCE_PCI_BRIDGE)) { + base = resource->limit; + end = resource->limit - (1<<resource->gran); + resource->base = base; + } + if (!(resource->flags & IORESOURCE_PCI_BRIDGE)) { unsigned long base_lo, base_hi; /* Some chipsets allow us to set/clear the I/O bit @@ -535,24 +540,16 @@ } } else if (resource->index == PCI_IO_BASE) { /* Set the I/O ranges. */ - compute_allocate_resource(&dev->link[0], resource, - IORESOURCE_IO, IORESOURCE_IO); pci_write_config8(dev, PCI_IO_BASE, base >> 8); pci_write_config16(dev, PCI_IO_BASE_UPPER16, base >> 16); pci_write_config8(dev, PCI_IO_LIMIT, end >> 8); pci_write_config16(dev, PCI_IO_LIMIT_UPPER16, end >> 16); } else if (resource->index == PCI_MEMORY_BASE) { /* Set the memory range. */ - compute_allocate_resource(&dev->link[0], resource, - IORESOURCE_MEM | IORESOURCE_PREFETCH, - IORESOURCE_MEM); pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16); pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16); } else if (resource->index == PCI_PREF_MEMORY_BASE) { /* Set the prefetchable memory range. */ - compute_allocate_resource(&dev->link[0], resource, - IORESOURCE_MEM | IORESOURCE_PREFETCH, - IORESOURCE_MEM | IORESOURCE_PREFETCH); pci_write_config16(dev, PCI_PREF_MEMORY_BASE, base >> 16); pci_write_config32(dev, PCI_PREF_BASE_UPPER32, base >> 32); pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, end >> 16); @@ -563,7 +560,7 @@ printk(BIOS_ERR, "ERROR: invalid resource->index %lx\n", resource->index); } - report_resource_stored(dev, resource, ""); + report_resource_stored(dev, resource, __func__); return; }
@@ -582,7 +579,7 @@ struct bus *bus; bus = &dev->link[link]; if (bus->children) { - phase4_assign_resources(bus); + phase4_set_resources(bus); } }
Modified: coreboot-v3/device/pci_ops.c =================================================================== --- coreboot-v3/device/pci_ops.c 2008-12-30 07:02:52 UTC (rev 1088) +++ coreboot-v3/device/pci_ops.c 2008-12-31 19:43:34 UTC (rev 1089) @@ -36,7 +36,7 @@ struct bus *pbus = dev->bus; while (pbus && pbus->dev && !ops_pci_bus(pbus)) { if (pbus->dev == dev) { - printk(BIOS_EMERG, "Loop: dev->dtsname dev->bus->dev\n"); + printk(BIOS_EMERG, "Loop: %s->bus->dev\n", dev->dtsname); printk(BIOS_EMERG, "To fix this, set ops_pci_bus in dts\n"); die("loop due to insufficient dts"); }
Modified: coreboot-v3/device/root_device.c =================================================================== --- coreboot-v3/device/root_device.c 2008-12-30 07:02:52 UTC (rev 1088) +++ coreboot-v3/device/root_device.c 2008-12-31 19:43:34 UTC (rev 1089) @@ -35,13 +35,7 @@ */ void root_dev_read_resources(struct device *root) { - void read_resources(struct bus *bus); - void show_all_devs_resources(void); - - read_resources(&root->link[0]); - - printk(BIOS_DEBUG, "%s: Done allocating\n", __FUNCTION__); - show_all_devs_resources(); + printk(BIOS_DEBUG, "This shouldn't be called!\n"); }
/** @@ -52,7 +46,7 @@ */ void root_dev_set_resources(struct device *root) { - phase4_assign_resources(&root->link[0]); + printk(BIOS_DEBUG, "This shouldn't be called!\n"); }
/** @@ -193,6 +187,7 @@ * mainboard directory. */ struct device_operations default_dev_ops_root = { + .id = {.type = DEVICE_ID_ROOT}, .phase3_scan = root_dev_scan_bus, .phase4_read_resources = root_dev_read_resources, .phase4_set_resources = root_dev_set_resources,
Modified: coreboot-v3/include/device/device.h =================================================================== --- coreboot-v3/include/device/device.h 2008-12-30 07:02:52 UTC (rev 1088) +++ coreboot-v3/include/device/device.h 2008-12-31 19:43:34 UTC (rev 1089) @@ -199,12 +199,11 @@ u16 subsystem_vendor; u16 subsystem_device;
- unsigned int class; /* 3 bytes: (base,sub,prog-if) */ - unsigned int hdr_type; /* PCI header type */ - unsigned int enabled:1; /* set if we should enable the device */ - unsigned int have_resources:1; /* Set if we have read the devices resources */ - unsigned int on_mainboard:1; - unsigned long rom_address; + unsigned int class; /* 3 bytes: (base,sub,prog-if) */ + unsigned int hdr_type; /* PCI header type */ + unsigned int enabled : 1; /* set if we should enable the device */ + unsigned int on_mainboard : 1; + unsigned long rom_address;
u8 command;
@@ -239,9 +238,7 @@ /* Generic device helper functions */ int reset_bus(struct bus *bus); unsigned int scan_bus(struct device *bus, unsigned int max); -void compute_allocate_resource(struct bus *bus, struct resource *bridge, - unsigned long type_mask, unsigned long type); -void assign_resources(struct bus *bus); +//void assign_resources(struct bus *bus); void enable_resources(struct device *dev); void enumerate_static_device(void); void enumerate_static_devices(void); @@ -267,13 +264,10 @@ const struct device_operations *constructor); void show_all_devs(int debug_level, const char *msg); void show_all_devs_tree(int debug_level, const char *msg); +void show_all_devs(int debug_level, const char *msg); +void show_all_devs_tree(int debug_level, const char *msg); +void print_resource_tree(const struct device * const dev, int debug_level, const char* msg);
-/* Rounding for boundaries. - * Due to some chip bugs, go ahead and round IO to 16 - */ -#define DEVICE_IO_ALIGN 16 -#define DEVICE_MEM_ALIGN 4096 - resource_t align_up(resource_t val, unsigned long gran); resource_t align_down(resource_t val, unsigned long gran);
@@ -296,7 +290,7 @@ void dev_root_phase5(void); void dev_phase6(void);
-void phase4_assign_resources(struct bus *bus); +void phase4_set_resources(struct bus *bus); unsigned int dev_phase3(struct device *bus, unsigned int max); void dev_phase5(struct device *dev);
Modified: coreboot-v3/include/device/resource.h =================================================================== --- coreboot-v3/include/device/resource.h 2008-12-30 07:02:52 UTC (rev 1088) +++ coreboot-v3/include/device/resource.h 2008-12-31 19:43:34 UTC (rev 1089) @@ -36,6 +36,7 @@ #define IORESOURCE_SUBTRACTIVE 0x00040000 /* This resource filters all of the unclaimed transactions * to the bus below. */ +#define IORESOURCE_BRIDGE 0x00080000 /* The IO resource has a bus below it. */ #define IORESOURCE_STORED 0x20000000 /* The IO resource assignment has been stored in the device */ #define IORESOURCE_ASSIGNED 0x40000000 /* An IO resource that has been assigned a value */ #define IORESOURCE_FIXED 0x80000000 /* An IO resource the allocator must not change */