Nico Huber has uploaded this change for review.

View Change

[WIP] device/resource_allocator_v4.5: Directly recurse in pass 2 for each bridge resource

Change-Id: I9b31c7242f0cdf747db48203243f0e9ba6643bf4
Signed-off-by: Nico Huber <nico.h@gmx.de>
---
M src/device/resource_allocator_v4.5.c
1 file changed, 40 insertions(+), 61 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/41959/1
diff --git a/src/device/resource_allocator_v4.5.c b/src/device/resource_allocator_v4.5.c
index 34e9fdd..96a6503 100644
--- a/src/device/resource_allocator_v4.5.c
+++ b/src/device/resource_allocator_v4.5.c
@@ -394,6 +394,43 @@
}

/*
+ * Pass 2 of the resource allocator at the bridge level loops through
+ * all the resources for the bridge and assigns all the base addresses
+ * of its children's resources of the same type. update_bridge_resource()
+ * of pass 1 pre-calculated the offsets of these bases inside the bridge
+ * resource. Now that the bridge resource is allocated, all we have to
+ * do is to add its final base to these offsets.
+ *
+ * Once allocation at the current bridge is complete, resource allocator
+ * continues walking down the downstream bridges until it hits the leaf
+ * devices.
+ */
+static void allocate_bridge_resources(const struct device *bridge, struct resource *bridge_res)
+{
+ void assign_resource_cb(void *param, struct device *dev, struct resource *res)
+ {
+ /* We have to filter the same resources as update_bridge_resource(). */
+ if (!res->size || !res->limit)
+ return;
+
+ assign_resource(res, *(const resource_t *)param + res->base, dev);
+
+ if (res->flags & IORESOURCE_BRIDGE)
+ allocate_bridge_resources(dev, res);
+ }
+
+ const unsigned long type_mask = IORESOURCE_TYPE_MASK | IORESOURCE_PREFETCH;
+ const unsigned long type = bridge_res->flags & type_mask;
+ struct bus *const bus = bridge->link_list;
+
+ if (!bus)
+ return;
+
+ /* Run assign_resource_cb() for all downstream resources of the same type. */
+ search_bus_resources(bus, type_mask, type, assign_resource_cb, &bridge_res->base);
+}
+
+/*
* This is where the actual allocation of resources happens during
* pass 2. We construct a list of memory ranges corresponding to the
* resource of a given type, then look for the biggest unallocated
@@ -433,63 +470,15 @@
}

assign_resource(res, base, dev);
+
+ if (res->flags & IORESOURCE_BRIDGE)
+ allocate_bridge_resources(dev, res);
}

cleanup_resource_ranges(domain, &ranges, domain_res);
}

/*
- * Pass 2 of the resource allocator at the bridge level loops through
- * all the resources for the bridge and assigns all the base addresses
- * of its children's resources of the same type. update_bridge_resource()
- * of pass 1 pre-calculated the offsets of these bases inside the bridge
- * resource. Now that the bridge resource is allocated, all we have to
- * do is to add its final base to these offsets.
- *
- * Once allocation at the current bridge is complete, resource allocator
- * continues walking down the downstream bridges until it hits the leaf
- * devices.
- */
-static void allocate_bridge_resources(const struct device *bridge)
-{
- void assign_resource_cb(void *param, struct device *dev, struct resource *res)
- {
- /* We have to filter the same resources as update_bridge_resource(). */
- if (!res->size || !res->limit)
- return;
-
- assign_resource(res, *(const resource_t *)param + res->base, dev);
- }
-
- const unsigned long type_mask = IORESOURCE_TYPE_MASK | IORESOURCE_PREFETCH;
- struct bus *const bus = bridge->link_list;
- struct resource *res;
- struct device *child;
-
- for (res = bridge->resource_list; res != NULL; res = res->next) {
- if (!res->size)
- continue;
-
- if (!(res->flags & IORESOURCE_BRIDGE))
- continue;
-
- if (!(res->flags & IORESOURCE_ASSIGNED))
- continue;
-
- /* Run assign_resource_cb() for all downstream resources of the same type. */
- search_bus_resources(bus, type_mask, res->flags & type_mask,
- assign_resource_cb, &res->base);
- }
-
- for (child = bus->children; child != NULL; child = child->sibling) {
- if (!dev_has_children(child))
- continue;
-
- allocate_bridge_resources(child);
- }
-}
-
-/*
* Pass 2 of resource allocator begins at the domain level. Every domain
* has two types of resources - io and mem. For each of these resources,
* this function creates a list of memory ranges that can be used for
@@ -504,8 +493,6 @@
*/
static void allocate_domain_resources(const struct device *domain)
{
- struct device *child;
-
/* Resource type I/O */
allocate_toplevel_resources(domain, IORESOURCE_IO);

@@ -516,14 +503,6 @@
* on the biggest resource requirement.
*/
allocate_toplevel_resources(domain, IORESOURCE_MEM);
-
- for (child = domain->link_list->children; child; child = child->sibling) {
- if (!dev_has_children(child))
- continue;
-
- /* Continue allocation for all downstream bridges. */
- allocate_bridge_resources(child);
- }
}

/*

To view, visit change 41959. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I9b31c7242f0cdf747db48203243f0e9ba6643bf4
Gerrit-Change-Number: 41959
Gerrit-PatchSet: 1
Gerrit-Owner: Nico Huber <nico.h@gmx.de>
Gerrit-MessageType: newchange