Index: cbv2/src/devices/device.c
===================================================================
--- cbv2.orig/src/devices/device.c
+++ cbv2/src/devices/device.c
@@ -128,7 +128,7 @@ static resource_t round(resource_t val, 
 /** Read the resources on all devices of a given bus.
  * @param bus bus to read the resources on.
  */
-static void read_resources(struct bus *bus)
+void read_resources(struct bus *bus)
 {
 	struct device *curdev;
 
@@ -137,11 +137,7 @@ static void read_resources(struct bus *b
 
 	/* Walk through all devices and find which resources they need. */
 	for (curdev = bus->children; curdev; curdev = curdev->sibling) {
-		unsigned links;
 		int i;
-		if (curdev->have_resources) {
-			continue;
-		}
 		if (!curdev->enabled) {
 			continue;
 		}
@@ -151,26 +147,10 @@ static void read_resources(struct bus *b
 			continue;
 		}
 		curdev->ops->read_resources(curdev);
-		curdev->have_resources = 1;
-		/* Read in subtractive resources behind the current device */
-		links = 0;
-		for (i = 0; i < curdev->resources; i++) {
-			struct resource *resource;
-			unsigned link;
-			resource = &curdev->resource[i];
-			if (!(resource->flags & IORESOURCE_SUBTRACTIVE))
-				continue;
-			link = IOINDEX_SUBTRACTIVE_LINK(resource->index);
-			if (link > MAX_LINKS) {
-				printk_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_spew("%s read_resources bus %d link: %d done\n",
 		    dev_path(bus->dev), bus->secondary, bus->link);
@@ -288,9 +268,6 @@ void compute_allocate_resource(struct bu
 		min_align = log2(DEVICE_MEM_ALIGN);
 	}
 
-	/* Make certain I have read in all of the resources */
-	read_resources(bus);
-
 	/* Remember we haven't found anything yet. */
 	resource = NULL;
 
@@ -386,6 +363,16 @@ void compute_allocate_resource(struct bu
 		    base, bridge->size, bridge->align, bridge->gran);
 }
 
+#if CONFIG_PCI_64BIT_PREF_MEM == 1
+	#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)
+
 #if CONFIG_CONSOLE_VGA == 1
 device_t vga_pri = 0;
 static void allocate_vga_resource(void)
@@ -642,56 +629,103 @@ void dev_enumerate(void)
  */
 void dev_configure(void)
 {
-	struct resource *io, *mem;
+	struct resource *res;
 	struct device *root;
+	struct device *child;
+	int i;
 
 	printk_info("Allocating resources...\n");
 
 	root = &dev_root;
 
-	if (!root->ops || !root->ops->read_resources) {
-		printk_err("dev_root missing read_resources\n");
-		return;
-	}
-	if (!root->ops || !root->ops->set_resources) {
-		printk_err("dev_root missing set_resources\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.
+	 */
+
+	/* Read the resources for the entire tree. */
 
 	printk_info("Reading resources...\n");
-	root->ops->read_resources(root);
+	read_resources(&root->link[0]);
 	printk_info("Done reading resources.\n");
 
 	print_resource_tree(root, BIOS_DEBUG, "After reading.");
+	/* 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_allocate_resource(&child->link[0],
+					       res, MEM_MASK, PREF_TYPE);
+				continue;
+			}
+			if (res->flags & IORESOURCE_MEM) {
+				compute_allocate_resource(&child->link[0],
+					       res, MEM_MASK, MEM_TYPE);
+				continue;
+			}
+			if (res->flags & IORESOURCE_IO) {
+				compute_allocate_resource(&child->link[0],
+					       res, IO_MASK, IO_TYPE);
+				continue;
+			}
+		}
+	}
 
-	/* Get the resources */
-	io = &root->resource[0];
-	mem = &root->resource[1];
-	/* Make certain the io devices are allocated somewhere safe. */
-	io->base = DEVICE_IO_START;
-	io->flags |= IORESOURCE_ASSIGNED;
-	io->flags &= ~IORESOURCE_STORED;
-	/* Now reallocate the pci resources memory with the
-	 * highest addresses I can manage.
+	/* Now we need to adjust the resources. The issue is that mem grows
+	 * downward. Reallocate the MEM resources with the highest addresses
+	 * I can manage.
 	 */
-	mem->base = resource_max(&root->resource[1]);
-	mem->flags |= IORESOURCE_ASSIGNED;
-	mem->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);
+		}
+	}
 
 #if CONFIG_CONSOLE_VGA == 1
-	/* Allocate the VGA I/O resource.. */
+	/* Allocate the VGA I/O resource. */
 	allocate_vga_resource();
 	print_resource_tree(root, BIOS_DEBUG, "After VGA.");
 #endif
 
 	/* Store the computed resource allocations into device registers ... */
 	printk_info("Setting resources...\n");
-	root->ops->set_resources(root);
+	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_allocate_resource(&child->link[0],
+					       res, MEM_MASK, PREF_TYPE);
+				continue;
+			}
+			if (res->flags & IORESOURCE_MEM) {
+				compute_allocate_resource(&child->link[0],
+					       res, MEM_MASK, MEM_TYPE);
+				continue;
+			}
+			if (res->flags & IORESOURCE_IO) {
+				compute_allocate_resource(&child->link[0],
+					       res, IO_MASK, IO_TYPE);
+				continue;
+			}
+		}
+	}
+	assign_resources(&root->link[0]);
 	printk_info("Done setting resources.\n");
-#if 0
-	mem->flags |= IORESOURCE_STORED;
-	report_resource_stored(root, mem, "");
-#endif
 	print_resource_tree(root, BIOS_DEBUG, "After assigning values.");
 
 	printk_info("Done allocating resources.\n");
Index: cbv2/src/devices/device_util.c
===================================================================
--- cbv2.orig/src/devices/device_util.c
+++ cbv2/src/devices/device_util.c
@@ -486,7 +486,7 @@ void search_bus_resources(struct bus *bu
 	for(curdev = bus->children; curdev; curdev = curdev->sibling) {
 		int i;
 		/* Ignore disabled devices */
-		if (!curdev->have_resources) continue;
+		if (!curdev->enabled) 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 */
@@ -513,7 +513,7 @@ void search_global_resources(
 	for(curdev = all_devices; curdev; curdev = curdev->next) {
 		int i;
 		/* Ignore disabled devices */
-		if (!curdev->have_resources) continue;
+		if (!curdev->enabled) 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 */
Index: cbv2/src/include/device/device.h
===================================================================
--- cbv2.orig/src/include/device/device.h
+++ cbv2/src/include/device/device.h
@@ -69,7 +69,6 @@ struct device {
 	unsigned int	hdr_type;	/* PCI header type */
 	unsigned int    enabled : 1;	/* set if we should enable the device */
 	unsigned int    initialized : 1; /* set if we have initialized the device */
-	unsigned int    have_resources : 1; /* Set if we have read the devices resources */
 	unsigned int    on_mainboard : 1;
 	unsigned long   rom_address;
 
Index: cbv2/src/southbridge/amd/sb600/sb600_lpc.c
===================================================================
--- cbv2.orig/src/southbridge/amd/sb600/sb600_lpc.c
+++ cbv2/src/southbridge/amd/sb600/sb600_lpc.c
@@ -111,7 +111,7 @@ static void sb600_lpc_enable_childrens_r
 		for (child = dev->link[link].children; child;
 		     child = child->sibling) {
 			enable_resources(child);
-			if (child->have_resources
+			if (child->enabled
 			    && (child->path.type == DEVICE_PATH_PNP)) {
 				for (i = 0; i < child->resources; i++) {
 					struct resource *res;
Index: cbv2/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c
===================================================================
--- cbv2.orig/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c
+++ cbv2/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c
@@ -69,7 +69,7 @@ static void bcm5785_lpc_enable_childrens
                 device_t child;
                 for (child = dev->link[link].children; child; child = child->sibling) {
                         enable_resources(child);
-			if(child->have_resources && (child->path.type == DEVICE_PATH_PNP)) {
+			if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
 				for(i=0;i<child->resources;i++) {
 					struct resource *res;
 			                unsigned long base, end; // don't need long long
Index: cbv2/src/southbridge/nvidia/ck804/ck804_lpc.c
===================================================================
--- cbv2.orig/src/southbridge/nvidia/ck804/ck804_lpc.c
+++ cbv2/src/southbridge/nvidia/ck804/ck804_lpc.c
@@ -308,7 +308,7 @@ static void ck804_lpc_enable_childrens_r
 		device_t child;
 		for (child = dev->link[link].children; child; child = child->sibling) {
 			enable_resources(child);
-			if (child->have_resources && (child->path.type == DEVICE_PATH_PNP)) {
+			if (child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
 				for (i = 0; i < child->resources; i++) {
 					struct resource *res;
 					unsigned long base, end;	// don't need long long
Index: cbv2/src/southbridge/nvidia/mcp55/mcp55_lpc.c
===================================================================
--- cbv2.orig/src/southbridge/nvidia/mcp55/mcp55_lpc.c
+++ cbv2/src/southbridge/nvidia/mcp55/mcp55_lpc.c
@@ -288,7 +288,7 @@ static void mcp55_lpc_enable_childrens_r
 		device_t child;
 		for (child = dev->link[link].children; child; child = child->sibling) {
 			enable_resources(child);
-			if(child->have_resources && (child->path.type == DEVICE_PATH_PNP)) {
+			if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
 				for(i=0;i<child->resources;i++) {
 					struct resource *res;
 					unsigned long base, end; // don't need long long
Index: cbv2/src/southbridge/sis/sis966/sis966_lpc.c
===================================================================
--- cbv2.orig/src/southbridge/sis/sis966/sis966_lpc.c
+++ cbv2/src/southbridge/sis/sis966/sis966_lpc.c
@@ -274,7 +274,7 @@ static void sis966_lpc_enable_childrens_
 		device_t child;
 		for (child = dev->link[link].children; child; child = child->sibling) {
 			enable_resources(child);
-			if(child->have_resources && (child->path.type == DEVICE_PATH_PNP)) {
+			if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
 				for(i=0;i<child->resources;i++) {
 					struct resource *res;
 					unsigned long base, end; // don't need long long
