Cleanup. Not totally yet. But it's better and it works with dbe62. 

Basically, variables such as domain, bus, etc. are now inherited from the parent. 

Label_tree has been fixed to do lots of tree annotation and cleanup. 

One whole un-needed function is gone. 

We're going to soon be able to do stuff like bus@3{} bus@2{} etc. which we 
need to support k8. 

This code "needs more love" as ward puts it but this is an improvement. 

Also, names are now unique:
struct device dev_pci_0_0_1_0

which is domain 0, bus 0, dev 1, fn 0.

Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>


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\n", prefix, tree->unit);
+	}
+	if (!strncmp(tree->name, "bus", 3)){
+		sprintf(name, "%sbus_%x\n", prefix, tree->unit);
+	}
+	if (!strncmp(tree->name, "apic", 4)){
+		sprintf(name, "%sapic_%x\n", prefix, tree->unit);
+	}
+	if (!strncmp(tree->name, "domain", 6)){
+		sprintf(name, "%sdomain_%x\n", prefix, tree->unit);
+	}
+	if (!strncmp(tree->name, "pci", 3)){
+		sprintf(name, "%spci_%x_%x_%x_%x\n", prefix, tree->domain, tree->bus, 
+					tree->dev, tree->fn);
+	}
+	if (!strncmp(tree->name, "ioport", 6)){
+		sprintf(name, "%sioport_%x\n", prefix, tree->unit);
+	}
+
+	assert(name);
+
+	return name;
+
+}
+
 char *
 topath(struct property *p){
 	struct data d = p->val;
@@ -535,63 +570,21 @@
 	struct property *prop;
 	int ops_set = 0;
 	int is_root = 0;
-	char *configname;
-	char *path;
 	int enabled = 1;
 
-	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,9 +653,9 @@
 		}
 	}
 	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);
+		fprintf(f, "\t.next = &%s,\n", tree->next->devname);
 	/* 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. */
@@ -670,20 +663,20 @@
 		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.dev = &%s,\n", tree->devname);
 		fprintf(f,"\t\t\t.link = 0,\n");
-		fprintf(f,"\t\t\t.children = &dev_%s\n", tree->children->label);
+		fprintf(f,"\t\t\t.children = &%s\n", tree->children->devname);
 		fprintf(f,"\t\t},\n");
 		fprintf(f,"\t},\n");
 	}
 	/* 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[0],\n", tree->parent->devname);
 	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 +714,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 +767,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 +876,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 +1276,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 +1422,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 +1440,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 +1516,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 +1529,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 +1560,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,19 @@
 	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 are correct. 
+	 */
+	int linkcount;
+	/* The path name we emit if we are generating structures */
+	char *struct_dev_path;
 };
 
 #define for_each_property(n, p) \
