These patches depend on the new resource allocator.  Abuild tested and boot
tested on SimNow, qemu, s2892, and s2895.

k8_north.diff:

change FX_DEVS to MAX_FX_DEVS
introduce fx_devs for the number of nodes
only call get_fx_devs if fx_devs == 0
change i to node_id and ii to i
remove shadowed variables
take out continue statements in loops go to fx_devs

k8_resources.diff:

combine find_iopair and find_mempair
return the register number instead of a resource
don't allocate resources until the allocate stage
simplify amdk8_create_vga_resource and move it to read resources
    (It could be moved above read resources, but I was minimizing changes)
allocate resources in amdk8_set_resources

    For each resource:
        See if there's already a resource for that link and node
        Use it if there is
        Otherwise allocate a new one
    Compact resources to get rid of extra ones

in amdk8_domain_read_resources, store the base and limit in the temporary
resources so it's easier to debug.

tolm_test needed to be changed so it didn't find the VGA resource
It could probably be changed to be > 0x100000 since any system should have
1M
of RAM and this is trying to find the bottom of PCI space.

tolm_test should be factored out of all northbridges

In device.c, rename allocate_vga_resource to set_vga_bridge_bits and move it
to
the beginning of resource allocation.

Signed-off-by: Myles Watson <[email protected]>

Thanks,
Myles
Index: cbv2/src/northbridge/amd/amdk8/northbridge.c
===================================================================
--- cbv2.orig/src/northbridge/amd/amdk8/northbridge.c
+++ cbv2/src/northbridge/amd/amdk8/northbridge.c
@@ -36,56 +36,38 @@
 
 struct amdk8_sysconf_t sysconf;
 
-#define FX_DEVS 8
-static device_t __f0_dev[FX_DEVS];
-static device_t __f1_dev[FX_DEVS];
-
-#if 0
-static void debug_fx_devs(void)
-{
-	int i;
-	for(i = 0; i < FX_DEVS; i++) {
-		device_t dev;
-		dev = __f0_dev[i];
-		if (dev) {
-			printk_debug("__f0_dev[%d]: %s bus: %p\n",
-				i, dev_path(dev), dev->bus);
-		}
-		dev = __f1_dev[i];
-		if (dev) {
-			printk_debug("__f1_dev[%d]: %s bus: %p\n",
-				i, dev_path(dev), dev->bus);
-		}
-	}
-}
-#endif
+#define MAX_FX_DEVS 8
+static device_t __f0_dev[MAX_FX_DEVS];
+static device_t __f1_dev[MAX_FX_DEVS];
+static unsigned fx_devs=0;
 
 static void get_fx_devs(void)
 {
 	int i;
-	if (__f1_dev[0]) {
-		return;
-	}
-	for(i = 0; i < FX_DEVS; i++) {
+	for(i = 0; i < MAX_FX_DEVS; i++) {
 		__f0_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 0));
 		__f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1));
+		if (__f0_dev[i] != NULL && __f1_dev[i] != NULL)
+			fx_devs = i+1;
 	}
