Commit 02e2da45c4601909d5105838323d5c529ec7010b

Authored by Paul Brook
1 parent 4856fcff

Add common BusState

Implement and use a common device bus state.  The main side-effect is
that creating a bus and attaching it to a parent device are no longer
separate operations.  For legacy code we allow a NULL parent, but that
should go away eventually.

Also tweak creation code to veriry theat a device in on the right bus.

Signed-off-by: Paul Brook <paul@codesourcery.com>
hw/acpi.c
... ... @@ -548,7 +548,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
548 548  
549 549 register_savevm("piix4_pm", 0, 1, pm_save, pm_load, s);
550 550  
551   - s->smbus = i2c_init_bus();
  551 + s->smbus = i2c_init_bus(NULL, "i2c");
552 552 s->irq = sci_irq;
553 553 qemu_register_reset(piix4_reset, 0, s);
554 554  
... ...
hw/apb_pci.c
... ... @@ -231,7 +231,8 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
231 231  
232 232 s = qemu_mallocz(sizeof(APBState));
233 233 /* Ultrasparc PBM main bus */
234   - s->bus = pci_register_bus(pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32);
  234 + s->bus = pci_register_bus(NULL, "pci",
  235 + pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32);
235 236  
236 237 pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read,
237 238 pci_apb_config_write, s);
... ...
hw/grackle_pci.c
... ... @@ -133,7 +133,8 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
133 133 int pci_mem_config, pci_mem_data;
134 134  
135 135 s = qemu_mallocz(sizeof(GrackleState));
136   - s->bus = pci_register_bus(pci_grackle_set_irq, pci_grackle_map_irq,
  136 + s->bus = pci_register_bus(NULL, "pci",
  137 + pci_grackle_set_irq, pci_grackle_map_irq,
137 138 pic, 0, 4);
138 139  
139 140 pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read,
... ...
hw/gt64xxx.c
... ... @@ -1128,7 +1128,8 @@ PCIBus *pci_gt64120_init(qemu_irq *pic)
1128 1128 s = qemu_mallocz(sizeof(GT64120State));
1129 1129 s->pci = qemu_mallocz(sizeof(GT64120PCIState));
1130 1130  
1131   - s->pci->bus = pci_register_bus(pci_gt64120_set_irq, pci_gt64120_map_irq,
  1131 + s->pci->bus = pci_register_bus(NULL, "pci",
  1132 + pci_gt64120_set_irq, pci_gt64120_map_irq,
1132 1133 pic, 144, 4);
1133 1134 s->ISD_handle = cpu_register_io_memory(0, gt64120_read, gt64120_write, s);
1134 1135 d = pci_register_device(s->pci->bus, "GT64120 PCI Bus", sizeof(PCIDevice),
... ...
hw/i2c.c
... ... @@ -11,6 +11,7 @@
11 11  
12 12 struct i2c_bus
13 13 {
  14 + BusState qbus;
14 15 i2c_slave *current_dev;
15 16 i2c_slave *dev;
16 17 int saved_address;
... ... @@ -39,11 +40,12 @@ static int i2c_bus_load(QEMUFile *f, void *opaque, int version_id)
39 40 }
40 41  
41 42 /* Create a new I2C bus. */
42   -i2c_bus *i2c_init_bus(void)
  43 +i2c_bus *i2c_init_bus(DeviceState *parent, const char *name)
43 44 {
44 45 i2c_bus *bus;
45 46  
46   - bus = (i2c_bus *)qemu_mallocz(sizeof(i2c_bus));
  47 + bus = FROM_QBUS(i2c_bus, qbus_create(BUS_TYPE_I2C, sizeof(i2c_bus),
  48 + parent, name));
47 49 register_savevm("i2c_bus", -1, 1, i2c_bus_save, i2c_bus_load, bus);
48 50 return bus;
49 51 }
... ... @@ -63,20 +65,22 @@ int i2c_bus_busy(i2c_bus *bus)
63 65 /* TODO: Make this handle multiple masters. */
64 66 int i2c_start_transfer(i2c_bus *bus, int address, int recv)
65 67 {
66   - i2c_slave *dev;
  68 + DeviceState *qdev;
  69 + i2c_slave *slave = NULL;
67 70  
68   - for (dev = bus->dev; dev; dev = dev->next) {
69   - if (dev->address == address)
  71 + LIST_FOREACH(qdev, &bus->qbus.children, sibling) {
  72 + slave = I2C_SLAVE_FROM_QDEV(qdev);
  73 + if (slave->address == address)
70 74 break;
71 75 }
72 76  
73   - if (!dev)
  77 + if (!slave)
74 78 return 1;
75 79  
76 80 /* If the bus is already busy, assume this is a repeated
77 81 start condition. */
78   - bus->current_dev = dev;
79   - dev->info->event(dev, recv ? I2C_START_RECV : I2C_START_SEND);
  82 + bus->current_dev = slave;
  83 + slave->info->event(slave, recv ? I2C_START_RECV : I2C_START_SEND);
80 84 return 0;
81 85 }
82 86  
... ... @@ -130,23 +134,20 @@ void i2c_slave_save(QEMUFile *f, i2c_slave *dev)
130 134 void i2c_slave_load(QEMUFile *f, i2c_slave *dev)
131 135 {
132 136 i2c_bus *bus;
133   - bus = qdev_get_bus(&dev->qdev);
  137 + bus = FROM_QBUS(i2c_bus, qdev_get_parent_bus(&dev->qdev));
134 138 dev->address = qemu_get_byte(f);
135 139 if (bus->saved_address == dev->address) {
136 140 bus->current_dev = dev;
137 141 }
138 142 }
139 143  
140   -static void i2c_slave_qdev_init(DeviceState *dev, void *opaque)
  144 +static void i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base)
141 145 {
142   - I2CSlaveInfo *info = opaque;
  146 + I2CSlaveInfo *info = container_of(base, I2CSlaveInfo, qdev);
143 147 i2c_slave *s = I2C_SLAVE_FROM_QDEV(dev);
144 148  
145 149 s->info = info;
146   - s->bus = qdev_get_bus(dev);
147 150 s->address = qdev_get_prop_int(dev, "address", 0);
148   - s->next = s->bus->dev;
149   - s->bus->dev = s;
150 151  
151 152 info->init(s);
152 153 }
... ... @@ -154,14 +155,16 @@ static void i2c_slave_qdev_init(DeviceState *dev, void *opaque)
154 155 void i2c_register_slave(const char *name, int size, I2CSlaveInfo *info)
155 156 {
156 157 assert(size >= sizeof(i2c_slave));
157   - qdev_register(name, size, i2c_slave_qdev_init, info);
  158 + info->qdev.init = i2c_slave_qdev_init;
  159 + info->qdev.bus_type = BUS_TYPE_I2C;
  160 + qdev_register(name, size, &info->qdev);
158 161 }
159 162  
160 163 DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, int addr)
161 164 {
162 165 DeviceState *dev;
163 166  
164   - dev = qdev_create(bus, name);
  167 + dev = qdev_create(&bus->qbus, name);
165 168 qdev_set_prop_int(dev, "address", addr);
166 169 qdev_init(dev);
167 170 return dev;
... ...
hw/i2c.h
... ... @@ -25,6 +25,8 @@ typedef void (*i2c_event_cb)(i2c_slave *s, enum i2c_event event);
25 25 typedef void (*i2c_slave_initfn)(i2c_slave *dev);
26 26  
27 27 typedef struct {
  28 + DeviceInfo qdev;
  29 +
28 30 /* Callbacks provided by the device. */
29 31 i2c_slave_initfn init;
30 32 i2c_event_cb event;
... ... @@ -39,11 +41,9 @@ struct i2c_slave
39 41  
40 42 /* Remaining fields for internal use by the I2C code. */
41 43 int address;
42   - void *next;
43   - i2c_bus *bus;
44 44 };
45 45  
46   -i2c_bus *i2c_init_bus(void);
  46 +i2c_bus *i2c_init_bus(DeviceState *parent, const char *name);
47 47 void i2c_set_slave_address(i2c_slave *dev, int address);
48 48 int i2c_bus_busy(i2c_bus *bus);
49 49 int i2c_start_transfer(i2c_bus *bus, int address, int recv);
... ...
hw/mips_malta.c
... ... @@ -907,7 +907,7 @@ void mips_malta_init (ram_addr_t ram_size,
907 907 for (i = 0; i < 8; i++) {
908 908 /* TODO: Populate SPD eeprom data. */
909 909 DeviceState *eeprom;
910   - eeprom = qdev_create(smbus, "smbus-eeprom");
  910 + eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
911 911 qdev_set_prop_int(eeprom, "address", 0x50 + i);
912 912 qdev_set_prop_ptr(eeprom, "data", eeprom_buf + (i * 256));
913 913 qdev_init(eeprom);
... ...
hw/musicpal.c
... ... @@ -431,7 +431,7 @@ static i2c_interface *musicpal_audio_init(qemu_irq irq)
431 431 s->irq = irq;
432 432  
433 433 i2c = qemu_mallocz(sizeof(i2c_interface));
434   - i2c->bus = i2c_init_bus();
  434 + i2c->bus = i2c_init_bus(NULL, "i2c");
435 435 i2c->current_addr = -1;
436 436  
437 437 s->wm = i2c_create_slave(i2c->bus, "wm8750", MP_WM_ADDR);
... ...
hw/omap_i2c.c
... ... @@ -433,7 +433,7 @@ struct omap_i2c_s *omap_i2c_init(target_phys_addr_t base,
433 433 s->irq = irq;
434 434 s->drq[0] = dma[0];
435 435 s->drq[1] = dma[1];
436   - s->bus = i2c_init_bus();
  436 + s->bus = i2c_init_bus(NULL, "i2c");
437 437 omap_i2c_reset(s);
438 438  
439 439 iomemtype = cpu_register_io_memory(0, omap_i2c_readfn,
... ... @@ -454,7 +454,7 @@ struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta,
454 454 s->irq = irq;
455 455 s->drq[0] = dma[0];
456 456 s->drq[1] = dma[1];
457   - s->bus = i2c_init_bus();
  457 + s->bus = i2c_init_bus(NULL, "i2c");
458 458 omap_i2c_reset(s);
459 459  
460 460 iomemtype = l4_register_io_memory(0, omap_i2c_readfn,
... ...
... ... @@ -1105,7 +1105,7 @@ static void pc_init1(ram_addr_t ram_size,
1105 1105 smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]);
1106 1106 for (i = 0; i < 8; i++) {
1107 1107 DeviceState *eeprom;
1108   - eeprom = qdev_create(smbus, "smbus-eeprom");
  1108 + eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
1109 1109 qdev_set_prop_int(eeprom, "address", 0x50 + i);
1110 1110 qdev_set_prop_ptr(eeprom, "data", eeprom_buf + (i * 256));
1111 1111 qdev_init(eeprom);
... ...
hw/pci.c
... ... @@ -30,6 +30,7 @@
30 30 //#define DEBUG_PCI
31 31  
32 32 struct PCIBus {
  33 + BusState qbus;
33 34 int bus_num;
34 35 int devfn_min;
35 36 pci_set_irq_fn set_irq;
... ... @@ -87,13 +88,16 @@ static int pcibus_load(QEMUFile *f, void *opaque, int version_id)
87 88 return 0;
88 89 }
89 90  
90   -PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
  91 +PCIBus *pci_register_bus(DeviceState *parent, const char *name,
  92 + pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
91 93 qemu_irq *pic, int devfn_min, int nirq)
92 94 {
93 95 PCIBus *bus;
94 96 static int nbus = 0;
95 97  
96   - bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
  98 + bus = FROM_QBUS(PCIBus, qbus_create(BUS_TYPE_PCI,
  99 + sizeof(PCIBus) + (nirq * sizeof(int)),
  100 + parent, name));
97 101 bus->set_irq = set_irq;
98 102 bus->map_irq = map_irq;
99 103 bus->irq_opaque = pic;
... ... @@ -320,7 +324,7 @@ int pci_unregister_device(PCIDevice *pci_dev)
320 324 qemu_free_irqs(pci_dev->irq);
321 325 pci_irq_index--;
322 326 pci_dev->bus->devices[pci_dev->devfn] = NULL;
323   - qemu_free(pci_dev);
  327 + qdev_free(&pci_dev->qdev);
324 328 return 0;
325 329 }
326 330  
... ... @@ -821,7 +825,7 @@ PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn,
821 825  
822 826 for (i = 0; pci_nic_models[i]; i++) {
823 827 if (strcmp(nd->model, pci_nic_models[i]) == 0) {
824   - dev = qdev_create(bus, pci_nic_names[i]);
  828 + dev = qdev_create(&bus->qbus, pci_nic_names[i]);
825 829 qdev_set_prop_int(dev, "devfn", devfn);
826 830 qdev_set_netdev(dev, nd);
827 831 qdev_init(dev);
... ... @@ -901,32 +905,43 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
901 905 return s->bus;
902 906 }
903 907  
904   -static void pci_qdev_init(DeviceState *qdev, void *opaque)
  908 +typedef struct {
  909 + DeviceInfo qdev;
  910 + pci_qdev_initfn init;
  911 +} PCIDeviceInfo;
  912 +
  913 +static void pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
905 914 {
906 915 PCIDevice *pci_dev = (PCIDevice *)qdev;
907   - pci_qdev_initfn init;
  916 + PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
908 917 PCIBus *bus;
909 918 int devfn;
910 919  
911   - init = opaque;
912   - bus = qdev_get_bus(qdev);
  920 + bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
913 921 devfn = qdev_get_prop_int(qdev, "devfn", -1);
914 922 pci_dev = do_pci_register_device(pci_dev, bus, "FIXME", devfn,
915 923 NULL, NULL);//FIXME:config_read, config_write);
916 924 assert(pci_dev);
917   - init(pci_dev);
  925 + info->init(pci_dev);
918 926 }
919 927  
920 928 void pci_qdev_register(const char *name, int size, pci_qdev_initfn init)
921 929 {
922   - qdev_register(name, size, pci_qdev_init, init);
  930 + PCIDeviceInfo *info;
  931 +
  932 + info = qemu_mallocz(sizeof(*info));
  933 + info->init = init;
  934 + info->qdev.init = pci_qdev_init;
  935 + info->qdev.bus_type = BUS_TYPE_PCI;
  936 +
  937 + qdev_register(name, size, &info->qdev);
923 938 }
924 939  
925 940 PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
926 941 {
927 942 DeviceState *dev;
928 943  
929   - dev = qdev_create(bus, name);
  944 + dev = qdev_create(&bus->qbus, name);
930 945 qdev_set_prop_int(dev, "devfn", devfn);
931 946 qdev_init(dev);
932 947  
... ...
hw/pci.h
... ... @@ -183,7 +183,8 @@ int pci_device_load(PCIDevice *s, QEMUFile *f);
183 183  
184 184 typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level);
185 185 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
186   -PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
  186 +PCIBus *pci_register_bus(DeviceState *parent, const char *name,
  187 + pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
187 188 qemu_irq *pic, int devfn_min, int nirq);
188 189  
189 190 PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn,
... ...
hw/piix_pci.c
... ... @@ -176,7 +176,8 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic)
176 176 I440FXState *s;
177 177  
178 178 s = qemu_mallocz(sizeof(I440FXState));
179   - b = pci_register_bus(piix3_set_irq, pci_slot_get_pirq, pic, 0, 4);
  179 + b = pci_register_bus(NULL, "pci",
  180 + piix3_set_irq, pci_slot_get_pirq, pic, 0, 4);
180 181 s->bus = b;
181 182  
182 183 register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
... ...
hw/pl022.c
... ... @@ -297,8 +297,7 @@ static void pl022_init(SysBusDevice *dev)
297 297 pl022_writefn, s);
298 298 sysbus_init_mmio(dev, 0x1000, iomemtype);
299 299 sysbus_init_irq(dev, &s->irq);
300   - s->ssi = ssi_create_bus();
301   - qdev_attach_child_bus(&dev->qdev, "ssi", s->ssi);
  300 + s->ssi = ssi_create_bus(&dev->qdev, "ssi");
302 301 pl022_reset(s);
303 302 register_savevm("pl022_ssp", -1, 1, pl022_save, pl022_load, s);
304 303 }
... ...
hw/ppc4xx_pci.c
... ... @@ -370,7 +370,8 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
370 370  
371 371 controller = qemu_mallocz(sizeof(PPC4xxPCIState));
372 372  
373   - controller->pci_state.bus = pci_register_bus(ppc4xx_pci_set_irq,
  373 + controller->pci_state.bus = pci_register_bus(NULL, "pci",
  374 + ppc4xx_pci_set_irq,
374 375 ppc4xx_pci_map_irq,
375 376 pci_irqs, 0, 4);
376 377  
... ...
hw/ppce500_pci.c
... ... @@ -317,7 +317,8 @@ PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
317 317  
318 318 controller = qemu_mallocz(sizeof(PPCE500PCIState));
319 319  
320   - controller->pci_state.bus = pci_register_bus(mpc85xx_pci_set_irq,
  320 + controller->pci_state.bus = pci_register_bus(NULL, "pci",
  321 + mpc85xx_pci_set_irq,
321 322 mpc85xx_pci_map_irq,
322 323 pci_irqs, 0x88, 4);
323 324 d = pci_register_device(controller->pci_state.bus,
... ...
hw/prep_pci.c
... ... @@ -136,7 +136,8 @@ PCIBus *pci_prep_init(qemu_irq *pic)
136 136 int PPC_io_memory;
137 137  
138 138 s = qemu_mallocz(sizeof(PREPPCIState));
139   - s->bus = pci_register_bus(prep_set_irq, prep_map_irq, pic, 0, 4);
  139 + s->bus = pci_register_bus(NULL, "pci",
  140 + prep_set_irq, prep_map_irq, pic, 0, 4);
140 141  
141 142 register_ioport_write(0xcf8, 4, 4, pci_prep_addr_writel, s);
142 143 register_ioport_read(0xcf8, 4, 4, pci_prep_addr_readl, s);
... ...
hw/pxa2xx.c
... ... @@ -863,8 +863,7 @@ static void pxa2xx_ssp_init(SysBusDevice *dev)
863 863 register_savevm("pxa2xx_ssp", -1, 0,
864 864 pxa2xx_ssp_save, pxa2xx_ssp_load, s);
865 865  
866   - s->bus = ssi_create_bus();
867   - qdev_attach_child_bus(&dev->qdev, "ssi", s->bus);
  866 + s->bus = ssi_create_bus(&dev->qdev, "ssi");
868 867 }
869 868  
870 869 /* Real-Time Clock */
... ... @@ -1500,12 +1499,12 @@ PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base,
1500 1499 PXA2xxI2CState *s = qemu_mallocz(sizeof(PXA2xxI2CState));
1501 1500  
1502 1501 /* FIXME: Should the slave device really be on a separate bus? */
1503   - dev = i2c_create_slave(i2c_init_bus(), "pxa2xx-i2c-slave", 0);
  1502 + dev = i2c_create_slave(i2c_init_bus(NULL, "dummy"), "pxa2xx-i2c-slave", 0);
1504 1503 s->slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, I2C_SLAVE_FROM_QDEV(dev));
1505 1504 s->slave->host = s;
1506 1505  
1507 1506 s->irq = irq;
1508   - s->bus = i2c_init_bus();
  1507 + s->bus = i2c_init_bus(NULL, "i2c");
1509 1508 s->offset = base - (base & (~region_size) & TARGET_PAGE_MASK);
1510 1509  
1511 1510 iomemtype = cpu_register_io_memory(0, pxa2xx_i2c_readfn,
... ... @@ -2117,7 +2116,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
2117 2116 DeviceState *dev;
2118 2117 dev = sysbus_create_simple("pxa2xx-ssp", pxa27x_ssp[i].io_base,
2119 2118 s->pic[pxa27x_ssp[i].irqn]);
2120   - s->ssp[i] = qdev_get_child_bus(dev, "ssi");
  2119 + s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
2121 2120 }
2122 2121  
2123 2122 if (usb_enabled) {
... ... @@ -2229,7 +2228,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
2229 2228 DeviceState *dev;
2230 2229 dev = sysbus_create_simple("pxa2xx-ssp", pxa255_ssp[i].io_base,
2231 2230 s->pic[pxa255_ssp[i].irqn]);
2232   - s->ssp[i] = qdev_get_child_bus(dev, "ssi");
  2231 + s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
2233 2232 }
2234 2233  
2235 2234 if (usb_enabled) {
... ...
hw/qdev.c
... ... @@ -41,23 +41,18 @@ struct DeviceProperty {
41 41  
42 42 struct DeviceType {
43 43 const char *name;
44   - qdev_initfn init;
45   - void *opaque;
  44 + DeviceInfo *info;
46 45 int size;
47 46 DeviceType *next;
48 47 };
49 48  
50   -struct ChildBusList {
51   - const char *name;
52   - void *ptr;
53   - ChildBusList *next;
54   -};
  49 +/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
  50 +BusState *main_system_bus;
55 51  
56 52 static DeviceType *device_type_list;
57 53  
58 54 /* Register a new device type. */
59   -DeviceType *qdev_register(const char *name, int size, qdev_initfn init,
60   - void *opaque)
  55 +void qdev_register(const char *name, int size, DeviceInfo *info)
61 56 {
62 57 DeviceType *t;
63 58  
... ... @@ -68,16 +63,13 @@ DeviceType *qdev_register(const char *name, int size, qdev_initfn init,
68 63 device_type_list = t;
69 64 t->name = qemu_strdup(name);
70 65 t->size = size;
71   - t->init = init;
72   - t->opaque = opaque;
73   -
74   - return t;
  66 + t->info = info;
75 67 }
76 68  
77 69 /* Create a new device. This only initializes the device state structure
78 70 and allows properties to be set. qdev_init should be called to
79 71 initialize the actual device emulation. */
80   -DeviceState *qdev_create(void *bus, const char *name)
  72 +DeviceState *qdev_create(BusState *bus, const char *name)
81 73 {
82 74 DeviceType *t;
83 75 DeviceState *dev;
... ... @@ -88,14 +80,28 @@ DeviceState *qdev_create(void *bus, const char *name)
88 80 }
89 81 }
90 82 if (!t) {
91   - fprintf(stderr, "Unknown device '%s'\n", name);
92   - exit(1);
  83 + hw_error("Unknown device '%s'\n", name);
93 84 }
94 85  
95 86 dev = qemu_mallocz(t->size);
96 87 dev->name = name;
97 88 dev->type = t;
98   - dev->bus = bus;
  89 +
  90 + if (!bus) {
  91 + /* ???: This assumes system busses have no additional state. */
  92 + if (!main_system_bus) {
  93 + main_system_bus = qbus_create(BUS_TYPE_SYSTEM, sizeof(BusState),
  94 + NULL, "main-system-bus");
  95 + }
  96 + bus = main_system_bus;
  97 + }
  98 + if (t->info->bus_type != bus->type) {
  99 + /* TODO: Print bus type names. */
  100 + hw_error("Device '%s' on wrong bus type (%d/%d)", name,
  101 + t->info->bus_type, bus->type);
  102 + }
  103 + dev->parent_bus = bus;
  104 + LIST_INSERT_HEAD(&bus->children, dev, sibling);
99 105 return dev;
100 106 }
101 107  
... ... @@ -104,7 +110,14 @@ DeviceState *qdev_create(void *bus, const char *name)
104 110 calling this function. */
105 111 void qdev_init(DeviceState *dev)
106 112 {
107   - dev->type->init(dev, dev->type->opaque);
  113 + dev->type->info->init(dev, dev->type->info);
  114 +}
  115 +
  116 +/* Unlink device from bus and free the structure. */
  117 +void qdev_free(DeviceState *dev)
  118 +{
  119 + LIST_REMOVE(dev, sibling);
  120 + free(dev);
108 121 }
109 122  
110 123 static DeviceProperty *create_prop(DeviceState *dev, const char *name)
... ... @@ -169,9 +182,9 @@ CharDriverState *qdev_init_chardev(DeviceState *dev)
169 182 }
170 183 }
171 184  
172   -void *qdev_get_bus(DeviceState *dev)
  185 +BusState *qdev_get_parent_bus(DeviceState *dev)
173 186 {
174   - return dev->bus;
  187 + return dev->parent_bus;
175 188 }
176 189  
177 190 static DeviceProperty *find_prop(DeviceState *dev, const char *name)
... ... @@ -267,30 +280,18 @@ BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
267 280 return drives_table[index].bdrv;
268 281 }
269 282  
270   -void *qdev_get_child_bus(DeviceState *dev, const char *name)
  283 +BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
271 284 {
272   - ChildBusList *bus;
  285 + BusState *bus;
273 286  
274   - for (bus = dev->child_bus; bus; bus = bus->next) {
  287 + LIST_FOREACH(bus, &dev->child_bus, sibling) {
275 288 if (strcmp(name, bus->name) == 0) {
276   - return bus->ptr;
  289 + return bus;
277 290 }
278 291 }
279 292 return NULL;
280 293 }
281 294  
282   -void qdev_attach_child_bus(DeviceState *dev, const char *name, void *bus)
283   -{
284   - ChildBusList *p;
285   -
286   - assert(!qdev_get_child_bus(dev, name));
287   - p = qemu_mallocz(sizeof(*p));
288   - p->name = qemu_strdup(name);
289   - p->ptr = bus;
290   - p->next = dev->child_bus;
291   - dev->child_bus = p;
292   -}
293   -
294 295 static int next_scsi_bus;
295 296  
296 297 /* Create a scsi bus, and attach devices to it. */
... ... @@ -309,3 +310,19 @@ void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
309 310 attach(host, drives_table[index].bdrv, unit);
310 311 }
311 312 }
  313 +
  314 +BusState *qbus_create(BusType type, size_t size,
  315 + DeviceState *parent, const char *name)
  316 +{
  317 + BusState *bus;
  318 +
  319 + bus = qemu_mallocz(size);
  320 + bus->type = type;
  321 + bus->parent = parent;
  322 + bus->name = qemu_strdup(name);
  323 + LIST_INIT(&bus->children);
  324 + if (parent) {
  325 + LIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
  326 + }
  327 + return bus;
  328 +}
... ...
hw/qdev.h
... ... @@ -2,20 +2,20 @@
2 2 #define QDEV_H
3 3  
4 4 #include "hw.h"
  5 +#include "sys-queue.h"
5 6  
6 7 typedef struct DeviceType DeviceType;
7 8  
8 9 typedef struct DeviceProperty DeviceProperty;
9 10  
10   -typedef struct ChildBusList ChildBusList;
  11 +typedef struct BusState BusState;
11 12  
12 13 /* This structure should not be accessed directly. We declare it here
13 14 so that it can be embedded in individual device state structures. */
14   -struct DeviceState
15   -{
  15 +struct DeviceState {
16 16 const char *name;
17 17 DeviceType *type;
18   - void *bus;
  18 + BusState *parent_bus;
19 19 DeviceProperty *props;
20 20 int num_irq_sink;
21 21 qemu_irq *irq_sink;
... ... @@ -23,14 +23,32 @@ struct DeviceState
23 23 qemu_irq *gpio_out;
24 24 int num_gpio_in;
25 25 qemu_irq *gpio_in;
26   - ChildBusList *child_bus;
  26 + LIST_HEAD(, BusState) child_bus;
27 27 NICInfo *nd;
  28 + LIST_ENTRY(DeviceState) sibling;
  29 +};
  30 +
  31 +typedef enum {
  32 + BUS_TYPE_SYSTEM,
  33 + BUS_TYPE_PCI,
  34 + BUS_TYPE_SCSI,
  35 + BUS_TYPE_I2C,
  36 + BUS_TYPE_SSI
  37 +} BusType;
  38 +
  39 +struct BusState {
  40 + DeviceState *parent;
  41 + const char *name;
  42 + BusType type;
  43 + LIST_HEAD(, DeviceState) children;
  44 + LIST_ENTRY(BusState) sibling;
28 45 };
29 46  
30 47 /*** Board API. This should go away once we have a machine config file. ***/
31 48  
32   -DeviceState *qdev_create(void *bus, const char *name);
  49 +DeviceState *qdev_create(BusState *bus, const char *name);
33 50 void qdev_init(DeviceState *dev);
  51 +void qdev_free(DeviceState *dev);
34 52  
35 53 /* Set properties between creation and init. */
36 54 void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value);
... ... @@ -41,28 +59,33 @@ qemu_irq qdev_get_irq_sink(DeviceState *dev, int n);
41 59 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
42 60 void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
43 61  
44   -void *qdev_get_child_bus(DeviceState *dev, const char *name);
  62 +BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
45 63  
46 64 /*** Device API. ***/
47 65  
48   -typedef void (*qdev_initfn)(DeviceState *dev, void *opaque);
  66 +typedef struct DeviceInfo DeviceInfo;
  67 +
  68 +typedef void (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
49 69 typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv,
50 70 int unit);
51 71  
52   -DeviceType *qdev_register(const char *name, int size, qdev_initfn init,
53   - void *opaque);
  72 +struct DeviceInfo {
  73 + qdev_initfn init;
  74 + BusType bus_type;
  75 +};
  76 +
  77 +void qdev_register(const char *name, int size, DeviceInfo *info);
54 78  
55 79 /* Register device properties. */
56 80 void qdev_init_irq_sink(DeviceState *dev, qemu_irq_handler handler, int nirq);
57 81 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n);
58 82 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n);
59   -void qdev_attach_child_bus(DeviceState *dev, const char *name, void *bus);
60 83  
61 84 void scsi_bus_new(DeviceState *host, SCSIAttachFn attach);
62 85  
63 86 CharDriverState *qdev_init_chardev(DeviceState *dev);
64 87  
65   -void *qdev_get_bus(DeviceState *dev);
  88 +BusState *qdev_get_parent_bus(DeviceState *dev);
66 89 uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def);
67 90 void *qdev_get_prop_ptr(DeviceState *dev, const char *name);
68 91  
... ... @@ -76,4 +99,11 @@ void *qdev_get_prop_ptr(DeviceState *dev, const char *name);
76 99 #define DO_UPCAST(type, field, dev) container_of(dev, type, field)
77 100 #endif
78 101  
  102 +/*** BUS API. ***/
  103 +
  104 +BusState *qbus_create(BusType type, size_t size,
  105 + DeviceState *parent, const char *name);
  106 +
  107 +#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
  108 +
79 109 #endif
... ...
hw/realview.c
... ... @@ -109,7 +109,7 @@ static void realview_init(ram_addr_t ram_size,
109 109  
110 110 dev = sysbus_create_varargs("realview_pci", 0x60000000,
111 111 pic[48], pic[49], pic[50], pic[51], NULL);
112   - pci_bus = qdev_get_child_bus(dev, "pci");
  112 + pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
113 113 if (usb_enabled) {
114 114 usb_ohci_init_pci(pci_bus, 3, -1);
115 115 }
... ...
hw/sh_pci.c
... ... @@ -174,7 +174,8 @@ PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
174 174 int mem, reg, iop;
175 175  
176 176 p = qemu_mallocz(sizeof(SHPCIC));
177   - p->bus = pci_register_bus(set_irq, map_irq, pic, devfn_min, nirq);
  177 + p->bus = pci_register_bus(NULL, "pci",
  178 + set_irq, map_irq, pic, devfn_min, nirq);
178 179  
179 180 p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice),
180 181 -1, NULL, NULL);
... ...
hw/spitz.c
... ... @@ -706,12 +706,9 @@ static void corgi_ssp_init(SSISlave *dev)
706 706 CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, dev);
707 707  
708 708 qdev_init_gpio_in(&dev->qdev, corgi_ssp_gpio_cs, 3);
709   - s->bus[0] = ssi_create_bus();
710   - qdev_attach_child_bus(&dev->qdev, "ssi0", s->bus[0]);
711   - s->bus[1] = ssi_create_bus();
712   - qdev_attach_child_bus(&dev->qdev, "ssi1", s->bus[1]);
713   - s->bus[2] = ssi_create_bus();
714   - qdev_attach_child_bus(&dev->qdev, "ssi2", s->bus[2]);
  709 + s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
  710 + s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
  711 + s->bus[2] = ssi_create_bus(&dev->qdev, "ssi2");
