@@ -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);
@@ -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);
}
}
@@ -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)
@@ -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 */
@@ -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);
}
}
@@ -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 */
@@ -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);
}
}
@@ -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;
}
@@ -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)
@@ -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);
Signed-off-by: Anthony Liguori <aliguori@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(-)