-	if (!__f1_dev[0]) {
-		die("Cannot find 0:0x18.1\n");
+	if (__f1_dev[0] == NULL || __f0_dev[0] == NULL || fx_devs == 0) {
+		die("Cannot find 0:0x18.[0|1]\n");
 	}
 }
 
 static uint32_t f1_read_config32(unsigned reg)
 {
-	get_fx_devs();
+	if ( fx_devs == 0)
+		get_fx_devs();
 	return pci_read_config32(__f1_dev[0], reg);
 }
 
 static void f1_write_config32(unsigned reg, uint32_t value)
 {
 	int i;
-	get_fx_devs();
-	for(i = 0; i < FX_DEVS; i++) {
+	if ( fx_devs == 0)
+		get_fx_devs();
+	for(i = 0; i < fx_devs; i++) {
 		device_t dev;
 		dev = __f1_dev[i];
 		if (dev && dev->enabled) {
@@ -291,7 +273,7 @@ static int reg_useable(unsigned reg,
 	unsigned nodeid, link=0;
 	int result;
 	res = 0;
-	for(nodeid = 0; !res && (nodeid < FX_DEVS); nodeid++) {
+	for(nodeid = 0; !res && (nodeid < fx_devs); nodeid++) {
 		device_t dev;
 		dev = __f0_dev[nodeid];
 		if (!dev)
@@ -634,7 +616,6 @@ struct chip_operations northbridge_amd_a
 
 static void amdk8_domain_read_resources(device_t dev)
 {
-	struct resource *resource;
 	unsigned reg;
 
 	/* Find the already assigned resource pairs */
@@ -652,10 +633,10 @@ static void amdk8_domain_read_resources(
 			reg_dev = __f0_dev[nodeid];
 			if (reg_dev) {
 				/* Reserve the resource  */
-				struct resource *reg_resource;
-				reg_resource = new_resource(reg_dev, IOINDEX(0x100 + reg, link));
-				if (reg_resource) {
-					reg_resource->flags = 1;
+				struct resource *res;
+				res = new_resource(reg_dev, IOINDEX(0x100 + reg, link));
+				if (res) {
+					res->flags = 1;
 				}
 			}
 		}
@@ -725,15 +706,14 @@ static struct hw_mem_hole_info get_hw_me
 		mem_hole.hole_startk = HW_MEM_HOLE_SIZEK;
 		mem_hole.node_id = -1;
 
-		for (i = 0; i < FX_DEVS; i++) {
+		for (i = 0; i < fx_devs; i++) {
 			uint32_t base;
 			uint32_t hole;
 			base  = f1_read_config32(0x40 + (i << 3));
 			if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
 				continue;
 			}
-			if (!__f1_dev[i])
-				continue;
+
 			hole = pci_read_config32(__f1_dev[i], 0xf0);
 			if(hole & 1) { // we find the hole
 				mem_hole.hole_startk = (hole & (0xff<<24)) >> 10;
@@ -769,9 +749,10 @@ static struct hw_mem_hole_info get_hw_me
 		return mem_hole;
 
 }
-static void disable_hoist_memory(unsigned long hole_startk, int i)
+
+static void disable_hoist_memory(unsigned long hole_startk, int node_id)
 {
-	int ii;
+	int i;
 	device_t dev;
 	uint32_t base, limit;
 	uint32_t hoist;
@@ -787,33 +768,35 @@ static void disable_hoist_memory(unsigne
 
 	hole_sizek = (4*1024*1024) - hole_startk;
 
-	for(ii=7;ii>i;ii--) {
+	for(i=7;i>node_id;i--) {
 
-		base  = f1_read_config32(0x40 + (ii << 3));
+		base  = f1_read_config32(0x40 + (i << 3));
 		if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
 			continue;
 		}
-		limit = f1_read_config32(0x44 + (ii << 3));
-		f1_write_config32(0x44 + (ii << 3),limit - (hole_sizek << 2));
-		f1_write_config32(0x40 + (ii << 3),base - (hole_sizek << 2));
+		limit = f1_read_config32(0x44 + (i << 3));
+		f1_write_config32(0x44 + (i << 3),limit - (hole_sizek << 2));
+		f1_write_config32(0x40 + (i << 3),base - (hole_sizek << 2));
 	}
-	limit = f1_read_config32(0x44 + (i << 3));
-	f1_write_config32(0x44 + (i << 3),limit - (hole_sizek << 2));
-	dev = __f1_dev[i];
-	if (dev) {
-		hoist = pci_read_config32(dev, 0xf0);
-		if(hoist & 1) {
-			pci_write_config32(dev, 0xf0, 0);
-		} else {
-			base = pci_read_config32(dev, 0x40 + (i << 3));
-			f1_write_config32(0x40 + (i << 3),base - (hole_sizek << 2));
-		}
+	limit = f1_read_config32(0x44 + (node_id << 3));
+	f1_write_config32(0x44 + (node_id << 3),limit - (hole_sizek << 2));
+	dev = __f1_dev[node_id];
+	if (dev == NULL) {
+		printk_err("%s: node %x is NULL!\n", __func__, node_id);
+		return;
+	}
+	hoist = pci_read_config32(dev, 0xf0);
+	if(hoist & 1)
+		pci_write_config32(dev, 0xf0, 0);
+	else {
+		base = pci_read_config32(dev, 0x40 + (node_id << 3));
+		f1_write_config32(0x40 + (node_id << 3),base - (hole_sizek << 2));
 	}
 }
 
-static uint32_t hoist_memory(unsigned long hole_startk, int i)
+static uint32_t hoist_memory(unsigned long hole_startk, int node_id)
 {
-	int ii;
+	int i;
 	uint32_t carry_over;
 	device_t dev;
 	uint32_t base, limit;
@@ -822,27 +805,27 @@ static uint32_t hoist_memory(unsigned lo
 
 	carry_over = (4*1024*1024) - hole_startk;
 
-	for(ii=7;ii>i;ii--) {
+	for(i=7;i>node_id;i--) {
 
-		base  = f1_read_config32(0x40 + (ii << 3));
+		base  = f1_read_config32(0x40 + (i << 3));
 		if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
 			continue;
 		}
-		limit = f1_read_config32(0x44 + (ii << 3));
-		f1_write_config32(0x44 + (ii << 3),limit + (carry_over << 2));
-		f1_write_config32(0x40 + (ii << 3),base + (carry_over << 2));
-	}
-	limit = f1_read_config32(0x44 + (i << 3));
-	f1_write_config32(0x44 + (i << 3),limit + (carry_over << 2));
-	dev = __f1_dev[i];
-	base  = pci_read_config32(dev, 0x40 + (i << 3));
+		limit = f1_read_config32(0x44 + (i << 3));
+		f1_write_config32(0x44 + (i << 3),limit + (carry_over << 2));
+		f1_write_config32(0x40 + (i << 3),base + (carry_over << 2));
+	}
+	limit = f1_read_config32(0x44 + (node_id << 3));
+	f1_write_config32(0x44 + (node_id << 3),limit + (carry_over << 2));
+	dev = __f1_dev[node_id];
+	base  = pci_read_config32(dev, 0x40 + (node_id << 3));
 	basek  = (base & 0xffff0000) >> 2;
 	if(basek == hole_startk) {
 		//don't need set memhole here, because hole off set will be 0, overflow
 		//so need to change base reg instead, new basek will be 4*1024*1024
 		base &= 0x0000ffff;
 		base |= (4*1024*1024)<<2;
-		f1_write_config32(0x40 + (i<<3), base);
+		f1_write_config32(0x40 + (node_id<<3), base);
 	}
 	else if (dev)
 	{
@@ -980,7 +963,7 @@ static void amdk8_domain_set_resources(d
 		#if HW_MEM_HOLE_SIZE_AUTO_INC == 1
 			//We need to double check if the mmio_basek is valid for hole setting, if it is equal to basek, we need to decrease it some
 			uint32_t basek_pri;
-			for (i = 0; i < FX_DEVS; i++) {
+			for (i = 0; i < fx_devs; i++) {
 				uint32_t base;
 				uint32_t basek;
 				base  = f1_read_config32(0x40 + (i << 3));
@@ -1005,7 +988,7 @@ static void amdk8_domain_set_resources(d
 #endif
 
 	idx = 0x10;
-	for(i = 0; i < FX_DEVS; i++) {
+	for(i = 0; i < fx_devs; i++) {
 		uint32_t base, limit;
 		unsigned basek, limitk, sizek;
 		base  = f1_read_config32(0x40 + (i << 3));
@@ -1100,7 +1083,7 @@ static unsigned int amdk8_domain_scan_bu
 	 * Including enabling relaxed ordering if it is safe.
 	 */
 	get_fx_devs();
-	for(i = 0; i < FX_DEVS; i++) {
+	for(i = 0; i < fx_devs; i++) {
 		device_t f0_dev;
 		f0_dev = __f0_dev[i];
 		if (f0_dev && f0_dev->enabled) {
Index: cbv2/src/northbridge/amd/amdk8/northbridge.c
===================================================================
--- cbv2.orig/src/northbridge/amd/amdk8/northbridge.c
+++ cbv2/src/northbridge/amd/amdk8/northbridge.c
@@ -295,13 +295,14 @@ static int reg_useable(unsigned reg,
 	return result;
 }
 
-static struct resource *amdk8_find_iopair(device_t dev, unsigned nodeid, unsigned link)
+static unsigned amdk8_find_reg(device_t dev, unsigned nodeid, unsigned link,
+			       unsigned min, unsigned max)
 {
-	struct resource *resource;
+	unsigned resource;
 	unsigned free_reg, reg;
 	resource = 0;
 	free_reg = 0;
-	for(reg = 0xc0; reg <= 0xd8; reg += 0x8) {
+	for(reg = min; reg <= max; reg += 0x8) {
 		int result;
 		result = reg_useable(reg, dev, nodeid, link);
 		if (result == 1) {
@@ -313,40 +314,23 @@ static struct resource *amdk8_find_iopai
 			free_reg = reg;
 		}
 	}
-	if (reg > 0xd8) {
+	if (reg > max) {
 		reg = free_reg;
 	}
 	if (reg > 0) {
-		resource = new_resource(dev, IOINDEX(0x100 + reg, link));
+		resource = IOINDEX(0x100 + reg, link);
 	}
 	return resource;
 }
 
-static struct resource *amdk8_find_mempair(device_t dev, unsigned nodeid, unsigned link)
+static unsigned amdk8_find_iopair(device_t dev, unsigned nodeid, unsigned link)
 {
-	struct resource *resource;
-	unsigned free_reg, reg;
-	resource = 0;
-	free_reg = 0;
-	for(reg = 0x80; reg <= 0xb8; reg += 0x8) {
-		int result;
-		result = reg_useable(reg, dev, nodeid, link);
-		if (result == 1) {
-			/* I have been allocated this one */
-			break;
-		}
-		else if (result > 1) {
-			/* I have a free register pair */
-			free_reg = reg;
-		}
-	}
-	if (reg > 0xb8) {
-		reg = free_reg;
-	}
-	if (reg > 0) {
-		resource = new_resource(dev, IOINDEX(0x100 + reg, link));
-	}
-	return resource;
+	return amdk8_find_reg(dev, nodeid, link, 0xc0, 0xd8);
+}
+
+static unsigned amdk8_find_mempair(device_t dev, unsigned nodeid, unsigned link)
+{
+	return amdk8_find_reg(dev, nodeid, link, 0x80, 0xb8);
 }
 
 static void amdk8_link_read_bases(device_t dev, unsigned nodeid, unsigned link)
@@ -354,7 +338,7 @@ static void amdk8_link_read_bases(device
 	struct resource *resource;
 
 	/* Initialize the io space constraints on the current bus */
-	resource =  amdk8_find_iopair(dev, nodeid, link);
+	resource = new_resource(dev, IOINDEX(0, link));
 	if (resource) {
 		resource->base  = 0;
 		resource->size  = 0;
@@ -365,7 +349,7 @@ static void amdk8_link_read_bases(device
 	}
 
 	/* Initialize the prefetchable memory constraints on the current bus */
-	resource = amdk8_find_mempair(dev, nodeid, link);
+	resource = new_resource(dev, IOINDEX(2, link));
 	if (resource) {
 		resource->base  = 0;
 		resource->size  = 0;
@@ -379,7 +363,7 @@ static void amdk8_link_read_bases(device
 	}
 
 	/* Initialize the memory constraints on the current bus */
-	resource = amdk8_find_mempair(dev, nodeid, link);
+	resource = new_resource(dev, IOINDEX(1, link));
 	if (resource) {
 		resource->base  = 0;
 		resource->size  = 0;
@@ -390,6 +374,8 @@ static void amdk8_link_read_bases(device
 	}
 }
 
+static void amdk8_create_vga_resource(device_t dev, unsigned nodeid);
+
 static void amdk8_read_resources(device_t dev)
 {
 	unsigned nodeid, link;
@@ -399,6 +385,8 @@ static void amdk8_read_resources(device_
 			amdk8_link_read_bases(dev, nodeid, link);
 		}
 	}
+
+	amdk8_create_vga_resource(dev, nodeid);
 }
 
 static void amdk8_set_resource(device_t dev, struct resource *resource, unsigned nodeid)
@@ -500,8 +488,6 @@ static void amdk8_create_vga_resource(de
 {
 	struct resource *resource;
 	unsigned link;
-	uint32_t base, limit;
-	unsigned reg;
 
 	/* find out which link the VGA card is connected,
 	 * we only deal with the 'first' vga card */
@@ -525,31 +511,16 @@ static void amdk8_create_vga_resource(de
 
 	printk_debug("VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link);
 
-	/* allocate a temp resrouce for legacy VGA buffer */
-	resource = amdk8_find_mempair(dev, nodeid, link);
+	/* allocate a temp resource for the legacy VGA buffer */
+	resource = new_resource(dev, IOINDEX(4, link));
 	if(!resource){
-		printk_debug("VGA: Can not find free mmio reg for legacy VGA buffer\n");
+		printk_debug("VGA: %s out of resources.\n", dev_path(dev));
 		return;
 	}
 	resource->base = 0xa0000;
 	resource->size = 0x20000;
-
-	/* write the resource to the hardware */
-	reg  = resource->index & 0xfc;
-	base  = f1_read_config32(reg);
-	limit = f1_read_config32(reg + 0x4);
-	base  &= 0x000000f0;
-	base  |= (resource->base >> 8) & 0xffffff00;
-	base  |= 3;
-	limit &= 0x00000048;
-	limit |= (resource_end(resource) >> 8) & 0xffffff00;
-	limit |= (resource->index & 3) << 4;
-	limit |= (nodeid & 7);
-	f1_write_config32(reg + 0x4, limit);
-	f1_write_config32(reg, base);
-
-	/* release the temp resource */
-	resource->flags = 0;
+	resource->flags = IORESOURCE_FIXED | IORESOURCE_MEM |
+			  IORESOURCE_ASSIGNED;
 }
 
 static void amdk8_set_resources(device_t dev)
@@ -560,13 +531,36 @@ static void amdk8_set_resources(device_t
 	/* Find the nodeid */
 	nodeid = amdk8_nodeid(dev);
 
-	amdk8_create_vga_resource(dev, nodeid);
-
 	/* Set each resource we have found */
 	for(i = 0; i < dev->resources; i++) {
-		amdk8_set_resource(dev, &dev->resource[i], nodeid);
+		struct resource *res = &dev->resource[i];
+		struct resource *old = NULL;
+		unsigned index;
+
+		if (res->size == 0) /* No need to allocate registers. */
+			continue;
+
+		if (res->flags & IORESOURCE_IO)
+			index = amdk8_find_iopair(dev, nodeid,
+						  IOINDEX_LINK(res->index));
+		else
+			index = amdk8_find_mempair(dev, nodeid,
+						   IOINDEX_LINK(res->index));
+
+		old = probe_resource(dev, index);
+		if (old) {
+			res->index = old->index;
+			old->index = 0;
+			old->flags = 0;
+		}
+		else
+			res->index = index;
+
+		amdk8_set_resource(dev, res, nodeid);
 	}
 
+	compact_resources(dev);
+
 	for(link = 0; link < dev->links; link++) {
 		struct bus *bus;
 		bus = &dev->link[link];
@@ -636,6 +630,8 @@ static void amdk8_domain_read_resources(
 				struct resource *res;
 				res = new_resource(reg_dev, IOINDEX(0x100 + reg, link));
 				if (res) {
+					res->base = base;
+					res->limit = limit;
 					res->flags = 1;
 				}
 			}
@@ -672,7 +668,8 @@ static void tolm_test(void *gp, struct d
 	struct resource **best_p = gp;
 	struct resource *best;
 	best = *best_p;
-	if (!best || (best->base > new->base)) {
+	/* Skip VGA. */
+	if (!best || (best->base > new->base && new->base > 0xa0000)) {
 		best = new;
 	}
 	*best_p = best;
Index: cbv2/src/devices/device.c
===================================================================
--- cbv2.orig/src/devices/device.c
+++ cbv2/src/devices/device.c
@@ -662,9 +662,9 @@ static void avoid_fixed_resources(struct
 
 #if CONFIG_CONSOLE_VGA == 1
 device_t vga_pri = 0;
-static void allocate_vga_resource(void)
+static void set_vga_bridge_bits(void)
 {
-#warning "FIXME modify allocate_vga_resource so it is less pci centric!"
+#warning "FIXME modify set_vga_bridge so it is less pci centric!"
 #warning "This function knows too much about PCI stuff, it should be just a iterator/visitor."
 
 	/* FIXME: Handle the VGA palette snooping. */
@@ -715,7 +715,7 @@ static void allocate_vga_resource(void)
 
 	if (vga) {
 		/* VGA is first add on card or the only onboard VGA. */
-		printk_debug("Allocating VGA resource %s\n", dev_path(vga));
+		printk_debug("Setting up VGA for %s\n", dev_path(vga));
 		/* All legacy VGA cards have MEM & I/O space registers. */
 		vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
 		vga_pri = vga;
@@ -920,6 +920,10 @@ void dev_configure(void)
 	struct device *child;
 	int i;
 
+#if CONFIG_CONSOLE_VGA == 1
+	set_vga_bridge_bits();
+#endif
+
 	printk_info("Allocating resources...\n");
 
 	root = &dev_root;
@@ -983,12 +987,6 @@ void dev_configure(void)
 		}
 	}
 
-#if CONFIG_CONSOLE_VGA == 1
-	/* 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");
 	for (child = root->link[0].children; child; child = child->sibling) {
-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to