Index: cbv2/src/devices/device.c
===================================================================
--- cbv2.orig/src/devices/device.c
+++ cbv2/src/devices/device.c
@@ -234,59 +234,68 @@ static struct device *largest_resource(s
  *   the allocator. Also this allows handling of other types of bridges.
  *
  */
-void compute_allocate_resource(struct bus *bus,
-			       struct resource *bridge,
-			       unsigned long type_mask, unsigned long type)
+void compute_resources(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 = round(bridge->base, bridge->align);
 
-	printk_debug("%s compute_allocate_resource %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
-	 * but resource type specific.
-	 */
-	if (bridge->flags & IORESOURCE_IO) {
-		min_align = log2(DEVICE_IO_ALIGN);
-	}
-	if (bridge->flags & IORESOURCE_MEM) {
-		min_align = log2(DEVICE_MEM_ALIGN);
+	printk_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);
+
+	/* 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++) {
+			unsigned link;
+			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.
+			 */
+			link = IOINDEX_LINK(child_bridge->index);
+			compute_resources(&dev->link[link], child_bridge,
+					  type_mask | IORESOURCE_PREFETCH,
+					  type | (child_bridge->flags &
+						  IORESOURCE_PREFETCH));
+		}
 	}
 
 	/* 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))) {
-		/* 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 */
-		align = resource->align;
-		if (align < min_align) {
-			align = min_align;
-		}
 
-		/* Propagate the resource alignment to the bridge register. */
-		if (align > bridge->align) {
-			bridge->align = align;
+		/* Size 0 resources can be skipped. */
+		if (!resource->size) {
+			continue;
 		}
 
-		if (resource->flags & IORESOURCE_FIXED) {
-			continue;
+		/* Propagate the resource alignment to the bridge resource. */
+		if (resource->align > bridge->align) {
+			bridge->align = resource->align;
 		}
 
 		/* Propagate the resource limit to the bridge register. */
@@ -319,30 +328,18 @@ void compute_allocate_resource(struct bu
 				base = 0x3e0;
 			}
 		}
-
-		if ((round(base, align) + resource->size - 1) <=
-		    resource->limit) {
-			/* base must be aligned to size */
-			base = round(base, align);
-			resource->base = base;
-			resource->flags |= IORESOURCE_ASSIGNED;
-			resource->flags &= ~IORESOURCE_STORED;
-			base += resource->size;
-
-			printk_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");
-		}
-#if CONFIG_PCIE_CONFIGSPACE_HOLE
-#warning Handle PCIe hole differently...
-		if (base >= 0xf0000000 && base < 0xf4000000) {
-			base = 0xf4000000;
-		}
-#endif
+		/* Base must be aligned. */
+		base = round(base, resource->align);
+		resource->base = base;
+		base += resource->size;
+
+		printk_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");
 	}
 	/* A pci bridge resource does not need to be a power
 	 * of two size, but it does have a minimum granularity.
@@ -350,13 +347,186 @@ void compute_allocate_resource(struct bu
 	 * know not to place something else at an address postitively
 	 * decoded by the bridge.
 	 */
-	bridge->size = round(base, bridge->gran) - bridge->base;
+	bridge->size = round(base, bridge->gran) -
+		       round(bridge->base, bridge->align);
 
-	printk_spew("%s compute_allocate_resource %s: base: %08Lx size: %08Lx align: %d gran: %d done\n",
-		    dev_path(bus->dev),
+	printk_spew("%s %s_%s: base: %llx size: %llx align: %d gran: %d limit: %llx done\n",
+		    dev_path(bus->dev), __func__,
 		    (bridge->flags & IORESOURCE_IO) ? "io" :
 		     (bridge->flags & IORESOURCE_PREFETCH) ?  "prefmem" : "mem",
-		    base, bridge->size, bridge->align, bridge->gran);
+		    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 allocate_resources(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_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))) {
+
+		/* Propagate the bridge limit to the resource register. */
+		if (resource->limit > bridge->limit) {
+			resource->limit = bridge->limit;
+		}
+
+		/* Size 0 resources can be skipped. */
+		if (!resource->size) {
+			/* Set the base to limit so it doesn't confuse tolm. */
+			resource->base = resource->limit;
+			resource->flags |= IORESOURCE_ASSIGNED;
+			continue;
+		}
+
+		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;
+			}
+		}
+
+		if ((round(base, resource->align) + resource->size - 1) <=
+		    resource->limit) {
+			/* Base must be aligned. */
+			base = round(base, resource->align);
+			resource->base = base;
+			resource->flags |= IORESOURCE_ASSIGNED;
+			resource->flags &= ~IORESOURCE_STORED;
+			base += resource->size;
+		} else {
+			printk_err("!! Resource didn't fit !!\n");
+			printk_err("   aligned base %llx size %llx limit %llx\n",
+			       round(base, resource->align), resource->size,
+			       resource->limit);
+			printk_err("   %llx needs to be <= %llx (limit)\n",
+			       (round(base, resource->align) +
+				resource->size) - 1, resource->limit);
+			printk_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_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->flags |= IORESOURCE_ASSIGNED;
+
+	printk_spew("%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, allocate_resources. */
+	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++) {
+			unsigned link;
+			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.
+			 */
+			link = IOINDEX_LINK(child_bridge->index);
+			allocate_resources(&dev->link[link], child_bridge,
+					   type_mask | IORESOURCE_PREFETCH,
+					   type | (child_bridge->flags &
+						   IORESOURCE_PREFETCH));
+		}
+	}
 }
 
 #if CONFIG_PCI_64BIT_PREF_MEM == 1
