
This is the second step toward extending the device model so that the ops pointers
for static devices are set up automatically, as they currently are for dynamic 
devices. 

There is one cosmetic aspect to this patch, in device.h. 
I am setting up DEVICE_ID to names to have a bit
more meaning. Instead of just numbers, they are ints initialized as 4-byte constants
that will look like more meaningfull to a debugger (e.g. JTAG device). 

I am changing the device code in two very simple ways. 
First, cosmetic, taking out a comment that won't make much
sense to many people. 

Second, change the memcpy to an assign, since it gets us 
type checking; and add an assign for the id. 

Add a dts file for the northbridge/amd/geodelx that sets 
two things: the constructor and the domainid. 

Finally, in the DTC (device tree compiler), add code that looks
in the config properties for the domainid and pciid 
properties and initializes the generic device. 

This produces code that looks right and builds. I'm happy about the small amount of changes it has taken to make this work. 

Next set of patches will remove the antiquated vendor, device
usage in the device struct and functions that use it.

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

Index: include/device/device.h
===================================================================
--- include/device/device.h	(revision 556)
+++ include/device/device.h	(working copy)
@@ -25,18 +25,24 @@
 #include <device/resource.h>
 #include <device/path.h>
 
+/* here is a simple macro for creating 32-bit int values from 
+ * 4 chars. I am putting it here as I am not yet sure where to 
+ * put it!
+ */
+
+#define TYPENAME(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|(d))
 #define DEVICE_ID_MAX 64
 enum device_id_type {
-	DEVICE_ID_NONE = 0,
-	DEVICE_ID_ROOT,
-	DEVICE_ID_PCI,
-	DEVICE_ID_PNP,
-	DEVICE_ID_I2C,
-	DEVICE_ID_APIC,
-	DEVICE_ID_PCI_DOMAIN,
-	DEVICE_ID_APIC_CLUSTER,
-	DEVICE_ID_CPU,
-	DEVICE_ID_CPU_BUS,
+	DEVICE_ID_NONE	= 0,
+	DEVICE_ID_ROOT	= TYPENAME('R','O','O','T'),
+	DEVICE_ID_PCI	= TYPENAME(' ','P','C','I'),
+	DEVICE_ID_PNP	= TYPENAME(' ','P','N','P'),
+	DEVICE_ID_I2C	= TYPENAME(' ','I','2','C'),
+	DEVICE_ID_APIC	= TYPENAME('A','P','I','C'),
+	DEVICE_ID_PCI_DOMAIN = TYPENAME('P','C','I','D'),
+	DEVICE_ID_APIC_CLUSTER = TYPENAME('A','P','C','C'),
+	DEVICE_ID_CPU = TYPENAME(' ','C','P','U'),
+	DEVICE_ID_CPU_BUS =  TYPENAME(' ','B','U','S'),
 };
 
 struct device;
Index: device/device.c
===================================================================
--- device/device.c	(revision 556)
+++ device/device.c	(working copy)
@@ -209,11 +209,12 @@
 	}
 
 	dev = new_device();
-	if (!dev) /* Please don't do this at home */
+	if (!dev)
 		goto out;
 
 	memset(dev, 0, sizeof(*dev));
-	memcpy(&dev->path, path, sizeof(*path));
+	dev->path = *path;
+	dev->id = *devid;
 
 	/* Initialize the back pointers in the link fields. */
 	for (link = 0; link < MAX_LINKS; link++) {
Index: northbridge/amd/geodelx/dts
===================================================================
--- northbridge/amd/geodelx/dts	(revision 0)
+++ northbridge/amd/geodelx/dts	(revision 0)
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2008 Ronald G. Minnich <rminnich@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+{
+        constructor = "geodelx_north_constructors";
+	domainid = "PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LXBRIDGE";
+};
+
Index: util/dtc/flattree.c
===================================================================
--- util/dtc/flattree.c	(revision 554)
+++ util/dtc/flattree.c	(working copy)
@@ -532,8 +532,23 @@
 	if (tree->config){
 		configname = clean(tree->label, 0);
 		printf("\t.device_configuration = &%s,\n", configname);
+		/* get the properties out that are generic device props */
+		for_each_config(tree, prop) {
+			if (streq(prop->name, "domainid")){
+				fprintf(f, "\t.id = {.type=DEVICE_ID_PCI_DOMAIN,.u={.pci_domain={ %s }}},\n", 
+					prop->val.val);
+			}
+			if (streq(prop->name, "pciid")){
+				fprintf(f, "\t.id = {.type=DEVICE_ID_PCI,.u={.pci={ %s }}},\n", 
+					prop->val.val);
+			}
+		}
 	}
 	for_each_property(tree, prop) {
+		/* note the flaw here: we're just taking the %s as an initialization string. 
+		 * Someone who is good at yacc might be able to put this stuff into the dts language. 
+		 * this streq stuff is a bit of a hack 
+		 */
 		if (streq(prop->name, "pcidomain")){
 			fprintf(f, "\t.path = {.type=DEVICE_PATH_PCI_DOMAIN,.u={.pci_domain={ .domain = %s }}},\n", 
 				prop->val.val);
@@ -1349,7 +1364,7 @@
 
 	fix_next(bi->dt);
 	/* emit any includes that we need  -- TODO: ONLY ONCE PER TYPE*/
-	fprintf(f, "#include <device/device.h>\n#include <device/pci.h>\n");
+	fprintf(f, "#include <device/device.h>\n#include <device/pci.h>\n#include <device/pci_ids.h>\n");
 	fprintf(f, "extern const char *mainboard_vendor, *mainboard_part_number;\n");
 	flatten_tree_emit_includes(bi->dt, &linuxbios_emitter, f, &strbuf, vi);
 
