Signed-off-by: Anthony Liguori <aligu...@us.ibm.com> --- hw/acpi_piix4.c | 7 +++-- hw/ide/pci.c | 11 +++++++- hw/kvmclock.c | 5 ++- hw/kvmclock.h | 5 ++- hw/pc.c | 49 ++++++++++++++++++++++++++++++++------- hw/pc.h | 37 ++++++++++++++++------------- hw/pc_piix.c | 68 ++++++++++++++++++++++++++++++++++-------------------- hw/piix_pci.c | 12 +++++++-- hw/usb-uhci.c | 4 +- hw/usb-uhci.h | 2 +- 10 files changed, 134 insertions(+), 66 deletions(-)
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index d9075e6..401baaa 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -372,14 +372,15 @@ static int piix4_pm_initfn(PCIDevice *dev) return 0; } -i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, - qemu_irq sci_irq, qemu_irq cmos_s3, qemu_irq smi_irq, - int kvm_enabled) +i2c_bus *piix4_pm_init(PCIBus *bus, DeviceState **pdev, int devfn, + uint32_t smb_io_base, qemu_irq sci_irq, + qemu_irq cmos_s3, qemu_irq smi_irq, int kvm_enabled) { PCIDevice *dev; PIIX4PMState *s; dev = pci_create(bus, devfn, "PIIX4_PM"); + *pdev = &dev->qdev; qdev_prop_set_uint32(&dev->qdev, "smb_io_base", smb_io_base); s = DO_UPCAST(PIIX4PMState, dev, dev); diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 49b823d..897bca2 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -498,9 +498,16 @@ void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table) int i; for (i = 0; i < 4; i++) { - if (hd_table[i] == NULL) + char name[32]; + IDEDevice *c; + + if (hd_table[i] == NULL) { continue; - ide_create_drive(d->bus+bus[i], unit[i], hd_table[i]); + } + + c = ide_create_drive(d->bus+bus[i], unit[i], hd_table[i]); + snprintf(name, sizeof(name), "drive[%d]", i); + qdev_property_add_child(&dev->qdev, name, &c->qdev, NULL); } } diff --git a/hw/kvmclock.c b/hw/kvmclock.c index 5388bc4..ddfaf3c 100644 --- a/hw/kvmclock.c +++ b/hw/kvmclock.c @@ -99,13 +99,14 @@ static SysBusDeviceInfo kvmclock_info = { }; /* Note: Must be called after VCPU initialization. */ -void kvmclock_create(void) +DeviceState *kvmclock_create(void) { if (kvm_enabled() && first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE) | (1ULL << KVM_FEATURE_CLOCKSOURCE2))) { - sysbus_create_simple("kvmclock", -1, NULL); + return sysbus_create_simple("kvmclock", -1, NULL); } + return NULL; } static void kvmclock_register_device(void) diff --git a/hw/kvmclock.h b/hw/kvmclock.h index 252ea13..40dda86 100644 --- a/hw/kvmclock.h +++ b/hw/kvmclock.h @@ -13,12 +13,13 @@ #ifdef CONFIG_KVM -void kvmclock_create(void); +DeviceState *kvmclock_create(void); #else /* CONFIG_KVM */ -static inline void kvmclock_create(void) +static inline DeviceState *kvmclock_create(void) { + return NULL; } #endif /* !CONFIG_KVM */ diff --git a/hw/pc.c b/hw/pc.c index 2fd124a..47e6fb9 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -849,15 +849,17 @@ static const int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 }; static const int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc }; static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 }; -void pc_init_ne2k_isa(NICInfo *nd) +DeviceState *pc_init_ne2k_isa(NICInfo *nd) { static int nb_ne2k = 0; + DeviceState *dev; if (nb_ne2k == NE2000_NB_MAX) - return; - isa_ne2000_init(ne2000_io[nb_ne2k], - ne2000_irq[nb_ne2k], nd); + return NULL; + dev = isa_ne2000_init(ne2000_io[nb_ne2k], + ne2000_irq[nb_ne2k], nd); nb_ne2k++; + return dev; } int cpu_is_bsp(CPUState *env) @@ -1118,7 +1120,9 @@ static void cpu_request_exit(void *opaque, int irq, int level) } } -void pc_basic_device_init(qemu_irq *gsi, +void pc_basic_device_init(DeviceState *board, + DeviceState *superio, + qemu_irq *gsi, ISADevice **rtc_state, ISADevice **floppy, bool no_vmport) @@ -1142,33 +1146,51 @@ void pc_basic_device_init(qemu_irq *gsi, sysbus_connect_irq(sysbus_from_qdev(hpet), i, gsi[i]); } rtc_irq = qdev_get_gpio_in(hpet, 0); + + qdev_property_add_child(board, "hpet", hpet, NULL); } } *rtc_state = rtc_init(2000, rtc_irq); + qdev_property_add_child(superio, "rtc", &(*rtc_state)->qdev, NULL); qemu_register_boot_set(pc_boot_set, *rtc_state); pit = pit_init(0x40, 0); + qdev_property_add_child(superio, "pit", &pit->qdev, NULL); + + /* FIXME not qdev */ pcspk_init(pit); for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { - serial_isa_init(i, serial_hds[i]); + DeviceState *dev; + char name[1024]; + + dev = serial_isa_init(i, serial_hds[i]); + snprintf(name, sizeof(name), "serial[%d]", i); + qdev_property_add_child(board, name, dev, NULL); } } for(i = 0; i < MAX_PARALLEL_PORTS; i++) { if (parallel_hds[i]) { - parallel_init(i, parallel_hds[i]); + DeviceState *dev; + char name[1024]; + + dev = parallel_init(i, parallel_hds[i]); + snprintf(name, sizeof(name), "parallel[%d]", i); + qdev_property_add_child(board, name, dev, NULL); } } a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2); i8042 = isa_create_simple("i8042"); + qdev_property_add_child(superio, "pckbd", &i8042->qdev, NULL); i8042_setup_a20_line(i8042, &a20_line[0]); if (!no_vmport) { vmport_init(); vmmouse = isa_try_create("vmmouse"); + qdev_property_add_child(superio, "vmmouse", &vmmouse->qdev, NULL); } else { vmmouse = NULL; } @@ -1178,23 +1200,32 @@ void pc_basic_device_init(qemu_irq *gsi, } port92 = isa_create_simple("port92"); port92_init(port92, &a20_line[1]); + qdev_property_add_child(superio, "port92", &port92->qdev, NULL); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); + + /* FIXME not qdev */ DMA_init(0, cpu_exit_irq); for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); } *floppy = fdctrl_init_isa(fd); + qdev_property_add_child(superio, "floppy", &(*floppy)->qdev, NULL); } -void pc_pci_device_init(PCIBus *pci_bus) +void pc_pci_device_init(PCIBus *pci_bus, DeviceState *board) { int max_bus; int bus; max_bus = drive_get_max_bus(IF_SCSI); for (bus = 0; bus <= max_bus; bus++) { - pci_create_simple(pci_bus, -1, "lsi53c895a"); + DeviceState *dev; + char name[32]; + + snprintf(name, sizeof(name), "scsi[%d]", bus); + dev = &pci_create_simple(pci_bus, -1, "lsi53c895a")->qdev; + qdev_property_add_child(board, name, dev, NULL); } } diff --git a/hw/pc.h b/hw/pc.h index 8d2e553..cd64755 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -20,39 +20,39 @@ SerialState *serial_mm_init(MemoryRegion *address_space, target_phys_addr_t base, int it_shift, qemu_irq irq, int baudbase, CharDriverState *chr, enum device_endian); -static inline bool serial_isa_init(int index, CharDriverState *chr) +static inline DeviceState *serial_isa_init(int index, CharDriverState *chr) { ISADevice *dev; dev = isa_try_create("isa-serial"); if (!dev) { - return false; + return NULL; } qdev_prop_set_uint32(&dev->qdev, "index", index); qdev_prop_set_chr(&dev->qdev, "chardev", chr); if (qdev_init(&dev->qdev) < 0) { - return false; + return NULL; } - return true; + return &dev->qdev; } void serial_set_frequency(SerialState *s, uint32_t frequency); /* parallel.c */ -static inline bool parallel_init(int index, CharDriverState *chr) +static inline DeviceState *parallel_init(int index, CharDriverState *chr) { ISADevice *dev; dev = isa_try_create("isa-parallel"); if (!dev) { - return false; + return NULL; } qdev_prop_set_uint32(&dev->qdev, "index", index); qdev_prop_set_chr(&dev->qdev, "chardev", chr); if (qdev_init(&dev->qdev) < 0) { - return false; + return NULL; } - return true; + return &dev->qdev; } bool parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, @@ -140,16 +140,18 @@ void pc_memory_init(MemoryRegion *system_memory, MemoryRegion **ram_memory); qemu_irq *pc_allocate_cpu_irq(void); DeviceState *pc_vga_init(PCIBus *pci_bus); -void pc_basic_device_init(qemu_irq *gsi, +void pc_basic_device_init(DeviceState *board, + DeviceState *superio, + qemu_irq *gsi, ISADevice **rtc_state, ISADevice **floppy, bool no_vmport); -void pc_init_ne2k_isa(NICInfo *nd); +DeviceState *pc_init_ne2k_isa(NICInfo *nd); void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, const char *boot_device, ISADevice *floppy, BusState *ide0, BusState *ide1, ISADevice *s); -void pc_pci_device_init(PCIBus *pci_bus); +void pc_pci_device_init(PCIBus *pci_bus, DeviceState *board); typedef void (*cpu_set_smm_t)(int smm, void *arg); void cpu_smm_register(cpu_set_smm_t callback, void *arg); @@ -164,9 +166,9 @@ int acpi_table_add(const char *table_desc); /* acpi_piix.c */ -i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, - qemu_irq sci_irq, qemu_irq cmos_s3, qemu_irq smi_irq, - int kvm_enabled); +i2c_bus *piix4_pm_init(PCIBus *bus, DeviceState **pdev, int devfn, + uint32_t smb_io_base, qemu_irq sci_irq, + qemu_irq cmos_s3, qemu_irq smi_irq, int kvm_enabled); void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr); /* hpet.c */ @@ -181,6 +183,7 @@ struct PCII440FXState; typedef struct PCII440FXState PCII440FXState; PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, + DeviceState **i440fx, DeviceState **piix3, qemu_irq *pic, MemoryRegion *address_space_mem, MemoryRegion *address_space_io, @@ -227,7 +230,7 @@ DeviceState *pci_cirrus_vga_init(PCIBus *bus); DeviceState *isa_cirrus_vga_init(MemoryRegion *address_space); /* ne2000.c */ -static inline bool isa_ne2000_init(int base, int irq, NICInfo *nd) +static inline DeviceState *isa_ne2000_init(int base, int irq, NICInfo *nd) { ISADevice *dev; @@ -235,13 +238,13 @@ static inline bool isa_ne2000_init(int base, int irq, NICInfo *nd) dev = isa_try_create("ne2k_isa"); if (!dev) { - return false; + return NULL; } qdev_prop_set_uint32(&dev->qdev, "iobase", base); qdev_prop_set_uint32(&dev->qdev, "irq", irq); qdev_set_nic_properties(&dev->qdev, nd); qdev_init_nofail(&dev->qdev); - return true; + return &dev->qdev; } /* e820 types */ diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 166c2fc..e4e2c26 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -53,7 +53,7 @@ static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; -static void ioapic_init(GSIState *gsi_state) +static DeviceState *ioapic_init(GSIState *gsi_state) { DeviceState *dev; SysBusDevice *d; @@ -67,6 +67,8 @@ static void ioapic_init(GSIState *gsi_state) for (i = 0; i < IOAPIC_NUM_PINS; i++) { gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i); } + + return dev; } /* PC hardware initialisation */ @@ -99,12 +101,18 @@ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *ram_memory; MemoryRegion *pci_memory; MemoryRegion *rom_memory; + DeviceState *superio = NULL; + DeviceState *board; DeviceState *dev; + board = qdev_create(NULL, "container"); + qdev_property_add_child(qdev_get_root(), "pc", board, NULL); + pc_cpus_init(cpu_model); if (kvmclock_enabled) { - kvmclock_create(); + dev = kvmclock_create(); + qdev_property_add_child(board, "kvmclock", dev, NULL); } if (ram_size >= 0xe0000000 ) { @@ -136,7 +144,10 @@ static void pc_init1(MemoryRegion *system_memory, gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS); if (pci_enabled) { - pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, gsi, + DeviceState *i440fx, *piix3; + + pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, + &i440fx, &piix3, gsi, system_memory, system_io, ram_size, below_4g_mem_size, 0x100000000ULL - below_4g_mem_size, @@ -145,6 +156,9 @@ static void pc_init1(MemoryRegion *system_memory, ? 0 : ((uint64_t)1 << 62)), pci_memory, ram_memory); + + qdev_property_add_child(board, "host-controller", i440fx, NULL); + superio = piix3; } else { pci_bus = NULL; i440fx_state = NULL; @@ -164,30 +178,39 @@ static void pc_init1(MemoryRegion *system_memory, gsi_state->i8259_irq[i] = i8259[i]; } if (pci_enabled) { - ioapic_init(gsi_state); + dev = ioapic_init(gsi_state); + qdev_property_add_child(board, "ioapic", dev, NULL); } pc_register_ferr_irq(gsi[13]); dev = pc_vga_init(pci_enabled? pci_bus: NULL); if (dev) { - qdev_property_add_child(qdev_get_root(), "vga", dev, NULL); + qdev_property_add_child(board, "vga", dev, NULL); } if (xen_enabled()) { - pci_create_simple(pci_bus, -1, "xen-platform"); + dev = &pci_create_simple(pci_bus, -1, "xen-platform")->qdev; + qdev_property_add_child(board, "xen", dev, NULL); } /* init basic PC hardware */ - pc_basic_device_init(gsi, &rtc_state, &floppy, xen_enabled()); + pc_basic_device_init(board, superio, gsi, &rtc_state, + &floppy, xen_enabled()); for(i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; + DeviceState *dev; + char buffer[32]; - if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) - pc_init_ne2k_isa(nd); - else - pci_nic_init_nofail(nd, "e1000", NULL); + if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0)) { + dev = pc_init_ne2k_isa(nd); + } else { + dev = &pci_nic_init_nofail(nd, "e1000", NULL)->qdev; + } + + snprintf(buffer, sizeof(buffer), "nic[%d]", i); + qdev_property_add_child(board, buffer, dev, NULL); } ide_drive_get(hd, MAX_IDE_BUS); @@ -200,33 +223,27 @@ static void pc_init1(MemoryRegion *system_memory, } idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); + qdev_property_add_child(board, "ide", &dev->qdev, NULL); } else { for(i = 0; i < MAX_IDE_BUS; i++) { ISADevice *dev; + char buffer[32]; dev = isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); idebus[i] = qdev_get_child_bus(&dev->qdev, "ide.0"); + snprintf(buffer, sizeof(buffer), "ide[%d]", i); + qdev_property_add_child(board, buffer, &dev->qdev, NULL); } } - /* FIXME there's some major spaghetti here. Somehow we create the devices - * on the PIIX before we actually create it. We create the PIIX3 deep in - * the recess of the i440fx creation too and then lose the DeviceState. - * - * For now, let's "fix" this by making judicious use of paths. This is not - * generally the right way to do this. - */ - - qdev_property_add_child(qdev_resolve_path("/i440fx/piix3", NULL), - "rtc", (DeviceState *)rtc_state, NULL); - audio_init(gsi, pci_enabled ? pci_bus : NULL); pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, floppy, idebus[0], idebus[1], rtc_state); if (pci_enabled && usb_enabled) { - usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); + dev = usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); + qdev_property_add_child(board, "usb-host", dev, NULL); } if (pci_enabled && acpi_enabled) { @@ -239,14 +256,15 @@ static void pc_init1(MemoryRegion *system_memory, } smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); /* TODO: Populate SPD eeprom data. */ - smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, + smbus = piix4_pm_init(pci_bus, &dev, piix3_devfn + 3, 0xb100, gsi[9], *cmos_s3, *smi_irq, kvm_enabled()); + qdev_property_add_child(superio, "pm", dev, NULL); smbus_eeprom_init(smbus, 8, NULL, 0); } if (pci_enabled) { - pc_pci_device_init(pci_bus); + pc_pci_device_init(pci_bus, board); } } diff --git a/hw/piix_pci.c b/hw/piix_pci.c index d785d4b..e690ee1 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -262,6 +262,7 @@ static int i440fx_initfn(PCIDevice *dev) static PCIBus *i440fx_common_init(const char *device_name, PCII440FXState **pi440fx_state, + DeviceState **i440fx, int *piix3_devfn, qemu_irq *pic, MemoryRegion *address_space_mem, @@ -288,7 +289,7 @@ static PCIBus *i440fx_common_init(const char *device_name, address_space_io, 0); s->bus = b; qdev_init_nofail(dev); - qdev_property_add_child(qdev_get_root(), "i440fx", dev, NULL); + *i440fx = dev; d = pci_create_simple(b, 0, device_name); *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d); @@ -296,6 +297,9 @@ static PCIBus *i440fx_common_init(const char *device_name, f->system_memory = address_space_mem; f->pci_address_space = pci_address_space; f->ram_memory = ram_memory; + + qdev_property_add_child(dev, "i440fx", &d->qdev, NULL); + memory_region_init_alias(&f->pci_hole, "pci-hole", f->pci_address_space, pci_hole_start, pci_hole_size); memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole); @@ -325,7 +329,7 @@ static PCIBus *i440fx_common_init(const char *device_name, pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, PIIX_NUM_PIRQS); - qdev_property_add_child(dev, "piix3", &piix3->dev.qdev, NULL); + qdev_property_add_child(&d->qdev, "piix3", &piix3->dev.qdev, NULL); } piix3->pic = pic; @@ -344,6 +348,7 @@ static PCIBus *i440fx_common_init(const char *device_name, } PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, + DeviceState **i440fx, DeviceState **piix3, qemu_irq *pic, MemoryRegion *address_space_mem, MemoryRegion *address_space_io, @@ -357,11 +362,12 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, { PCIBus *b; - b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, + b = i440fx_common_init("i440FX", pi440fx_state, i440fx, piix3_devfn, pic, address_space_mem, address_space_io, ram_size, pci_hole_start, pci_hole_size, pci_hole64_size, pci_hole64_size, pci_memory, ram_memory); + *piix3 = &(*pi440fx_state)->piix3->dev.qdev; return b; } diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index f9e3ea5..3e4456a 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -1269,9 +1269,9 @@ static void uhci_register(void) } device_init(uhci_register); -void usb_uhci_piix3_init(PCIBus *bus, int devfn) +DeviceState *usb_uhci_piix3_init(PCIBus *bus, int devfn) { - pci_create_simple(bus, devfn, "piix3-usb-uhci"); + return &pci_create_simple(bus, devfn, "piix3-usb-uhci")->qdev; } void usb_uhci_piix4_init(PCIBus *bus, int devfn) diff --git a/hw/usb-uhci.h b/hw/usb-uhci.h index 3e4d377..1fef610 100644 --- a/hw/usb-uhci.h +++ b/hw/usb-uhci.h @@ -3,7 +3,7 @@ #include "qemu-common.h" -void usb_uhci_piix3_init(PCIBus *bus, int devfn); +DeviceState *usb_uhci_piix3_init(PCIBus *bus, int devfn); void usb_uhci_piix4_init(PCIBus *bus, int devfn); void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn); -- 1.7.4.1