715 712  
716 713 register_savevm("spitz_ssp", -1, 1, spitz_ssp_save, spitz_ssp_load, s);
717 714 }
... ...
hw/ssi.c
... ... @@ -10,16 +10,21 @@
10 10 #include "ssi.h"
11 11  
12 12 struct SSIBus {
13   - SSISlave *slave;
  13 + BusState qbus;
14 14 };
15 15  
16   -static void ssi_slave_init(DeviceState *dev, void *opaque)
  16 +static void ssi_slave_init(DeviceState *dev, DeviceInfo *base_info)
17 17 {
18   - SSISlaveInfo *info = opaque;
  18 + SSISlaveInfo *info = container_of(base_info, SSISlaveInfo, qdev);
19 19 SSISlave *s = SSI_SLAVE_FROM_QDEV(dev);
20   - SSIBus *bus = qdev_get_bus(dev);
  20 + SSIBus *bus;
  21 +
  22 + bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev));
  23 + if (LIST_FIRST(&bus->qbus.children) != dev
  24 + || LIST_NEXT(dev, sibling) != NULL) {
  25 + hw_error("Too many devices on SSI bus");
  26 + }
21 27  
22   - bus->slave = s;
23 28 s->info = info;
24 29 info->init(s);
25 30 }
... ... @@ -27,26 +32,34 @@ static void ssi_slave_init(DeviceState *dev, void *opaque)
27 32 void ssi_register_slave(const char *name, int size, SSISlaveInfo *info)
28 33 {
29 34 assert(size >= sizeof(SSISlave));
30   - qdev_register(name, size, ssi_slave_init, info);
  35 + info->qdev.init = ssi_slave_init;
  36 + info->qdev.bus_type = BUS_TYPE_SSI;
  37 + qdev_register(name, size, &info->qdev);
31 38 }
32 39  
33 40 DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
34 41 {
35 42 DeviceState *dev;
36   - dev = qdev_create(bus, name);
  43 + dev = qdev_create(&bus->qbus, name);
37 44 qdev_init(dev);
38 45 return dev;
39 46 }
40 47  
41   -SSIBus *ssi_create_bus(void)
  48 +SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