@@ -776,17 +946,17 @@ void dev_configure(void)
 			if (res->flags & IORESOURCE_FIXED)
 				continue;
 			if (res->flags & IORESOURCE_PREFETCH) {
-				compute_allocate_resource(&child->link[0],
+				compute_resources(&child->link[0],
 					       res, MEM_MASK, PREF_TYPE);
 				continue;
 			}
 			if (res->flags & IORESOURCE_MEM) {
-				compute_allocate_resource(&child->link[0],
+				compute_resources(&child->link[0],
 					       res, MEM_MASK, MEM_TYPE);
 				continue;
 			}
 			if (res->flags & IORESOURCE_IO) {
-				compute_allocate_resource(&child->link[0],
+				compute_resources(&child->link[0],
 					       res, IO_MASK, IO_TYPE);
 				continue;
 			}
@@ -829,17 +999,17 @@ void dev_configure(void)
 			if (res->flags & IORESOURCE_FIXED)
 				continue;
 			if (res->flags & IORESOURCE_PREFETCH) {
-				compute_allocate_resource(&child->link[0],
+				allocate_resources(&child->link[0],
 					       res, MEM_MASK, PREF_TYPE);
 				continue;
 			}
 			if (res->flags & IORESOURCE_MEM) {
-				compute_allocate_resource(&child->link[0],
+				allocate_resources(&child->link[0],
 					       res, MEM_MASK, MEM_TYPE);
 				continue;
 			}
 			if (res->flags & IORESOURCE_IO) {
-				compute_allocate_resource(&child->link[0],
+				allocate_resources(&child->link[0],
 					       res, IO_MASK, IO_TYPE);
 				continue;
 			}
Index: cbv2/src/include/device/resource.h
===================================================================
--- cbv2.orig/src/include/device/resource.h
+++ cbv2/src/include/device/resource.h
@@ -19,6 +19,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 */
Index: cbv2/src/devices/pci_device.c
===================================================================
--- cbv2.orig/src/devices/pci_device.c
+++ cbv2/src/devices/pci_device.c
@@ -375,7 +375,8 @@ static void pci_record_bridge_resource(s
 		resource->gran = gran;
 		resource->align = gran;
 		resource->limit = moving | (step - 1);
-		resource->flags = type | IORESOURCE_PCI_BRIDGE;
+		resource->flags = type | IORESOURCE_PCI_BRIDGE |
+				  IORESOURCE_BRIDGE;
 	}
 	return;
 }
Index: cbv2/src/northbridge/amd/amdk8/northbridge.c
===================================================================
--- cbv2.orig/src/northbridge/amd/amdk8/northbridge.c
+++ cbv2/src/northbridge/amd/amdk8/northbridge.c
@@ -379,7 +379,7 @@ static void amdk8_link_read_bases(device
 		resource->align = log2(HT_IO_HOST_ALIGN);
 		resource->gran  = log2(HT_IO_HOST_ALIGN);
 		resource->limit = 0xffffUL;
-		resource->flags = IORESOURCE_IO;
+		resource->flags = IORESOURCE_IO | IORESOURCE_BRIDGE;
 	}
 
 	/* Initialize the prefetchable memory constraints on the current bus */
@@ -391,6 +391,9 @@ static void amdk8_link_read_bases(device
 		resource->gran  = log2(HT_MEM_HOST_ALIGN);
 		resource->limit = 0xffffffffffULL;
 		resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+#ifdef CONFIG_PCI_64BIT_PREF_MEM
+		resource->flags |= IORESOURCE_BRIDGE;
+#endif
 	}
 
 	/* Initialize the memory constraints on the current bus */
@@ -400,8 +403,8 @@ static void amdk8_link_read_bases(device
 		resource->size  = 0;
 		resource->align = log2(HT_MEM_HOST_ALIGN);
 		resource->gran  = log2(HT_MEM_HOST_ALIGN);
-		resource->limit = 0xffffffffffULL;
-		resource->flags = IORESOURCE_MEM;
+		resource->limit = 0xffffffffULL;
+		resource->flags = IORESOURCE_MEM | IORESOURCE_BRIDGE;
 	}
 }
 
