diff --git a/device/device.c b/device/device.c index 3246193f80..3a2d94e382 100644 --- a/device/device.c +++ b/device/device.c @@ -209,11 +209,12 @@ struct device *alloc_dev(struct bus *parent, struct device_path *path, } 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++) { diff --git a/include/device/device.h b/include/device/device.h index 37b8379915..3b3718c7f7 100644 --- a/include/device/device.h +++ b/include/device/device.h @@ -25,18 +25,28 @@ #include #include +/** + * Create a 32-bit value from four characters. This is better + * than the usual enum values when using (JTAG) debuggers. + * It also makes it harder for accidentally assigned type values + * to be mistaken for a real value -- e.g. it is more likely in the event + * of a programming error that a '1' is somehow assigned + * to the type field, whereas these values are more complex. + * Thus errors may be easier to find. + */ +#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; diff --git a/include/device/pci.h b/include/device/pci.h index 9d6eba3a72..ce9a347406 100644 --- a/include/device/pci.h +++ b/include/device/pci.h @@ -29,6 +29,7 @@ #include #include #include +#include /* * For more information, please consult the following manuals (look at diff --git a/util/dtc/flattree.c b/util/dtc/flattree.c index 828b1ed175..8243454f26 100644 --- a/util/dtc/flattree.c +++ b/util/dtc/flattree.c @@ -532,7 +532,33 @@ static void linuxbios_emit_special(FILE *e, struct node *tree) if (tree->config){ configname = clean(tree->label, 0); printf("\t.device_configuration = &%s,\n", configname); + /* The config property list for a device is derived from the + * device dts, e.g. northbridge/intel/i440bx/dts, not the + * mainboard dts. + * Almost all of these properties are specific to the device. + * Some, such as the device id, are part of the common + * device struct. Check the config properties and + * pull out those properties that are for the common + * (a.k.a. generic) device struct. + */ + /* 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); + } + } } + /* Process the properties specified in the mainboard dts. + * Some of these properties require special initialization + * (e.g. the path); some are flags, i.e. if the property exists + * then a variable is set to 1 (e.g. on_mainboard); + * and some are just set directly into the code (e.g. ops_pci). + */ for_each_property(tree, prop) { if (streq(prop->name, "pcidomain")){ fprintf(f, "\t.path = {.type=DEVICE_PATH_PCI_DOMAIN,.u={.pci_domain={ .domain = %s }}},\n",