Index: util/dtc/flattree.c
===================================================================
--- util/dtc/flattree.c	(revision 855)
+++ util/dtc/flattree.c	(working copy)
@@ -79,6 +79,41 @@
 	return cleanname;
 }
 
+/* given a node, generate a configuration path for the node. 
+ * The config path generated depends on the type of node, as indicated by the 
+ * node name, e.g. pci node names are not the same as apic or ioport node names 
+ * This should be more cleanly integrated into labeltree ... FIX ME
+ */
+char *configuration_name(struct node *tree, char *prefix)
+{
+	char *name = malloc(64);
+
+	if (!strncmp(tree->name, "cpu", 3)){
+		sprintf(name, "%scpu_%x", prefix, tree->unit);
+	}
+	if (!strncmp(tree->name, "bus", 3)){
+		sprintf(name, "%sbus_%x", prefix, tree->unit);
+	}
+	if (!strncmp(tree->name, "apic", 4)){
+		sprintf(name, "%sapic_%x", prefix, tree->unit);
+	}
+	if (!strncmp(tree->name, "domain", 6)){
+		sprintf(name, "%sdomain_%x", prefix, tree->unit);
+	}
+	if (!strncmp(tree->name, "pci", 3)){
+		sprintf(name, "%spci_%x_%x_%x_%x", prefix, tree->domain, tree->bus, 
+					tree->dev, tree->fn);
+	}
+	if (!strncmp(tree->name, "ioport", 6)){
+		sprintf(name, "%sioport_%x", prefix, tree->unit);
+	}
+
+	assert(name);
+
+	return name;
+
+}
+
 char *
 topath(struct property *p){
 	struct data d = p->val;
@@ -535,63 +570,22 @@
 	struct property *prop;
 	int ops_set = 0;
 	int is_root = 0;
-	char *configname;
-	char *path;
 	int enabled = 1;
+	int linkcount = 0;
 
-	fprintf(f, "struct device dev_%s = {\n", tree->label);
+
+	/*NEXT FIX WITHTHE STRUCT DEV PATH STRUCT MEMBER*/
+	/*SO THE PATH STUFF BELOW IS REMOVED AS IT IS IN LABELTREE */
+	fprintf(f, "struct device %s = {\n", tree->devname);
 	/* special case -- the root has a distinguished path */
 	if (! strncmp(tree->label, "root", 4)){
 		is_root = 1;
-		fprintf(f, "\t.path =  { .type = DEVICE_PATH_ROOT },\n");
 	}
 
-	/* from the node names (tree->name) we derive the path */
-	path = index(tree->name, '@');
-	if (path && path[1]) {
-		path++;
-		if (!strncmp(tree->name, "cpu", 3)){
-			fprintf(f, "\t.path = {.type=DEVICE_PATH_CPU,{.cpu={ .id = 0x%s }}},\n", 
-				path);
-		}
-		if (!strncmp(tree->name, "bus", 3)){
-			fprintf(f, "\t.path = {.type=DEVICE_PATH_PCI_BUS,{.pci_bus={ .bus = 0x%s }}},\n", 
-				path);
-		}
-		if (!strncmp(tree->name, "apic", 4)){
-			fprintf(f, "\t.path = {.type=DEVICE_PATH_APIC,{.apic={ 0x%s }}},\n", 
-				path);
-		}
-		if (!strncmp(tree->name, "domain", 6)){
-			fprintf(f, "\t.path = {.type=DEVICE_PATH_PCI_DOMAIN,{.pci_domain={ .domain = 0x%s }}},\n", 
-				path);
-		}
-		if (!strncmp(tree->name, "pci", 3)){
-			/* it's in two parts */
-			char *devfn = strdup(path);
-			char *dev = devfn;
-			char *fn;
+	fprintf(f, "\t.path = %s,\n", tree->struct_dev_path);
 
-			fn = index(devfn, ',');
-			/* if there is no fn we assume 0 */
-			/* the Rules are unclear on this point */
-			if (fn)
-				*fn++ = 0;
-			else
-				fn = "0";
-
-			fprintf(f, "\t.path = {.type=DEVICE_PATH_PCI,{.pci={ .devfn = PCI_DEVFN(0x%s, 0x%s)}}},\n", 
-				dev, fn);
-		}
-		if (!strncmp(tree->name, "ioport", 6)){
-			fprintf(f, "\t.path = {.type=DEVICE_PATH_IOPORT,{.ioport={.iobase=0x%s}}},\n", 
-				path);
-		}
-	}
-
 	if (tree->config){
-		configname = clean(tree->label, 0);
-		printf("\t.device_configuration = &%s,\n", configname);
+		printf("\t.device_configuration = &%s,\n", tree->configname);
 		/* The config property list for a device is derived from the
 		 * device dts, e.g. northbridge/intel/i440bx/dts, not the
 		 * mainboard dts. 
@@ -660,30 +654,41 @@
 		}
 	}
 	if (tree->next_sibling) 
-		fprintf(f, "\t.sibling = &dev_%s,\n", tree->next_sibling->label);
+		fprintf(f, "\t.sibling = &%s,\n", tree->next_sibling->devname);
 	if (tree->next) 
-		fprintf(f, "\t.next = &dev_%s,\n", tree->next->label);
-	/* now do we do next? */
-	/* this will need to do a bus for every child. And, below, we're going to need to find which bus we're on*/
-	/* for now, let's keep it to the minimum that will work, while we see if we like this. */
-	if (tree->children){
-		fprintf(f,"\t.links = 1,\n");
-		fprintf(f,"\t.link = {\n");
-		fprintf(f,"\t\t[0] = {\n");
-		fprintf(f,"\t\t\t.dev = &dev_%s,\n", tree->label);
-		fprintf(f,"\t\t\t.link = 0,\n");
-		fprintf(f,"\t\t\t.children = &dev_%s\n", tree->children->label);
-		fprintf(f,"\t\t},\n");
-		fprintf(f,"\t},\n");
+		fprintf(f, "\t.next = &%s,\n", tree->next->devname);
+
+	/* the links came from v2. It was used when multiple devices
+	 * had the same path, as in K8 HT links or I2C muxes. 
+	 * We're still not clear on whether/how to use links. 
+	 * for now, we do not use them.
+	 */
+
+	if ( 0 && tree->children){
+		struct node *child;
+		for_each_child(tree, child) {
+			fprintf(f,"\t.link = {\n");
+			/* use the child bus number? Maybe ... */
+			fprintf(f,"\t\t[%d] = {\n", linkcount);
+			fprintf(f,"\t\t\t.dev = &%s,\n", tree->devname);
+			fprintf(f,"\t\t\t.link = %d,\n", child->bus);
+			fprintf(f,"\t\t\t.children = &%s\n", child->devname);
+			fprintf(f,"\t\t},\n");
+			fprintf(f,"\t},\n");
+			child->parentlink = linkcount;
+			linkcount++;
+		}
 	}
+	fprintf(f,"\t.links = %d,\n", linkcount);
 	/* fill in the 'bus I am on' entry */
 	if (tree->parent)
-		fprintf(f, "\t.bus = &dev_%s.link[0],\n", tree->parent->label);
+		fprintf(f, "\t.bus = &%s.link[%d],\n", tree->parent->devname, 
+				tree->parentlink);
 	else
-		fprintf(f, "\t.bus = &dev_%s.link[0],\n", tree->label);
+		fprintf(f, "\t.bus = &%s.link[0],\n", tree->devname);
 
 	if (tree->next)
-		fprintf(f, "\t.next = &dev_%s,\n", tree->next->label);
+		fprintf(f, "\t.next = &%s,\n", tree->next->devname);
 
 	if ((! ops_set) && is_root)
 		fprintf(f, "\t.ops = &default_dev_ops_root,\n");
@@ -721,31 +726,6 @@
 	return i;
 }
 
-/* we're going to overload the name node for testing. This may be the wrong thing long-term */
-static void flatten_tree_emit_includes(struct node *tree, struct emitter *emit,
-			 void *etarget, struct data *strbuf,
-			 struct version_info *vi)
-{
-	char *pathname;
-	struct property *prop;
-	struct node *child;
-	FILE *f = etarget;
-
-	for_each_property(tree, prop) {
-		if (streq(prop->name, "config")) {
-			pathname = topath(prop);
-			fprintf(f, "#include <%s/config.h>\n", pathname);
-			free(pathname);
-		}
-	}
-
-	for_each_child(tree, child) {
-		flatten_tree_emit_includes(child, emit, etarget, strbuf, vi);
-	}
-
-
-}
-
 static void flatten_tree_emit_device_operations(struct node *tree, struct emitter *emit,
 			 void *etarget, struct data *strbuf,
 			 struct version_info *vi)
@@ -799,6 +779,7 @@
 
 	if (tree->config){
 //		treename = clean(tree->label, 0);
+fprintf(stderr, "TREE %s HAS CONFIG\n", tree->label);
 		treename = toname(tree->config->label, "_config");
 		emit->beginnode(etarget, treename);
 
@@ -907,7 +888,7 @@
 		  * the design of this code is wrong and must be fixed. 
 		  * the operator should take the node itself, not a string. 
 		  */
-		printf("struct %s %s = {\n", structname, treelabel);
+		printf("struct %s %s = {\n", structname, tree->configname);
 
 		for_each_config(tree, configprop) {
 			char *cleanname;
@@ -1307,14 +1288,118 @@
 	data_free(strbuf);
 }
 
-/*Set up the clean label  */
+/* walk the tree and set up parent/child relationships, names, inherited values, and so on */
 
 void
 labeltree(struct node *tree)
 {
 	struct node *child;
+	int is_root = 0;
+	char *path;
 
 	tree->label = clean(tree->name, 1);
+	/* special case -- the root has a distinguished path */
+	if (! strncmp(tree->label, "root", 4)){
+		is_root = 1;
+		tree->devname = "dev_root";
+		tree->struct_dev_path = "{ .type = DEVICE_PATH_ROOT }";
+	}
+
+
+	/* manage the @ syntax to initialize variables in the tre struct */
+	/* the @ is still optional, so we do it this way. */
+	path = index(tree->name, '@');
+	if (path && path[1]) {
+		tree->struct_dev_path = malloc(128);
+		path++;
+		if (!strncmp(tree->name, "cpu", 3)){
+			tree->unit = strtol(path, 0, 16);
+		}
+		if (!strncmp(tree->name, "apic", 4)){
+			tree->unit = strtol(path, 0, 16);
+		}
+		if (!strncmp(tree->name, "domain", 6)){
+			tree->domain = strtol(path, 0, 16);
+		}
+		if (!strncmp(tree->name, "bus", 3)){
+			tree->bus = strtol(path, 0, 16);
+		}
+		if (!strncmp(tree->name, "pci", 3)){
+			/* it's in two parts */
+			char *devfn = strdup(path);
+			char *dev = devfn;
+			char *fn;
+
+			fn = index(devfn, ',');
+			/* if there is no fn we assume 0 */
+			/* the Rules are unclear on this point */
+			if (fn)
+				*fn++ = 0;
+			else
+				fn = "0";
+
+			tree->dev = strtol(dev, 0, 16);
+			tree->fn = strtol(fn, 0, 16);
+		}
+		if (!strncmp(tree->name, "ioport", 6)){
+			tree->unit = strtol(path, 0, 16);
+			
+		}
+
+	}
+
+	/* now create the names in the tree that we need */
+	/* these are not dependent on the presence of @ in the name */
+
+	tree->struct_dev_path = malloc(128);
+	if (! strncmp(tree->label, "root", 4)){
+		tree->devname = "dev_root";
+		sprintf(tree->struct_dev_path,  "{ .type = DEVICE_PATH_ROOT }");
+	}
+	if (!strncmp(tree->name, "cpu", 3)){
+		sprintf(tree->struct_dev_path, "{.type=DEVICE_PATH_CPU,{.cpu={ .id = 0x%x }}}", 
+			tree->unit);
+	}
+	if (!strncmp(tree->name, "apic", 4)){
+		sprintf(tree->struct_dev_path, "{.type=DEVICE_PATH_APIC,{.apic={ 0x%x }}}", 
+			tree->unit);
+	}
+	if (!strncmp(tree->name, "domain", 6)){
+		sprintf(tree->struct_dev_path, "{.type=DEVICE_PATH_PCI_DOMAIN,{.pci_domain={ .domain = 0x%x }}}", 
+			tree->domain);
+	}
+	if (!strncmp(tree->name, "bus", 3)){
+		sprintf(tree->struct_dev_path, "{.type=DEVICE_PATH_PCI_BUS,{.pci_bus={ .bus = 0x%x }}}", 
+			tree->bus);
+		tree->domain = tree->parent->domain;
+	}
+	if (!strncmp(tree->name, "pci", 3)){
+
+		sprintf(tree->struct_dev_path, "{.type=DEVICE_PATH_PCI,{.pci={ .devfn = PCI_DEVFN(0x%x, 0x%x)}}}", 
+			tree->dev, tree->fn);
+		tree->bus = tree->parent->bus;
+		tree->domain = tree->parent->domain;
+	}
+	if (!strncmp(tree->name, "ioport", 6)){
+		sprintf(tree->struct_dev_path, "{{.type=DEVICE_PATH_IOPORT,{.ioport={.iobase=0x%x}}}", 
+			tree->unit);
+		tree->dev = tree->parent->dev;
+		tree->fn = tree->parent->fn;
+		tree->bus = tree->parent->bus;
+		tree->domain = tree->parent->domain;
+		
+	}
+
+
+	/* generate names that will be used in several places. 
+	 * first is the name for the device struct, e.g. dev_pci_bus_dev_fn, or apic_unit
+	 * next is the name for the config struct, e.g. pci_bus_dev_fn
+	 */
+	if (! is_root) {
+		tree->devname = configuration_name(tree, "dev_");
+		tree->configname = configuration_name(tree, "");
+	}
+
 	
 	if (tree->next_sibling)
 		labeltree(tree->next_sibling);
@@ -1349,6 +1434,11 @@
 	extern struct node *first_node;
 	int found_mainboard_vendor = 0, found_mainboard_name = 0, found_mainboard_subsys = 0;
 
+	/* the root is special -- the parser gives it no name. We fix that here. 
+	  * fix in parser? 
+	  */
+	bi->dt->name  = bi->dt->label  = "root";
+
 	labeltree(bi->dt);
 
 	for (i = 0; i < ARRAY_SIZE(version_table); i++) {
@@ -1362,13 +1452,14 @@
 	  * fix in parser? 
 	  */
 	bi->dt->name  = bi->dt->label  = "root";
+
 	/* steps: emit all structs. Then emit the initializers, with the pointers to other structs etc. */
 
 	fix_next(bi->dt);
 	fprintf(f, "#include <statictree.h>\n");
 	/* forward declarations */
 	for(next = first_node; next; next = next->next)
-		fprintf(f, "struct device dev_%s;\n", next->label);
+		fprintf(f, "struct device %s;\n", next->devname);
 
 	/* special for the root. Emit the names for the mainboard vendor and part # */
 	for_each_property(bi->dt, prop) {
@@ -1437,6 +1528,10 @@
 	int found_mainboard_subsys = 0;
 	extern struct node *first_node;
 
+	/* the root is special -- the parser gives it no name. We fix that here. 
+	  * fix in parser? 
+	  */
+	bi->dt->name  = bi->dt->label  = "root";
 	labeltree(bi->dt);
 
 	for (i = 0; i < ARRAY_SIZE(version_table); i++) {
@@ -1446,10 +1541,6 @@
 	if (!vi)
 		die("Unknown device tree blob version %d\n", version);
 
-	/* the root is special -- the parser gives it no name. We fix that here. 
-	  * fix in parser? 
-	  */
-	bi->dt->name  = bi->dt->label  = "root";
 	/* steps: emit all structs. Then emit the initializers, with the pointers to other structs etc. */
 
 	fix_next(bi->dt);
@@ -1481,8 +1572,6 @@
 		break;
 	}
 
-	flatten_tree_emit_includes(bi->dt, &coreboot_emitter, f, &strbuf, vi);
-
 	flatten_tree_emit_structdecls(bi->dt, &coreboot_emitter, f, &strbuf, vi);
 	/* */
 
Index: util/dtc/dtc.h
===================================================================
--- util/dtc/dtc.h	(revision 855)
+++ util/dtc/dtc.h	(working copy)
@@ -166,6 +166,20 @@
 	int addr_cells, size_cells;
 
 	char *label;
+	/* names generated by configuration_name */
+	char *devname; 	/* the name of the device struct */
+	char *configname;	/* the name of the configuration struct */
+	/* hardware-related information */
+	int domain, bus, dev, fn;	/* pci-related */
+	int unit;				/* e.g. api #, cpu #, ioport # */
+	/* some devices (K8 CPU for example) have more than one link. 
+	 * the labeltree function is responsible for make sure that parent link
+	 * counts  and childs' knowledge of which link it is on are correct. 
+	 */
+	int linkcount;	/* how many links this node has (think of K8 links */
+	int parentlink;	/* which of the parent's links this child is on */
+	/* The path name we emit if we are generating structures */
+	char *struct_dev_path;
 };
 
 #define for_each_property(n, p) \
