[coreboot-gerrit] New patch to review for coreboot: 8f1f6f7 resource: Apply constraints directly on domain resources

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Tue Mar 24 05:29:55 CET 2015


Kyösti Mälkki (kyosti.malkki at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8893

-gerrit

commit 8f1f6f7bad1c65d4a6a8c7baa63b08c0ff89a3c1
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Mon Mar 23 19:17:43 2015 +0200

    resource: Apply constraints directly on domain resources
    
    There is no need to negotiate the resource limits via intermediate
    limits structure. Recursively walk the devicetree for each type of
    resource and apply the constraints directly on the domain path.
    
    Change-Id: Ib4facc9cafa7f0cb12416a89618c7a20e05bc3d1
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
 src/device/device.c | 91 +++++++++++++----------------------------------------
 1 file changed, 21 insertions(+), 70 deletions(-)

diff --git a/src/device/device.c b/src/device/device.c
index 33869d0..3aa4875 100644
--- a/src/device/device.c
+++ b/src/device/device.c
@@ -295,6 +295,14 @@ static struct device *largest_resource(struct bus *bus,
 	return state.result_dev;
 }
 
+#define IORESOURCE_TYPE  (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH)
+
+static int resource_match(struct resource *res, struct resource *lim)
+{
+	u32 mask = (IORESOURCE_TYPE & ~IORESOURCE_PREFETCH);
+	return (res->flags & mask) == (lim->flags & mask);
+}
+
 /**
  * This function is the guts of the resource allocator.
  *
@@ -591,44 +599,20 @@ static void allocate_resources(struct bus *bus, struct resource *bridge,
 	}
 }
 
-#define IORESOURCE_TYPE  (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH)
-
-static int resource_is(struct resource *res, u32 type)
-{
-	u32 mask = (IORESOURCE_TYPE & ~IORESOURCE_PREFETCH);
-	return (res->flags & mask) == type;
-}
-
-struct constraints {
-	struct resource pref, io, mem;
-};
-
-static struct resource * resource_limit(struct constraints *limits, struct resource *res)
-{
-	struct resource *lim = NULL;
-
-	/* PREFETCH, MEM, or I/O - skip any others. */
-	if (resource_is(res, IORESOURCE_MEM))
-		lim = &limits->mem;
-	else if (resource_is(res, IORESOURCE_IO))
-		lim = &limits->io;
-	else if (resource_is(res, IORESOURCE_MEM | IORESOURCE_PREFETCH))
-		lim = &limits->pref;
-
-	return lim;
-}
-
-static void constrain_resources(struct device *dev, struct constraints* limits)
+static void constrain_resources(struct device *dev, struct resource *lim)
 {
 	struct device *child;
 	struct resource *res;
-	struct resource *lim;
 	struct bus *link;
 
 	/* Constrain limits based on the fixed resources of this device. */
 	for (res = dev->resource_list; res; res = res->next) {
 		if (!(res->flags & IORESOURCE_FIXED))
 			continue;
+
+		if (!resource_match(res, lim))
+			continue;
+
 		if (!res->size) {
 			/* It makes no sense to have 0-sized, fixed resources.*/
 			printk(BIOS_ERR, "skipping %s@%lx fixed resource, "
@@ -636,10 +620,6 @@ static void constrain_resources(struct device *dev, struct constraints* limits)
 			continue;
 		}
 
-		lim = resource_limit(limits, res);
-		if (!lim)
-			continue;
-
 		/*
 		 * Is it a fixed resource outside the current known region?
 		 * If so, we don't have to consider it - it will be handled
@@ -669,67 +649,38 @@ static void constrain_resources(struct device *dev, struct constraints* limits)
 	for (link = dev->link_list; link; link = link->next) {
 		for (child = link->children; child; child = child->sibling) {
 			if (child->enabled)
-				constrain_resources(child, limits);
+				constrain_resources(child, lim);
 		}
 	}
 }
 
 static void avoid_fixed_resources(struct device *dev)
 {
-	struct constraints limits;
 	struct resource *res;
-	struct resource *lim;
+	resource_t mem_limit = 0xffffffffULL;
 
 	printk(BIOS_SPEW, "%s: %s\n", __func__, dev_path(dev));
 
-	/* 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 (res = dev->resource_list; res; res = res->next) {
 		if ((res->flags & IORESOURCE_FIXED))
 			continue;
 
-		lim = resource_limit(&limits, res);
-		if (!lim)
-			continue;
-
-		if (res->base > lim->base)
-			lim->base = res->base;
-		if  (res->limit < lim->limit)
-			lim->limit = res->limit;
+		/* Place MEM resources one after other. */
+		if ((res->flags & IORESOURCE_MEM) && (res->limit > mem_limit))
+			res->limit = mem_limit;
 
 		printk(BIOS_SPEW, "%s:@%s %02lx base %08llx limit %08llx\n",
 			__func__, dev_path(dev), res->index, res->base, 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 (res = dev->resource_list; res; res = res->next) {
-		if ((res->flags & IORESOURCE_FIXED))
-			continue;
 
-		lim = resource_limit(&limits, res);
-		if (!lim)
-			continue;
+		/* Look through the tree for fixed resources and update the limits. */
+		constrain_resources(dev, res);
 
-		/* Is the resource outside the limits? */
-		if (lim->base > res->base)
-			res->base = lim->base;
-		if (res->limit > lim->limit)
-			res->limit = lim->limit;
 
 		/* MEM resources need to start at the highest address manageable. */
 		if (res->flags & IORESOURCE_MEM) {
 			res->base = resource_max(res);
-			lim->limit = res->base - 1;
+			mem_limit = res->base - 1;
 		}
 
 		printk(BIOS_SPEW, "%s:@%s %02lx base %08llx limit %08llx\n",



More information about the coreboot-gerrit mailing list