42 49 {
43   - return qemu_mallocz(sizeof(SSIBus));
  50 + BusState *bus;
  51 + bus = qbus_create(BUS_TYPE_SSI, sizeof(SSIBus), parent, name);
  52 + return FROM_QBUS(SSIBus, bus);
44 53 }
45 54  
46 55 uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
47 56 {
48   - if (!bus->slave) {
  57 + DeviceState *dev;
  58 + SSISlave *slave;
  59 + dev = LIST_FIRST(&bus->qbus.children);
  60 + if (!dev) {
49 61 return 0;
50 62 }
51   - return bus->slave->info->transfer(bus->slave, val);
  63 + slave = SSI_SLAVE_FROM_QDEV(dev);
  64 + return slave->info->transfer(slave, val);
52 65 }
... ...
hw/ssi.h
... ... @@ -17,6 +17,7 @@ typedef struct SSISlave SSISlave;
17 17  
18 18 /* Slave devices. */
19 19 typedef struct {
  20 + DeviceInfo qdev;
20 21 void (*init)(SSISlave *dev);
21 22 uint32_t (*transfer)(SSISlave *dev, uint32_t val);
22 23 } SSISlaveInfo;
... ... @@ -34,7 +35,7 @@ void ssi_register_slave(const char *name, int size, SSISlaveInfo *info);
34 35 DeviceState *ssi_create_slave(SSIBus *bus, const char *name);
35 36  
36 37 /* Master interface. */
37   -SSIBus *ssi_create_bus(void);
  38 +SSIBus *ssi_create_bus(DeviceState *parent, const char *name);
38 39  
39 40 uint32_t ssi_transfer(SSIBus *bus, uint32_t val);
40 41  
... ...
hw/stellaris.c
... ... @@ -874,11 +874,11 @@ static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id)
874 874 static void stellaris_i2c_init(SysBusDevice * dev)
875 875 {
876 876 stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
877   - i2c_bus *bus = i2c_init_bus();
  877 + i2c_bus *bus;
878 878 int iomemtype;
879 879  
880 880 sysbus_init_irq(dev, &s->irq);
881   - qdev_attach_child_bus(&dev->qdev, "i2c", bus);
  881 + bus = i2c_init_bus(&dev->qdev, "i2c");
882 882 s->bus = bus;
883 883  
884 884 iomemtype = cpu_register_io_memory(0, stellaris_i2c_readfn,
... ... @@ -1239,10 +1239,8 @@ static void stellaris_ssi_bus_init(SSISlave *dev)
1239 1239 {
1240 1240 stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1241 1241  
1242   - s->bus[0] = ssi_create_bus();
1243   - qdev_attach_child_bus(&dev->qdev, "ssi0", s->bus[0]);
1244   - s->bus[1] = ssi_create_bus();
1245   - qdev_attach_child_bus(&dev->qdev, "ssi1", s->bus[1]);
  1242 + s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
  1243 + s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
1246 1244 qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
1247 1245  
1248 1246 register_savevm("stellaris_ssi_bus", -1, 1,
... ... @@ -1320,7 +1318,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1320 1318 if (board->dc2 & (1 << 12)) {
1321 1319 DeviceState *dev;
1322 1320 dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
1323   - i2c = qdev_get_child_bus(dev, "i2c");
  1321 + i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
1324 1322 if (board->peripherals & BP_OLED_I2C) {
1325 1323 i2c_create_slave(i2c, "ssd0303", 0x3d);
1326 1324 }
... ...
hw/sysbus.c
... ... @@ -21,6 +21,11 @@
21 21 #include "sysbus.h"
22 22 #include "sysemu.h"
23 23  
  24 +typedef struct {
  25 + DeviceInfo qdev;
  26 + sysbus_initfn init;
  27 +} SysBusDeviceInfo;
  28 +
24 29 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
25 30 {
26 31 assert(n >= 0 && n < dev->num_irq);
... ... @@ -97,17 +102,24 @@ void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
97 102 dev->mmio[n].cb = cb;
98 103 }
99 104  
100   -static void sysbus_device_init(DeviceState *dev, void *opaque)
  105 +static void sysbus_device_init(DeviceState *dev, DeviceInfo *base)
101 106 {
102   - sysbus_initfn init = (sysbus_initfn)opaque;
  107 + SysBusDeviceInfo *info = container_of(base, SysBusDeviceInfo, qdev);
103 108  
104   - init(sysbus_from_qdev(dev));
  109 + info->init(sysbus_from_qdev(dev));
105 110 }
106 111  
107 112 void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init)
108 113 {
  114 + SysBusDeviceInfo *info;
  115 +
  116 + info = qemu_mallocz(sizeof(*info));
  117 + info->init = init;
  118 + info->qdev.init = sysbus_device_init;
  119 + info->qdev.bus_type = BUS_TYPE_SYSTEM;
  120 +
109 121 assert(size >= sizeof(SysBusDevice));
110   - qdev_register(name, size, sysbus_device_init, init);
  122 + qdev_register(name, size, &info->qdev);
111 123 }
112 124  
113 125 DeviceState *sysbus_create_varargs(const char *name,
... ...
hw/unin_pci.c
... ... @@ -175,7 +175,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
175 175 /* Use values found on a real PowerMac */
176 176 /* Uninorth main bus */
177 177 s = qemu_mallocz(sizeof(UNINState));
178   - s->bus = pci_register_bus(pci_unin_set_irq, pci_unin_map_irq,
  178 + s->bus = pci_register_bus(NULL, "pci",
  179 + pci_unin_set_irq, pci_unin_map_irq,
179 180 pic, 11 << 3, 4);
180 181  
181 182 pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read,
... ...
hw/versatile_pci.c
... ... @@ -118,9 +118,9 @@ static void pci_vpb_init(SysBusDevice *dev)
118 118 for (i = 0; i < 4; i++) {
119 119 sysbus_init_irq(dev, &s->irq[i]);
120 120 }
121   - bus = pci_register_bus(pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
  121 + bus = pci_register_bus(&dev->qdev, "pci",
  122 + pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
122 123 11 << 3, 4);
123   - qdev_attach_child_bus(&dev->qdev, "pci", bus);
124 124  
125 125 /* ??? Register memory space. */
126 126  
... ...
hw/versatilepb.c
... ... @@ -201,7 +201,7 @@ static void versatile_init(ram_addr_t ram_size,
201 201  
202 202 dev = sysbus_create_varargs("versatile_pci", 0x40000000,
203 203 sic[27], sic[28], sic[29], sic[30], NULL);
204   - pci_bus = qdev_get_child_bus(dev, "pci");
  204 + pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
205 205  
206 206 /* The Versatile PCI bridge does not provide access to PCI IO space,
207 207 so many of the qemu PCI devices are not useable. */
... ...