* [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more. @ 2009-07-03 10:22 Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 01/13] qdev: rework device properties Gerd Hoffmann ` (12 more replies) 0 siblings, 13 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Hi, This patch series has all qdev patches which I consider ready for being merged, excluding the patches which are already in anthonys patch queue. What is in there? First the qdev property rework. Quite big one, but as it puts the way properties work upside down it can hardly be split into smaller pieces. Support for property default values added since I posted it last time. The patch description is much better too. Otherwise it is unchanged. The other patches are building on top of the properties. They are a bunch of little, self-contained and friendly patches. They bring: * A new, generic -device switch to add devices to your VM. * Support for attaching user-specified ids to devices. * A few more devices being switched to qdev. My complete qdev patch queue (including some not-yet posted bits) is available here: http://git.et.redhat.com/?p=qemu-kraxel.git;a=shortlog;h=refs/heads/qdev.v9 cheers, Gerd ^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 01/13] qdev: rework device properties. 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 02/13] qdev: factor out driver search to qdev_find_info() Gerd Hoffmann ` (11 subsequent siblings) 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann This patch is a major overhaul of the device properties. The properties are saved directly in the device state struct now, the linked list of property values is gone. Advantages: * We don't have to maintain the list with the property values. * The value in the property list and the value actually used by the device can't go out of sync any more (used to happen for the pci.devfn == -1 case) because there is only one place where the value is stored. * A record describing the property is required now, you can't set random properties any more. There are bus-specific and device-specific properties. The former should be used for properties common to all bus drivers. Typical use case is bus addressing, i.e. pci.devfn and i2c.address. Properties have a PropertyInfo struct attached with name, size and function pointers to parse and print properties. A few common property types have PropertyInfos defined in qdev-properties.c. Drivers are free to implement their own very special property parsers if needed. Properties can have default values. If unset they are zero-filled. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- Makefile | 2 +- hw/arm_sysctl.c | 20 ++++- hw/armv7m.c | 22 ++++- hw/axis_dev88.c | 2 +- hw/esp.c | 14 ++-- hw/etraxfs.c | 2 +- hw/etraxfs_pic.c | 18 ++++- hw/i2c.c | 11 ++- hw/i2c.h | 2 +- hw/integratorcp.c | 30 +++++-- hw/mips_malta.c | 4 +- hw/musicpal.c | 2 +- hw/pc.c | 4 +- hw/pci.c | 17 +++- hw/pcnet.c | 19 ++++- hw/qdev-properties.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.c | 141 +++++---------------------------- hw/qdev.h | 60 ++++++++------ hw/smbus_eeprom.c | 10 ++- hw/smc91c111.c | 2 +- hw/stellaris.c | 2 +- hw/sun4m.c | 3 +- hw/syborg.c | 4 +- hw/syborg_fb.c | 45 +++++++---- hw/syborg_interrupt.c | 21 ++++- hw/syborg_keyboard.c | 21 ++++- hw/syborg_pointer.c | 29 ++++++-- hw/syborg_serial.c | 21 ++++- hw/syborg_timer.c | 11 ++- hw/xilinx.h | 12 ++-- hw/xilinx_ethlite.c | 29 ++++++-- hw/xilinx_intc.c | 18 ++++- hw/xilinx_timer.c | 32 ++++++-- 33 files changed, 574 insertions(+), 263 deletions(-) create mode 100644 hw/qdev-properties.c diff --git a/Makefile b/Makefile index 66c28e5..39143ba 100644 --- a/Makefile +++ b/Makefile @@ -108,7 +108,7 @@ obj-y += bt-hci-csr.o obj-y += buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o obj-y += qemu-char.o aio.o net-checksum.o savevm.o cache-utils.o obj-y += msmouse.o ps2.o -obj-y += qdev.o ssi.o +obj-y += qdev.o qdev-properties.o ssi.o obj-$(CONFIG_BRLAPI) += baum.o diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c index c9d1e3f..bb005c8 100644 --- a/hw/arm_sysctl.c +++ b/hw/arm_sysctl.c @@ -194,7 +194,6 @@ static void arm_sysctl_init1(SysBusDevice *dev) arm_sysctl_state *s = FROM_SYSBUS(arm_sysctl_state, dev); int iomemtype; - s->sys_id = qdev_get_prop_int(&dev->qdev, "sys_id", 0); /* The MPcore bootloader uses these flags to start secondary CPUs. We don't use a bootloader, so do this here. */ s->flags = 3; @@ -210,15 +209,28 @@ void arm_sysctl_init(uint32_t base, uint32_t sys_id) DeviceState *dev; dev = qdev_create(NULL, "realview_sysctl"); - qdev_set_prop_int(dev, "sys_id", sys_id); + qdev_prop_set_uint32(dev, "sys_id", sys_id); qdev_init(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); } +static SysBusDeviceInfo arm_sysctl_info = { + .init = arm_sysctl_init1, + .qdev.name = "realview_sysctl", + .qdev.size = sizeof(arm_sysctl_state), + .qdev.props = (Property[]) { + { + .name = "sys_id", + .info = &qdev_prop_uint32, + .offset = offsetof(arm_sysctl_state, sys_id), + }, + {/* end of list */} + } +}; + static void arm_sysctl_register_devices(void) { - sysbus_register_dev("realview_sysctl", sizeof(arm_sysctl_state), - arm_sysctl_init1); + sysbus_register_withprop(&arm_sysctl_info); } device_init(arm_sysctl_register_devices) diff --git a/hw/armv7m.c b/hw/armv7m.c index 297a3e1..2e66d7e 100644 --- a/hw/armv7m.c +++ b/hw/armv7m.c @@ -127,7 +127,6 @@ static void bitband_init(SysBusDevice *dev) BitBandState *s = FROM_SYSBUS(BitBandState, dev); int iomemtype; - s->base = qdev_get_prop_int(&dev->qdev, "base", 0); iomemtype = cpu_register_io_memory(bitband_readfn, bitband_writefn, &s->base); sysbus_init_mmio(dev, 0x02000000, iomemtype); @@ -138,12 +137,12 @@ static void armv7m_bitband_init(void) DeviceState *dev; dev = qdev_create(NULL, "ARM,bitband-memory"); - qdev_set_prop_int(dev, "base", 0x20000000); + qdev_prop_set_uint32(dev, "base", 0x20000000); qdev_init(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x22000000); dev = qdev_create(NULL, "ARM,bitband-memory"); - qdev_set_prop_int(dev, "base", 0x40000000); + qdev_prop_set_uint32(dev, "base", 0x40000000); qdev_init(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x42000000); } @@ -238,10 +237,23 @@ qemu_irq *armv7m_init(int flash_size, int sram_size, return pic; } +static SysBusDeviceInfo bitband_info = { + .init = bitband_init, + .qdev.name = "ARM,bitband-memory", + .qdev.size = sizeof(BitBandState), + .qdev.props = (Property[]) { + { + .name = "base", + .info = &qdev_prop_hex32, + .offset = offsetof(BitBandState, base), + }, + {/* end of list */} + } +}; + static void armv7m_register_devices(void) { - sysbus_register_dev("ARM,bitband-memory", sizeof(BitBandState), - bitband_init); + sysbus_register_withprop(&bitband_info); } device_init(armv7m_register_devices) diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c index 79a4d71..f93f431 100644 --- a/hw/axis_dev88.c +++ b/hw/axis_dev88.c @@ -297,7 +297,7 @@ void axisdev88_init (ram_addr_t ram_size, cpu_irq = cris_pic_init_cpu(env); dev = qdev_create(NULL, "etraxfs,pic"); /* FIXME: Is there a proper way to signal vectors to the CPU core? */ - qdev_set_prop_ptr(dev, "interrupt_vector", &env->interrupt_vector); + qdev_prop_set_ptr(dev, "interrupt_vector", &env->interrupt_vector); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, 0x3001c000); diff --git a/hw/esp.c b/hw/esp.c index 88d42a1..9eacccb 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -650,12 +650,14 @@ void esp_init(target_phys_addr_t espaddr, int it_shift, { DeviceState *dev; SysBusDevice *s; + ESPState *esp; dev = qdev_create(NULL, "esp"); - qdev_set_prop_ptr(dev, "dma_memory_read", dma_memory_read); - qdev_set_prop_ptr(dev, "dma_memory_write", dma_memory_write); - qdev_set_prop_ptr(dev, "dma_opaque", dma_opaque); - qdev_set_prop_int(dev, "it_shift", it_shift); + esp = DO_UPCAST(ESPState, busdev.qdev, dev); + esp->dma_memory_read = dma_memory_read; + esp->dma_memory_write = dma_memory_write; + esp->dma_opaque = dma_opaque; + esp->it_shift = it_shift; qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_connect_irq(s, 0, irq); @@ -668,11 +670,7 @@ static void esp_init1(SysBusDevice *dev) int esp_io_memory; sysbus_init_irq(dev, &s->irq); - s->it_shift = qdev_get_prop_int(&dev->qdev, "it_shift", -1); assert(s->it_shift != -1); - s->dma_memory_read = qdev_get_prop_ptr(&dev->qdev, "dma_memory_read"); - s->dma_memory_write = qdev_get_prop_ptr(&dev->qdev, "dma_memory_write"); - s->dma_opaque = qdev_get_prop_ptr(&dev->qdev, "dma_opaque"); esp_io_memory = cpu_register_io_memory(esp_mem_read, esp_mem_write, s); sysbus_init_mmio(dev, ESP_REGS << s->it_shift, esp_io_memory); diff --git a/hw/etraxfs.c b/hw/etraxfs.c index 94cd6bc..c2eca52 100644 --- a/hw/etraxfs.c +++ b/hw/etraxfs.c @@ -88,7 +88,7 @@ void bareetraxfs_init (ram_addr_t ram_size, cpu_irq = cris_pic_init_cpu(env); dev = qdev_create(NULL, "etraxfs,pic"); /* FIXME: Is there a proper way to signal vectors to the CPU core? */ - qdev_set_prop_ptr(dev, "interrupt_vector", &env->interrupt_vector); + qdev_prop_set_ptr(dev, "interrupt_vector", &env->interrupt_vector); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, 0x3001c000); diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c index 1c67427..e627218 100644 --- a/hw/etraxfs_pic.c +++ b/hw/etraxfs_pic.c @@ -140,7 +140,6 @@ static void etraxfs_pic_init(SysBusDevice *dev) struct etrax_pic *s = FROM_SYSBUS(typeof (*s), dev); int intr_vect_regs; - s->interrupt_vector = qdev_get_prop_ptr(&dev->qdev, "interrupt_vector"); qdev_init_gpio_in(&dev->qdev, irq_handler, 32); sysbus_init_irq(dev, &s->parent_irq); sysbus_init_irq(dev, &s->parent_nmi); @@ -149,10 +148,23 @@ static void etraxfs_pic_init(SysBusDevice *dev) sysbus_init_mmio(dev, R_MAX * 4, intr_vect_regs); } +static SysBusDeviceInfo etraxfs_pic_info = { + .init = etraxfs_pic_init, + .qdev.name = "etraxfs,pic", + .qdev.size = sizeof(struct etrax_pic), + .qdev.props = (Property[]) { + { + .name = "interrupt_vector", + .info = &qdev_prop_ptr, + .offset = offsetof(struct etrax_pic, interrupt_vector), + }, + {/* end of list */} + } +}; + static void etraxfs_pic_register(void) { - sysbus_register_dev("etraxfs,pic", sizeof (struct etrax_pic), - etraxfs_pic_init); + sysbus_register_withprop(&etraxfs_pic_info); } device_init(etraxfs_pic_register) diff --git a/hw/i2c.c b/hw/i2c.c index 98aa7fc..42a5d7a 100644 --- a/hw/i2c.c +++ b/hw/i2c.c @@ -20,6 +20,14 @@ struct i2c_bus static struct BusInfo i2c_bus_info = { .name = "I2C", .size = sizeof(i2c_bus), + .props = (Property[]) { + { + .name = "address", + .info = &qdev_prop_uint32, + .offset = offsetof(struct i2c_slave, address), + }, + {/* end of list */} + } }; static void i2c_bus_save(QEMUFile *f, void *opaque) @@ -151,7 +159,6 @@ static void i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base) i2c_slave *s = I2C_SLAVE_FROM_QDEV(dev); s->info = info; - s->address = qdev_get_prop_int(dev, "address", 0); info->init(s); } @@ -169,7 +176,7 @@ DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, int addr) DeviceState *dev; dev = qdev_create(&bus->qbus, name); - qdev_set_prop_int(dev, "address", addr); + qdev_prop_set_uint32(dev, "address", addr); qdev_init(dev); return dev; } diff --git a/hw/i2c.h b/hw/i2c.h index c4df399..479ff4b 100644 --- a/hw/i2c.h +++ b/hw/i2c.h @@ -40,7 +40,7 @@ struct i2c_slave I2CSlaveInfo *info; /* Remaining fields for internal use by the I2C code. */ - int address; + uint32_t address; }; i2c_bus *i2c_init_bus(DeviceState *parent, const char *name); diff --git a/hw/integratorcp.c b/hw/integratorcp.c index 50eae0c..ddc8d85 100644 --- a/hw/integratorcp.c +++ b/hw/integratorcp.c @@ -17,6 +17,7 @@ typedef struct { SysBusDevice busdev; + uint32_t memsz; uint32_t flash_offset; uint32_t cm_osc; uint32_t cm_ctrl; @@ -230,23 +231,21 @@ static void integratorcm_init(SysBusDevice *dev) { int iomemtype; integratorcm_state *s = FROM_SYSBUS(integratorcm_state, dev); - int memsz; - memsz = qdev_get_prop_int(&dev->qdev, "memsz", 0); s->cm_osc = 0x01000048; /* ??? What should the high bits of this value be? */ s->cm_auxosc = 0x0007feff; s->cm_sdram = 0x00011122; - if (memsz >= 256) { + if (s->memsz >= 256) { integrator_spd[31] = 64; s->cm_sdram |= 0x10; - } else if (memsz >= 128) { + } else if (s->memsz >= 128) { integrator_spd[31] = 32; s->cm_sdram |= 0x0c; - } else if (memsz >= 64) { + } else if (s->memsz >= 64) { integrator_spd[31] = 16; s->cm_sdram |= 0x08; - } else if (memsz >= 32) { + } else if (s->memsz >= 32) { integrator_spd[31] = 4; s->cm_sdram |= 0x04; } else { @@ -475,7 +474,7 @@ static void integratorcp_init(ram_addr_t ram_size, cpu_register_physical_memory(0x80000000, ram_size, ram_offset | IO_MEM_RAM); dev = qdev_create(NULL, "integrator_core"); - qdev_set_prop_int(dev, "memsz", ram_size >> 20); + qdev_prop_set_uint32(dev, "memsz", ram_size >> 20); qdev_init(dev); sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000); @@ -522,11 +521,24 @@ static void integratorcp_machine_init(void) machine_init(integratorcp_machine_init); +static SysBusDeviceInfo core_info = { + .init = integratorcm_init, + .qdev.name = "integrator_core", + .qdev.size = sizeof(integratorcm_state), + .qdev.props = (Property[]) { + { + .name = "memsz", + .info = &qdev_prop_uint32, + .offset = offsetof(integratorcm_state, memsz), + }, + {/* end of list */} + } +}; + static void integratorcp_register_devices(void) { sysbus_register_dev("integrator_pic", sizeof(icp_pic_state), icp_pic_init); - sysbus_register_dev("integrator_core", sizeof(integratorcm_state), - integratorcm_init); + sysbus_register_withprop(&core_info); } device_init(integratorcp_register_devices) diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 853ec2b..7728e58 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -914,8 +914,8 @@ void mips_malta_init (ram_addr_t ram_size, /* TODO: Populate SPD eeprom data. */ DeviceState *eeprom; eeprom = qdev_create((BusState *)smbus, "smbus-eeprom"); - qdev_set_prop_int(eeprom, "address", 0x50 + i); - qdev_set_prop_ptr(eeprom, "data", eeprom_buf + (i * 256)); + qdev_prop_set_uint32(eeprom, "address", 0x50 + i); + qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256)); qdev_init(eeprom); } pit = pit_init(0x40, i8259[0]); diff --git a/hw/musicpal.c b/hw/musicpal.c index 10be69b..e636791 100644 --- a/hw/musicpal.c +++ b/hw/musicpal.c @@ -1578,7 +1578,7 @@ static void musicpal_init(ram_addr_t ram_size, qemu_check_nic_model(&nd_table[0], "mv88w8618"); dev = qdev_create(NULL, "mv88w8618_eth"); - qdev_set_netdev(dev, &nd_table[0]); + dev->nd = &nd_table[0]; qdev_init(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, MP_ETH_BASE); sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[MP_ETH_IRQ]); diff --git a/hw/pc.c b/hw/pc.c index 553ba5c..bdcec52 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1374,8 +1374,8 @@ static void pc_init1(ram_addr_t ram_size, for (i = 0; i < 8; i++) { DeviceState *eeprom; eeprom = qdev_create((BusState *)smbus, "smbus-eeprom"); - qdev_set_prop_int(eeprom, "address", 0x50 + i); - qdev_set_prop_ptr(eeprom, "data", eeprom_buf + (i * 256)); + qdev_prop_set_uint32(eeprom, "address", 0x50 + i); + qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256)); qdev_init(eeprom); } } diff --git a/hw/pci.c b/hw/pci.c index 9c7289a..07b62e9 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -54,6 +54,15 @@ static struct BusInfo pci_bus_info = { .name = "PCI", .size = sizeof(PCIBus), .print = pcibus_dev_print, + .props = (Property[]) { + { + .name = "devfn", + .info = &qdev_prop_uint32, + .offset = offsetof(PCIDevice, devfn), + .defval = (uint32_t[]) { -1 }, + }, + {/* end of list */} + } }; static void pci_update_mappings(PCIDevice *d); @@ -769,7 +778,7 @@ PCIDevice *pci_create(const char *name, const char *devaddr) } dev = qdev_create(&bus->qbus, name); - qdev_set_prop_int(dev, "devfn", devfn); + qdev_prop_set_uint32(dev, "devfn", devfn); return (PCIDevice *)dev; } @@ -812,7 +821,7 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, if (strcmp(nd->model, pci_nic_models[i]) == 0) { pci_dev = pci_create(pci_nic_names[i], devaddr); dev = &pci_dev->qdev; - qdev_set_netdev(dev, nd); + dev->nd = nd; qdev_init(dev); nd->private = dev; return pci_dev; @@ -890,7 +899,7 @@ static void pci_qdev_init(DeviceState *qdev, DeviceInfo *base) int devfn; bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev)); - devfn = qdev_get_prop_int(qdev, "devfn", -1); + devfn = pci_dev->devfn; pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn, info->config_read, info->config_write); assert(pci_dev); @@ -917,7 +926,7 @@ PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name) DeviceState *dev; dev = qdev_create(&bus->qbus, name); - qdev_set_prop_int(dev, "devfn", devfn); + qdev_prop_set_uint32(dev, "devfn", devfn); qdev_init(dev); return (PCIDevice *)dev; diff --git a/hw/pcnet.c b/hw/pcnet.c index 4519780..22ab6be 100644 --- a/hw/pcnet.c +++ b/hw/pcnet.c @@ -2128,8 +2128,6 @@ static void lance_init(SysBusDevice *dev) s->mmio_index = cpu_register_io_memory(lance_mem_read, lance_mem_write, d); - s->dma_opaque = qdev_get_prop_ptr(&dev->qdev, "dma"); - qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1); sysbus_init_mmio(dev, 4, s->mmio_index); @@ -2141,6 +2139,21 @@ static void lance_init(SysBusDevice *dev) pcnet_common_init(&dev->qdev, s, lance_cleanup); } + +static SysBusDeviceInfo lance_info = { + .init = lance_init, + .qdev.name = "lance", + .qdev.size = sizeof(SysBusPCNetState), + .qdev.props = (Property[]) { + { + .name = "dma", + .info = &qdev_prop_ptr, + .offset = offsetof(SysBusPCNetState, state.dma_opaque), + }, + {/* end of list */} + } +}; + #endif /* TARGET_SPARC */ static PCIDeviceInfo pcnet_info = { @@ -2153,7 +2166,7 @@ static void pcnet_register_devices(void) { pci_qdev_register(&pcnet_info); #if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) - sysbus_register_dev("lance", sizeof(SysBusPCNetState), lance_init); + sysbus_register_withprop(&lance_info); #endif } diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c new file mode 100644 index 0000000..b4f4f21 --- /dev/null +++ b/hw/qdev-properties.c @@ -0,0 +1,207 @@ +#include "qdev.h" + +static void *prop_ptr(DeviceState *dev, Property *prop) +{ + void *ptr = dev; + ptr += prop->offset; + return ptr; +} + +/* --- 32bit integer --- */ + +static int parse_uint32(DeviceState *dev, Property *prop, const char *str) +{ + uint32_t *ptr = prop_ptr(dev, prop); + + if (sscanf(str, "%" PRIu32, ptr) != 1) + return -1; + return 0; +} + +static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len) +{ + uint32_t *ptr = prop_ptr(dev, prop); + return snprintf(dest, len, "%" PRIu32, *ptr); +} + +PropertyInfo qdev_prop_uint32 = { + .name = "uint32", + .size = sizeof(uint32_t), + .parse = parse_uint32, + .print = print_uint32, +}; + +/* --- 32bit hex value --- */ + +static int parse_hex32(DeviceState *dev, Property *prop, const char *str) +{ + uint32_t *ptr = prop_ptr(dev, prop); + + if (sscanf(str, "%" PRIx32, ptr) != 1) + return -1; + return 0; +} + +static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len) +{ + uint32_t *ptr = prop_ptr(dev, prop); + return snprintf(dest, len, "0x%" PRIx32, *ptr); +} + +PropertyInfo qdev_prop_hex32 = { + .name = "hex32", + .size = sizeof(uint32_t), + .parse = parse_hex32, + .print = print_hex32, +}; + +/* --- pointer --- */ + +static int print_ptr(DeviceState *dev, Property *prop, char *dest, size_t len) +{ + void **ptr = prop_ptr(dev, prop); + return snprintf(dest, len, "<%p>", *ptr); +} + +PropertyInfo qdev_prop_ptr = { + .name = "ptr", + .size = sizeof(void*), + .print = print_ptr, +}; + +/* --- mac address --- */ + +/* + * accepted syntax versions: + * 01:02:03:04:05:06 + * 01-02-03-04-05-06 + */ +static int parse_mac(DeviceState *dev, Property *prop, const char *str) +{ + uint8_t *mac = prop_ptr(dev, prop); + int i, pos; + char *p; + + for (i = 0, pos = 0; i < 6; i++, pos += 3) { + if (!isxdigit(str[pos])) + return -1; + if (!isxdigit(str[pos+1])) + return -1; + if (i == 5 && str[pos+2] != '\0') + return -1; + if (str[pos+2] != ':' && str[pos+2] != '-') + return -1; + mac[i] = strtol(str+pos, &p, 16); + } + return 0; +} + +static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len) +{ + uint8_t *mac = prop_ptr(dev, prop); + return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); +} + +PropertyInfo qdev_prop_mac = { + .name = "mac", + .size = 6, + .parse = parse_mac, + .print = print_mac, +}; + +/* --- public helpers --- */ + +static Property *qdev_prop_walk(Property *props, const char *name) +{ + if (!props) + return NULL; + while (props->name) { + if (strcmp(props->name, name) == 0) + return props; + props++; + } + return NULL; +} + +static Property *qdev_prop_find(DeviceState *dev, const char *name) +{ + Property *prop; + + /* device properties */ + prop = qdev_prop_walk(dev->info->props, name); + if (prop) + return prop; + + /* bus properties */ + prop = qdev_prop_walk(dev->parent_bus->info->props, name); + if (prop) + return prop; + + return NULL; +} + +int qdev_prop_parse(DeviceState *dev, const char *name, const char *value) +{ + Property *prop; + + prop = qdev_prop_find(dev, name); + if (!prop) { + fprintf(stderr, "property \"%s.%s\" not found\n", + dev->info->name, name); + return -1; + } + if (!prop->info->parse) { + fprintf(stderr, "property \"%s.%s\" has no parser\n", + dev->info->name, name); + return -1; + } + return prop->info->parse(dev, prop, value); +} + +int qdev_prop_set(DeviceState *dev, const char *name, void *src, size_t size) +{ + Property *prop; + void *dst; + + prop = qdev_prop_find(dev, name); + if (!prop) { + fprintf(stderr, "property \"%s.%s\" not found\n", + dev->info->name, name); + return -1; + } + if (prop->info->size != size) { + fprintf(stderr, "property \"%s.%s\" size mismatch (%zd / %zd)\n", + dev->info->name, name, prop->info->size, size); + return -1; + } + dst = prop_ptr(dev, prop); + memcpy(dst, src, size); + return 0; +} + +int qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) +{ + return qdev_prop_set(dev, name, &value, sizeof(value)); +} + +int qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) +{ + return qdev_prop_set(dev, name, &value, sizeof(value)); +} + +void qdev_prop_set_defaults(DeviceState *dev, Property *props) +{ + char *dst; + + if (!props) + return; + while (props->name) { + if (props->defval) { + dst = prop_ptr(dev, props); + memcpy(dst, props->defval, props->info->size); + } + props++; + } +} + diff --git a/hw/qdev.c b/hw/qdev.c index fc49b05..9e10454 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -31,16 +31,6 @@ #include "sysemu.h" #include "monitor.h" -struct DeviceProperty { - const char *name; - DevicePropType type; - union { - uint64_t i; - void *ptr; - } value; - DeviceProperty *next; -}; - /* This is a nasty hack to allow passing a NULL bus to qdev_create. */ static BusState *main_system_bus; extern struct BusInfo system_bus_info; @@ -85,6 +75,8 @@ DeviceState *qdev_create(BusState *bus, const char *name) dev = qemu_mallocz(info->size); dev->info = info; dev->parent_bus = bus; + qdev_prop_set_defaults(dev, dev->info->props); + qdev_prop_set_defaults(dev, dev->parent_bus->info->props); LIST_INSERT_HEAD(&bus->children, dev, sibling); return dev; } @@ -104,52 +96,6 @@ void qdev_free(DeviceState *dev) free(dev); } -static DeviceProperty *create_prop(DeviceState *dev, const char *name, - DevicePropType type) -{ - DeviceProperty *prop; - - /* TODO: Check for duplicate properties. */ - prop = qemu_mallocz(sizeof(*prop)); - prop->name = qemu_strdup(name); - prop->type = type; - prop->next = dev->props; - dev->props = prop; - - return prop; -} - -void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value) -{ - DeviceProperty *prop; - - prop = create_prop(dev, name, PROP_TYPE_INT); - prop->value.i = value; -} - -void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value) -{ - DeviceProperty *prop; - - prop = create_prop(dev, name, PROP_TYPE_DEV); - prop->value.ptr = value; -} - -void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value) -{ - DeviceProperty *prop; - - prop = create_prop(dev, name, PROP_TYPE_PTR); - prop->value.ptr = value; -} - -void qdev_set_netdev(DeviceState *dev, NICInfo *nd) -{ - assert(!dev->nd); - dev->nd = nd; -} - - /* Get a character (serial) device interface. */ CharDriverState *qdev_init_chardev(DeviceState *dev) { @@ -168,52 +114,6 @@ BusState *qdev_get_parent_bus(DeviceState *dev) return dev->parent_bus; } -static DeviceProperty *find_prop(DeviceState *dev, const char *name, - DevicePropType type) -{ - DeviceProperty *prop; - - for (prop = dev->props; prop; prop = prop->next) { - if (strcmp(prop->name, name) == 0) { - assert (prop->type == type); - return prop; - } - } - return NULL; -} - -uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def) -{ - DeviceProperty *prop; - - prop = find_prop(dev, name, PROP_TYPE_INT); - if (!prop) { - return def; - } - - return prop->value.i; -} - -void *qdev_get_prop_ptr(DeviceState *dev, const char *name) -{ - DeviceProperty *prop; - - prop = find_prop(dev, name, PROP_TYPE_PTR); - assert(prop); - return prop->value.ptr; -} - -DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name) -{ - DeviceProperty *prop; - - prop = find_prop(dev, name, PROP_TYPE_DEV); - if (!prop) { - return NULL; - } - return prop->value.ptr; -} - void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n) { assert(dev->num_gpio_in == 0); @@ -325,9 +225,24 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name) #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__) static void qbus_print(Monitor *mon, BusState *bus, int indent); +static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props, + const char *prefix, int indent) +{ + char buf[64]; + + if (!props) + return; + while (props->name) { + if (props->info->print) { + props->info->print(dev, props, buf, sizeof(buf)); + qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf); + } + props++; + } +} + static void qdev_print(Monitor *mon, DeviceState *dev, int indent) { - DeviceProperty *prop; BusState *child; qdev_printf("dev: %s\n", dev->info->name); indent += 2; @@ -337,24 +252,8 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent) if (dev->num_gpio_out) { qdev_printf("gpio-out %d\n", dev->num_gpio_out); } - for (prop = dev->props; prop; prop = prop->next) { - switch (prop->type) { - case PROP_TYPE_INT: - qdev_printf("prop-int %s 0x%" PRIx64 "\n", prop->name, - prop->value.i); - break; - case PROP_TYPE_PTR: - qdev_printf("prop-ptr %s\n", prop->name); - break; - case PROP_TYPE_DEV: - qdev_printf("prop-dev %s %s\n", prop->name, - ((DeviceState *)prop->value.ptr)->info->name); - break; - default: - qdev_printf("prop-unknown%d %s\n", prop->type, prop->name); - break; - } - } + qdev_print_props(mon, dev, dev->info->props, "dev", indent); + qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent); if (dev->parent_bus->info->print) dev->parent_bus->info->print(mon, dev, indent); LIST_FOREACH(child, &dev->child_bus, sibling) { diff --git a/hw/qdev.h b/hw/qdev.h index 8ce5c23..9a3de47 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -4,9 +4,11 @@ #include "hw.h" #include "sys-queue.h" -typedef struct DeviceInfo DeviceInfo; +typedef struct Property Property; + +typedef struct PropertyInfo PropertyInfo; -typedef struct DeviceProperty DeviceProperty; +typedef struct DeviceInfo DeviceInfo; typedef struct BusState BusState; @@ -17,7 +19,6 @@ typedef struct BusInfo BusInfo; struct DeviceState { DeviceInfo *info; BusState *parent_bus; - DeviceProperty *props; int num_gpio_out; qemu_irq *gpio_out; int num_gpio_in; @@ -31,6 +32,7 @@ typedef void (*bus_dev_print)(Monitor *mon, DeviceState *dev, int indent); struct BusInfo { const char *name; size_t size; + Property *props; bus_dev_print print; }; @@ -42,18 +44,26 @@ struct BusState { LIST_ENTRY(BusState) sibling; }; +struct Property { + const char *name; + PropertyInfo *info; + int offset; + void *defval; +}; + +struct PropertyInfo { + const char *name; + size_t size; + int (*parse)(DeviceState *dev, Property *prop, const char *str); + int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); +}; + /*** Board API. This should go away once we have a machine config file. ***/ DeviceState *qdev_create(BusState *bus, const char *name); void qdev_init(DeviceState *dev); void qdev_free(DeviceState *dev); -/* Set properties between creation and init. */ -void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value); -void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value); -void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value); -void qdev_set_netdev(DeviceState *dev, NICInfo *nd); - qemu_irq qdev_get_gpio_in(DeviceState *dev, int n); void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); @@ -61,17 +71,6 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name); /*** Device API. ***/ -typedef enum { - PROP_TYPE_INT, - PROP_TYPE_PTR, - PROP_TYPE_DEV -} DevicePropType; - -typedef struct { - const char *name; - DevicePropType type; -} DevicePropList; - typedef void (*qdev_initfn)(DeviceState *dev, DeviceInfo *info); typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv, int unit); @@ -79,7 +78,7 @@ typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv, struct DeviceInfo { const char *name; size_t size; - DevicePropList *props; + Property *props; /* Private to qdev / bus. */ qdev_initfn init; @@ -99,10 +98,6 @@ void scsi_bus_new(DeviceState *host, SCSIAttachFn attach); CharDriverState *qdev_init_chardev(DeviceState *dev); BusState *qdev_get_parent_bus(DeviceState *dev); -uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def); -DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name); -/* FIXME: Remove opaque pointer properties. */ -void *qdev_get_prop_ptr(DeviceState *dev, const char *name); /* Convery from a base type to a parent type, with compile time checking. */ #ifdef __GNUC__ @@ -125,4 +120,19 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name); void do_info_qtree(Monitor *mon); void do_info_qdrv(Monitor *mon); +/*** qdev-properties.c ***/ + +extern PropertyInfo qdev_prop_uint32; +extern PropertyInfo qdev_prop_hex32; +extern PropertyInfo qdev_prop_ptr; +extern PropertyInfo qdev_prop_mac; + +/* Set properties between creation and init. */ +int qdev_prop_parse(DeviceState *dev, const char *name, const char *value); +int qdev_prop_set(DeviceState *dev, const char *name, void *src, size_t size); +int qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value); +/* FIXME: Remove opaque pointer properties. */ +int qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value); +void qdev_prop_set_defaults(DeviceState *dev, Property *props); + #endif diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c index 05a70d9..c071fb1 100644 --- a/hw/smbus_eeprom.c +++ b/hw/smbus_eeprom.c @@ -99,14 +99,20 @@ static void smbus_eeprom_init(SMBusDevice *dev) { SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *)dev; - /* FIXME: Should be a blob rather than a ptr. */ - eeprom->data = qdev_get_prop_ptr(&dev->i2c.qdev, "data"); eeprom->offset = 0; } static SMBusDeviceInfo smbus_eeprom_info = { .i2c.qdev.name = "smbus-eeprom", .i2c.qdev.size = sizeof(SMBusEEPROMDevice), + .i2c.qdev.props = (Property[]) { + { + .name = "data", + .info = &qdev_prop_ptr, + .offset = offsetof(SMBusEEPROMDevice, data), + }, + {/* end of list */} + }, .init = smbus_eeprom_init, .quick_cmd = eeprom_quick_cmd, .send_byte = eeprom_send_byte, diff --git a/hw/smc91c111.c b/hw/smc91c111.c index cf8d864..5f6956a 100644 --- a/hw/smc91c111.c +++ b/hw/smc91c111.c @@ -733,7 +733,7 @@ void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq) qemu_check_nic_model(nd, "smc91c111"); dev = qdev_create(NULL, "smc91c111"); - qdev_set_netdev(dev, nd); + dev->nd = nd; qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, base); diff --git a/hw/stellaris.c b/hw/stellaris.c index 5f44bff..d9434ca 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -1378,7 +1378,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, qemu_check_nic_model(&nd_table[0], "stellaris"); enet = qdev_create(NULL, "stellaris_enet"); - qdev_set_netdev(enet, &nd_table[0]); + enet->nd = &nd_table[0]; qdev_init(enet); sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000); sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]); diff --git a/hw/sun4m.c b/hw/sun4m.c index c67bf0b..0805f6e 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -373,8 +373,7 @@ static void lance_init(NICInfo *nd, target_phys_addr_t leaddr, qemu_check_nic_model(&nd_table[0], "lance"); dev = qdev_create(NULL, "lance"); - qdev_set_netdev(dev, nd); - qdev_set_prop_ptr(dev, "dma", dma_opaque); + dev->nd = nd; qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, leaddr); diff --git a/hw/syborg.c b/hw/syborg.c index 5ca9977..d8d38d4 100644 --- a/hw/syborg.c +++ b/hw/syborg.c @@ -64,7 +64,7 @@ static void syborg_init(ram_addr_t ram_size, sysbus_create_simple("syborg,rtc", 0xC0001000, NULL); dev = qdev_create(NULL, "syborg,timer"); - qdev_set_prop_int(dev, "frequency", 1000000); + qdev_prop_set_uint32(dev, "frequency", 1000000); qdev_init(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0xC0002000); sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[1]); @@ -83,7 +83,7 @@ static void syborg_init(ram_addr_t ram_size, qemu_check_nic_model(&nd_table[0], "virtio"); dev = qdev_create(NULL, "syborg,virtio-net"); - qdev_set_netdev(dev, &nd_table[0]); + dev->nd = &nd_table[0]; qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, 0xc000c000); diff --git a/hw/syborg_fb.c b/hw/syborg_fb.c index 42c6274..2929ffd 100644 --- a/hw/syborg_fb.c +++ b/hw/syborg_fb.c @@ -76,8 +76,8 @@ typedef struct { uint32_t base; uint32_t pitch; - int rows; - int cols; + uint32_t rows; + uint32_t cols; int blank; int bpp; int rgb; /* 0 = BGR, 1 = RGB */ @@ -507,41 +507,50 @@ static void syborg_fb_init(SysBusDevice *dev) { SyborgFBState *s = FROM_SYSBUS(SyborgFBState, dev); int iomemtype; - int width; - int height; sysbus_init_irq(dev, &s->irq); iomemtype = cpu_register_io_memory(syborg_fb_readfn, syborg_fb_writefn, s); sysbus_init_mmio(dev, 0x1000, iomemtype); - width = qdev_get_prop_int(&dev->qdev, "width", 0); - height = qdev_get_prop_int(&dev->qdev, "height", 0); - s->ds = graphic_console_init(syborg_fb_update_display, syborg_fb_invalidate_display, NULL, NULL, s); - if (width != 0 && height != 0) { - qemu_console_resize(s->ds, width, height); + if (s->cols != 0 && s->rows != 0) { + qemu_console_resize(s->ds, s->cols, s->rows); } - if (!width) - width = ds_get_width(s->ds); - if (!height) - height = ds_get_height(s->ds); - - s->cols = width; - s->rows = height; + if (!s->cols) + s->cols = ds_get_width(s->ds); + if (!s->rows) + s->rows = ds_get_height(s->ds); register_savevm("syborg_framebuffer", -1, 1, syborg_fb_save, syborg_fb_load, s); } +static SysBusDeviceInfo syborg_fb_info = { + .init = syborg_fb_init, + .qdev.name = "syborg,framebuffer", + .qdev.size = sizeof(SyborgFBState), + .qdev.props = (Property[]) { + { + .name = "width", + .info = &qdev_prop_uint32, + .offset = offsetof(SyborgFBState, cols), + },{ + .name = "height", + .info = &qdev_prop_uint32, + .offset = offsetof(SyborgFBState, rows), + }, + {/* end of list */} + } +}; + static void syborg_fb_register_devices(void) { - sysbus_register_dev("syborg,framebuffer", sizeof(SyborgFBState), - syborg_fb_init); + sysbus_register_withprop(&syborg_fb_info); } device_init(syborg_fb_register_devices) diff --git a/hw/syborg_interrupt.c b/hw/syborg_interrupt.c index 569c7f6..a372ec1 100644 --- a/hw/syborg_interrupt.c +++ b/hw/syborg_interrupt.c @@ -56,7 +56,7 @@ typedef struct { typedef struct { SysBusDevice busdev; int pending_count; - int num_irqs; + uint32_t num_irqs; syborg_int_flags *flags; qemu_irq parent_irq; } SyborgIntState; @@ -208,7 +208,6 @@ static void syborg_int_init(SysBusDevice *dev) int iomemtype; sysbus_init_irq(dev, &s->parent_irq); - s->num_irqs = qdev_get_prop_int(&dev->qdev, "num-interrupts", 64); qdev_init_gpio_in(&dev->qdev, syborg_int_set_irq, s->num_irqs); iomemtype = cpu_register_io_memory(syborg_int_readfn, syborg_int_writefn, s); @@ -218,10 +217,24 @@ static void syborg_int_init(SysBusDevice *dev) register_savevm("syborg_int", -1, 1, syborg_int_save, syborg_int_load, s); } +static SysBusDeviceInfo syborg_int_info = { + .init = syborg_int_init, + .qdev.name = "syborg,interrupt", + .qdev.size = sizeof(SyborgIntState), + .qdev.props = (Property[]) { + { + .name = "num-interrupts", + .info = &qdev_prop_uint32, + .offset = offsetof(SyborgIntState, num_irqs), + .defval = (uint32_t[]) { 64 }, + }, + {/* end of list */} + } +}; + static void syborg_interrupt_register_devices(void) { - sysbus_register_dev("syborg,interrupt", sizeof(SyborgIntState), - syborg_int_init); + sysbus_register_withprop(&syborg_int_info); } device_init(syborg_interrupt_register_devices) diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c index 84a099e..ffc85a5 100644 --- a/hw/syborg_keyboard.c +++ b/hw/syborg_keyboard.c @@ -53,7 +53,7 @@ typedef struct { SysBusDevice busdev; int int_enabled; int extension_bit; - int fifo_size; + uint32_t fifo_size; uint32_t *key_fifo; int read_pos, read_count; qemu_irq irq; @@ -212,7 +212,6 @@ static void syborg_keyboard_init(SysBusDevice *dev) iomemtype = cpu_register_io_memory(syborg_keyboard_readfn, syborg_keyboard_writefn, s); sysbus_init_mmio(dev, 0x1000, iomemtype); - s->fifo_size = qdev_get_prop_int(&dev->qdev, "fifo-size", 16); if (s->fifo_size <= 0) { fprintf(stderr, "syborg_keyboard: fifo too small\n"); s->fifo_size = 16; @@ -225,10 +224,24 @@ static void syborg_keyboard_init(SysBusDevice *dev) syborg_keyboard_save, syborg_keyboard_load, s); } +static SysBusDeviceInfo syborg_keyboard_info = { + .init = syborg_keyboard_init, + .qdev.name = "syborg,keyboard", + .qdev.size = sizeof(SyborgKeyboardState), + .qdev.props = (Property[]) { + { + .name = "fifo-size", + .info = &qdev_prop_uint32, + .offset = offsetof(SyborgKeyboardState, fifo_size), + .defval = (uint32_t[]) { 16 }, + }, + {/* end of list */} + } +}; + static void syborg_keyboard_register_devices(void) { - sysbus_register_dev("syborg,keyboard", sizeof(SyborgKeyboardState), - syborg_keyboard_init); + sysbus_register_withprop(&syborg_keyboard_info); } device_init(syborg_keyboard_register_devices) diff --git a/hw/syborg_pointer.c b/hw/syborg_pointer.c index e0a892d..edd1f22 100644 --- a/hw/syborg_pointer.c +++ b/hw/syborg_pointer.c @@ -45,11 +45,11 @@ typedef struct { typedef struct { SysBusDevice busdev; int int_enabled; - int fifo_size; + uint32_t fifo_size; event_data *event_fifo; int read_pos, read_count; qemu_irq irq; - int absolute; + uint32_t absolute; } SyborgPointerState; static void syborg_pointer_update(SyborgPointerState *s) @@ -209,8 +209,6 @@ static void syborg_pointer_init(SysBusDevice *dev) syborg_pointer_writefn, s); sysbus_init_mmio(dev, 0x1000, iomemtype); - s->absolute = qdev_get_prop_int(&dev->qdev, "absolute", 1); - s->fifo_size = qdev_get_prop_int(&dev->qdev, "fifo-size", 16); if (s->fifo_size <= 0) { fprintf(stderr, "syborg_pointer: fifo too small\n"); s->fifo_size = 16; @@ -224,10 +222,29 @@ static void syborg_pointer_init(SysBusDevice *dev) syborg_pointer_save, syborg_pointer_load, s); } +static SysBusDeviceInfo syborg_pointer_info = { + .init = syborg_pointer_init, + .qdev.name = "syborg,pointer", + .qdev.size = sizeof(SyborgPointerState), + .qdev.props = (Property[]) { + { + .name = "fifo-size", + .info = &qdev_prop_uint32, + .offset = offsetof(SyborgPointerState, fifo_size), + .defval = (uint32_t[]) { 16 }, + },{ + .name = "absolute", + .info = &qdev_prop_uint32, + .offset = offsetof(SyborgPointerState, absolute), + .defval = (uint32_t[]) { 1 }, + }, + {/* end of list */} + } +}; + static void syborg_pointer_register_devices(void) { - sysbus_register_dev("syborg,pointer", sizeof(SyborgPointerState), - syborg_pointer_init); + sysbus_register_withprop(&syborg_pointer_info); } device_init(syborg_pointer_register_devices) diff --git a/hw/syborg_serial.c b/hw/syborg_serial.c index f430508..f693421 100644 --- a/hw/syborg_serial.c +++ b/hw/syborg_serial.c @@ -59,7 +59,7 @@ enum { typedef struct { SysBusDevice busdev; uint32_t int_enable; - int fifo_size; + uint32_t fifo_size; uint32_t *read_fifo; int read_pos; int read_count; @@ -329,7 +329,6 @@ static void syborg_serial_init(SysBusDevice *dev) qemu_chr_add_handlers(s->chr, syborg_serial_can_receive, syborg_serial_receive, syborg_serial_event, s); } - s->fifo_size = qdev_get_prop_int(&dev->qdev, "fifo-size", 16); if (s->fifo_size <= 0) { fprintf(stderr, "syborg_serial: fifo too small\n"); s->fifo_size = 16; @@ -340,10 +339,24 @@ static void syborg_serial_init(SysBusDevice *dev) syborg_serial_save, syborg_serial_load, s); } +static SysBusDeviceInfo syborg_serial_info = { + .init = syborg_serial_init, + .qdev.name = "syborg,serial", + .qdev.size = sizeof(SyborgSerialState), + .qdev.props = (Property[]) { + { + .name = "fifo-size", + .info = &qdev_prop_uint32, + .offset = offsetof(SyborgSerialState, fifo_size), + .defval = (uint32_t[]) { 16 }, + }, + {/* end of list */} + } +}; + static void syborg_serial_register_devices(void) { - sysbus_register_dev("syborg,serial", sizeof(SyborgSerialState), - syborg_serial_init); + sysbus_register_withprop(&syborg_serial_info); } device_init(syborg_serial_register_devices) diff --git a/hw/syborg_timer.c b/hw/syborg_timer.c index 4f5e3a1..cf96c5f 100644 --- a/hw/syborg_timer.c +++ b/hw/syborg_timer.c @@ -209,7 +209,6 @@ static void syborg_timer_init(SysBusDevice *dev) QEMUBH *bh; int iomemtype; - s->freq = qdev_get_prop_int(&dev->qdev, "frequency", 0); if (s->freq == 0) { fprintf(stderr, "syborg_timer: Zero/unset frequency\n"); exit(1); @@ -230,9 +229,13 @@ static SysBusDeviceInfo syborg_timer_info = { .init = syborg_timer_init, .qdev.name = "syborg,timer", .qdev.size = sizeof(SyborgTimerState), - .qdev.props = (DevicePropList[]) { - {.name = "frequency", .type = PROP_TYPE_INT}, - {.name = NULL} + .qdev.props = (Property[]) { + { + .name = "frequency", + .info = &qdev_prop_uint32, + .offset = offsetof(SyborgTimerState, freq), + }, + {/* end of list */} } }; diff --git a/hw/xilinx.h b/hw/xilinx.h index 9707a0e..070679c 100644 --- a/hw/xilinx.h +++ b/hw/xilinx.h @@ -8,7 +8,7 @@ xilinx_intc_create(target_phys_addr_t base, qemu_irq irq, int kind_of_intr) DeviceState *dev; dev = qdev_create(NULL, "xilinx,intc"); - qdev_set_prop_int(dev, "kind-of-intr", kind_of_intr); + qdev_prop_set_uint32(dev, "kind-of-intr", kind_of_intr); qdev_init(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); @@ -22,8 +22,8 @@ xilinx_timer_create(target_phys_addr_t base, qemu_irq irq, int nr, int freq) DeviceState *dev; dev = qdev_create(NULL, "xilinx,timer"); - qdev_set_prop_int(dev, "nr-timers", nr); - qdev_set_prop_int(dev, "frequency", freq); + qdev_prop_set_uint32(dev, "nr-timers", nr); + qdev_prop_set_uint32(dev, "frequency", freq); qdev_init(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); @@ -40,9 +40,9 @@ xilinx_ethlite_create(NICInfo *nd, target_phys_addr_t base, qemu_irq irq, qemu_check_nic_model(nd, "xilinx-ethlite"); dev = qdev_create(NULL, "xilinx,ethlite"); - qdev_set_netdev(dev, nd); - qdev_set_prop_int(dev, "txpingpong", txpingpong); - qdev_set_prop_int(dev, "rxpingpong", rxpingpong); + dev->nd = nd; + qdev_prop_set_uint32(dev, "txpingpong", txpingpong); + qdev_prop_set_uint32(dev, "rxpingpong", rxpingpong); qdev_init(dev); sysbus_mmio_map(sysbus_from_qdev(dev), 0, base); sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c index f4b40c7..b3fd25b 100644 --- a/hw/xilinx_ethlite.c +++ b/hw/xilinx_ethlite.c @@ -53,8 +53,8 @@ struct xlx_ethlite qemu_irq irq; VLANClientState *vc; - unsigned int c_tx_pingpong; - unsigned int c_rx_pingpong; + uint32_t c_tx_pingpong; + uint32_t c_rx_pingpong; unsigned int txbuf; unsigned int rxbuf; @@ -213,8 +213,6 @@ static void xilinx_ethlite_init(SysBusDevice *dev) int regs; sysbus_init_irq(dev, &s->irq); - s->c_tx_pingpong = qdev_get_prop_int(&dev->qdev, "txpingpong", 1); - s->c_rx_pingpong = qdev_get_prop_int(&dev->qdev, "rxpingpong", 1); s->rxbuf = 0; regs = cpu_register_io_memory(eth_read, eth_write, s); @@ -225,10 +223,29 @@ static void xilinx_ethlite_init(SysBusDevice *dev) eth_can_rx, eth_rx, NULL, eth_cleanup, s); } +static SysBusDeviceInfo xilinx_ethlite_info = { + .init = xilinx_ethlite_init, + .qdev.name = "xilinx,ethlite", + .qdev.size = sizeof(struct xlx_ethlite), + .qdev.props = (Property[]) { + { + .name = "txpingpong", + .info = &qdev_prop_uint32, + .offset = offsetof(struct xlx_ethlite, c_tx_pingpong), + .defval = (uint32_t[]) { 1 }, + },{ + .name = "rxpingpong", + .info = &qdev_prop_uint32, + .offset = offsetof(struct xlx_ethlite, c_rx_pingpong), + .defval = (uint32_t[]) { 1 }, + }, + {/* end of list */} + } +}; + static void xilinx_ethlite_register(void) { - sysbus_register_dev("xilinx,ethlite", sizeof (struct xlx_ethlite), - xilinx_ethlite_init); + sysbus_register_withprop(&xilinx_ethlite_info); } device_init(xilinx_ethlite_register) diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c index 0540f52..3f08bf8 100644 --- a/hw/xilinx_intc.c +++ b/hw/xilinx_intc.c @@ -150,7 +150,6 @@ static void xilinx_intc_init(SysBusDevice *dev) struct xlx_pic *p = FROM_SYSBUS(typeof (*p), dev); int pic_regs; - p->c_kind_of_intr = qdev_get_prop_int(&dev->qdev, "kind-of-intr", 0); qdev_init_gpio_in(&dev->qdev, irq_handler, 32); sysbus_init_irq(dev, &p->parent_irq); @@ -158,10 +157,23 @@ static void xilinx_intc_init(SysBusDevice *dev) sysbus_init_mmio(dev, R_MAX * 4, pic_regs); } +static SysBusDeviceInfo xilinx_intc_info = { + .init = xilinx_intc_init, + .qdev.name = "xilinx,intc", + .qdev.size = sizeof(struct xlx_pic), + .qdev.props = (Property[]) { + { + .name = "kind-of-intr", + .info = &qdev_prop_uint32, + .offset = offsetof(struct xlx_pic, c_kind_of_intr), + }, + {/* end of list */} + } +}; + static void xilinx_intc_register(void) { - sysbus_register_dev("xilinx,intc", sizeof (struct xlx_pic), - xilinx_intc_init); + sysbus_register_withprop(&xilinx_intc_info); } device_init(xilinx_intc_register) diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c index a64ad2d..efb6a04 100644 --- a/hw/xilinx_timer.c +++ b/hw/xilinx_timer.c @@ -61,7 +61,8 @@ struct timerblock { SysBusDevice busdev; qemu_irq irq; - unsigned int nr_timers; + uint32_t nr_timers; + uint32_t freq_hz; struct xlx_timer *timers; }; @@ -192,14 +193,12 @@ static void xilinx_timer_init(SysBusDevice *dev) { struct timerblock *t = FROM_SYSBUS(typeof (*t), dev); unsigned int i; - int timer_regs, freq_hz; + int timer_regs; /* All timers share a single irq line. */ sysbus_init_irq(dev, &t->irq); /* Init all the ptimers. */ - freq_hz = qdev_get_prop_int(&dev->qdev, "frequency", 2); - t->nr_timers = qdev_get_prop_int(&dev->qdev, "nr-timers", 2); t->timers = qemu_mallocz(sizeof t->timers[0] * t->nr_timers); for (i = 0; i < t->nr_timers; i++) { struct xlx_timer *xt = &t->timers[i]; @@ -208,17 +207,36 @@ static void xilinx_timer_init(SysBusDevice *dev) xt->nr = i; xt->bh = qemu_bh_new(timer_hit, xt); xt->ptimer = ptimer_init(xt->bh); - ptimer_set_freq(xt->ptimer, freq_hz); + ptimer_set_freq(xt->ptimer, t->freq_hz); } timer_regs = cpu_register_io_memory(timer_read, timer_write, t); sysbus_init_mmio(dev, R_MAX * 4 * t->nr_timers, timer_regs); } +static SysBusDeviceInfo xilinx_timer_info = { + .init = xilinx_timer_init, + .qdev.name = "xilinx,timer", + .qdev.size = sizeof(struct timerblock), + .qdev.props = (Property[]) { + { + .name = "frequency", + .info = &qdev_prop_uint32, + .offset = offsetof(struct timerblock, freq_hz), + .defval = (uint32_t[]) { 2 }, + },{ + .name = "nr-timers", + .info = &qdev_prop_uint32, + .offset = offsetof(struct timerblock, nr_timers), + .defval = (uint32_t[]) { 2 }, + }, + {/* end of list */} + } +}; + static void xilinx_timer_register(void) { - sysbus_register_dev("xilinx,timer", sizeof (struct timerblock), - xilinx_timer_init); + sysbus_register_withprop(&xilinx_timer_info); } device_init(xilinx_timer_register) -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 02/13] qdev: factor out driver search to qdev_find_info() 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 01/13] qdev: rework device properties Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 03/13] qdev/pci: make pci_create return DeviceState instead of PCIDevice Gerd Hoffmann ` (10 subsequent siblings) 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/qdev.c | 22 +++++++++++++++------- 1 files changed, 15 insertions(+), 7 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 9e10454..2156dc0 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -46,6 +46,20 @@ void qdev_register(DeviceInfo *info) device_info_list = info; } +static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name) +{ + DeviceInfo *info; + + for (info = device_info_list; info != NULL; info = info->next) { + if (bus_info && info->bus_info != bus_info) + continue; + if (strcmp(info->name, name) != 0) + continue; + return info; + } + return NULL; +} + /* Create a new device. This only initializes the device state structure and allows properties to be set. qdev_init should be called to initialize the actual device emulation. */ @@ -61,13 +75,7 @@ DeviceState *qdev_create(BusState *bus, const char *name) bus = main_system_bus; } - for (info = device_info_list; info != NULL; info = info->next) { - if (info->bus_info != bus->info) - continue; - if (strcmp(info->name, name) != 0) - continue; - break; - } + info = qdev_find_info(bus->info, name); if (!info) { hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name); } -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 03/13] qdev/pci: make pci_create return DeviceState instead of PCIDevice. 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 01/13] qdev: rework device properties Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 02/13] qdev: factor out driver search to qdev_find_info() Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 04/13] qdev: add generic qdev_device_add() Gerd Hoffmann ` (9 subsequent siblings) 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Rationale: wanna use it as callback in qdev code. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/pc.c | 12 ++++++------ hw/pci-hotplug.c | 6 +++--- hw/pci.c | 10 ++++------ hw/pci.h | 2 +- hw/ppc440_bamboo.c | 6 +++--- hw/ppce500_mpc8544ds.c | 6 +++--- 6 files changed, 20 insertions(+), 22 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index bdcec52..2b89356 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1094,7 +1094,7 @@ static void pc_init1(ram_addr_t ram_size, ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; int bios_size, isa_bios_size, oprom_area_size; PCIBus *pci_bus; - PCIDevice *pci_dev; + DeviceState *qdev; int piix3_devfn = -1; CPUState *env; qemu_irq *cpu_irq; @@ -1400,17 +1400,17 @@ static void pc_init1(ram_addr_t ram_size, int unit_id = 0; while ((index = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) { - pci_dev = pci_create("virtio-blk-pci", - drives_table[index].devaddr); - qdev_init(&pci_dev->qdev); + qdev = pci_create("virtio-blk-pci", + drives_table[index].devaddr); + qdev_init(qdev); unit_id++; } } /* Add virtio balloon device */ if (pci_enabled && virtio_balloon) { - pci_dev = pci_create("virtio-balloon-pci", virtio_balloon_devaddr); - qdev_init(&pci_dev->qdev); + qdev = pci_create("virtio-balloon-pci", virtio_balloon_devaddr); + qdev_init(qdev); } /* Add virtio console devices */ diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index d0f2911..0781b52 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -97,7 +97,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, const char *devaddr, const char *opts) { - PCIDevice *dev; + DeviceState *dev; int type = -1, drive_idx = -1; char buf[128]; @@ -139,8 +139,8 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, dev = NULL; } if (dev) - qdev_init(&dev->qdev); - return dev; + qdev_init(dev); + return DO_UPCAST(PCIDevice, qdev, dev); } void pci_device_hot_add(Monitor *mon, const char *pci_addr, const char *type, diff --git a/hw/pci.c b/hw/pci.c index 07b62e9..f0cc36c 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -764,7 +764,7 @@ void pci_info(Monitor *mon) pci_for_each_device(0, pci_info_device); } -PCIDevice *pci_create(const char *name, const char *devaddr) +DeviceState *pci_create(const char *name, const char *devaddr) { PCIBus *bus; int devfn; @@ -779,7 +779,7 @@ PCIDevice *pci_create(const char *name, const char *devaddr) dev = qdev_create(&bus->qbus, name); qdev_prop_set_uint32(dev, "devfn", devfn); - return (PCIDevice *)dev; + return dev; } static const char * const pci_nic_models[] = { @@ -811,7 +811,6 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, const char *default_devaddr) { const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr; - PCIDevice *pci_dev; DeviceState *dev; int i; @@ -819,12 +818,11 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, for (i = 0; pci_nic_models[i]; i++) { if (strcmp(nd->model, pci_nic_models[i]) == 0) { - pci_dev = pci_create(pci_nic_names[i], devaddr); - dev = &pci_dev->qdev; + dev = pci_create(pci_nic_names[i], devaddr); dev->nd = nd; qdev_init(dev); nd->private = dev; - return pci_dev; + return DO_UPCAST(PCIDevice, qdev, dev); } } diff --git a/hw/pci.h b/hw/pci.h index cbfea6a..17563ed 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -324,7 +324,7 @@ typedef struct { void pci_qdev_register(PCIDeviceInfo *info); void pci_qdev_register_many(PCIDeviceInfo *info); -PCIDevice *pci_create(const char *name, const char *devaddr); +DeviceState *pci_create(const char *name, const char *devaddr); PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); /* lsi53c895a.c */ diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c index d9ef3ec..b6b8f8a 100644 --- a/hw/ppc440_bamboo.c +++ b/hw/ppc440_bamboo.c @@ -90,7 +90,7 @@ static void bamboo_init(ram_addr_t ram_size, { unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 }; PCIBus *pcibus; - PCIDevice *pci_dev; + DeviceState *qdev; CPUState *env; uint64_t elf_entry; uint64_t elf_lowaddr; @@ -111,8 +111,8 @@ static void bamboo_init(ram_addr_t ram_size, /* Add virtio block devices. */ while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) { - pci_dev = pci_create("virtio-blk-pci", drives_table[i].devaddr); - qdev_init(&pci_dev->qdev); + qdev = pci_create("virtio-blk-pci", drives_table[i].devaddr); + qdev_init(qdev); unit_id++; } diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c index c0e367d..d21eb95 100644 --- a/hw/ppce500_mpc8544ds.c +++ b/hw/ppce500_mpc8544ds.c @@ -157,7 +157,7 @@ static void mpc8544ds_init(ram_addr_t ram_size, const char *cpu_model) { PCIBus *pci_bus; - PCIDevice *pci_dev; + DeviceState *qdev; CPUState *env; uint64_t elf_entry; uint64_t elf_lowaddr; @@ -220,8 +220,8 @@ static void mpc8544ds_init(ram_addr_t ram_size, /* Add virtio block devices. */ while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) { - pci_dev = pci_create("virtio-blk-pci", drives_table[i].devaddr); - qdev_init(&pci_dev->qdev); + qdev = pci_create("virtio-blk-pci", drives_table[i].devaddr); + qdev_init(qdev); unit_id++; } -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 04/13] qdev: add generic qdev_device_add() 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann ` (2 preceding siblings ...) 2009-07-03 10:22 ` [Qemu-devel] [PATCH 03/13] qdev/pci: make pci_create return DeviceState instead of PCIDevice Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 05/13] qdev: add -device command line option Gerd Hoffmann ` (8 subsequent siblings) 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Will be used for -device command line. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/pci.c | 1 + hw/qdev.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ 3 files changed, 55 insertions(+), 0 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index f0cc36c..af72468 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -54,6 +54,7 @@ static struct BusInfo pci_bus_info = { .name = "PCI", .size = sizeof(PCIBus), .print = pcibus_dev_print, + .add = pci_create, .props = (Property[]) { { .name = "devfn", diff --git a/hw/qdev.c b/hw/qdev.c index 2156dc0..6bc2530 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -89,6 +89,57 @@ DeviceState *qdev_create(BusState *bus, const char *name) return dev; } +DeviceState *qdev_device_add(const char *cmdline) +{ + DeviceInfo *info; + DeviceState *qdev; + char driver[32], addr[32] = ""; + char tag[32], value[256]; + const char *params = NULL; + int n = 0; + + if (1 != sscanf(cmdline, "%32[^,],%n", driver, &n)) { + fprintf(stderr, "device parse error: \"%s\"\n", cmdline); + return NULL; + } + if (strcmp(driver, "?") == 0) { + for (info = device_info_list; info != NULL; info = info->next) { + fprintf(stderr, "name \"%s\", bus %s\n", info->name, info->bus_info->name); + } + return NULL; + } + if (n) { + params = cmdline + n; + get_param_value(addr, sizeof(addr), "addr", params); + } + info = qdev_find_info(NULL, driver); + + if (!info->bus_info->add) { + fprintf(stderr, "bus \"%s\" can't add devices.\n", + info->bus_info->name); + return NULL; + } + + qdev = info->bus_info->add(driver, strlen(addr) ? addr : NULL); + + if (params) { + while (params[0]) { + if (2 != sscanf(params, "%31[^=]=%255[^,]%n", tag, value, &n)) + break; + params += n; + if (strcmp(tag, "addr") == 0) + continue; + if (-1 == qdev_prop_parse(qdev, tag, value)) { + fprintf(stderr, "can't set property \"%s\" to \"%s\" for \"%s\"\n", + tag, value, driver); + } + } + } + + qdev_init(qdev); + return qdev; +} + /* Initialize a device. Device properties should be set before calling this function. IRQs and MMIO regions should be connected/mapped after calling this function. */ diff --git a/hw/qdev.h b/hw/qdev.h index 9a3de47..a856576 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -29,11 +29,13 @@ struct DeviceState { }; typedef void (*bus_dev_print)(Monitor *mon, DeviceState *dev, int indent); +typedef DeviceState* (*bus_dev_add)(const char *name, const char *addr); struct BusInfo { const char *name; size_t size; Property *props; bus_dev_print print; + bus_dev_add add; }; struct BusState { @@ -61,6 +63,7 @@ struct PropertyInfo { /*** Board API. This should go away once we have a machine config file. ***/ DeviceState *qdev_create(BusState *bus, const char *name); +DeviceState *qdev_device_add(const char *cmdline); void qdev_init(DeviceState *dev); void qdev_free(DeviceState *dev); -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 05/13] qdev: add -device command line option. 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann ` (3 preceding siblings ...) 2009-07-03 10:22 ` [Qemu-devel] [PATCH 04/13] qdev: add generic qdev_device_add() Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-07 15:38 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 06/13] qdev: add no_user, alias and desc Gerd Hoffmann ` (7 subsequent siblings) 12 siblings, 1 reply; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Add a linked list where command line options can be saved. Use it for the new -device and for the -usbdevice and -bt switches. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/qdev.c | 4 ++- qemu-options.hx | 2 + vl.c | 96 ++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 68 insertions(+), 34 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 6bc2530..82bcd04 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -124,8 +124,10 @@ DeviceState *qdev_device_add(const char *cmdline) if (params) { while (params[0]) { - if (2 != sscanf(params, "%31[^=]=%255[^,]%n", tag, value, &n)) + if (2 != sscanf(params, "%31[^=]=%255[^,]%n", tag, value, &n)) { + fprintf(stderr, "parse error at \"%s\"\n", params); break; + } params += n; if (strcmp(tag, "addr") == 0) continue; diff --git a/qemu-options.hx b/qemu-options.hx index a94f9d3..67d7bd0 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -364,6 +364,8 @@ Network adapter that supports CDC ethernet and RNDIS protocols. @end table ETEXI +DEF("device", HAS_ARG, QEMU_OPTION_device, + "-device driver[,options] add device\n") DEF("name", HAS_ARG, QEMU_OPTION_name, "-name string set the name of the guest\n") STEXI diff --git a/vl.c b/vl.c index 7b7489c..ca82f80 100644 --- a/vl.c +++ b/vl.c @@ -181,12 +181,6 @@ int main(int argc, char **argv) #define DEFAULT_RAM_SIZE 128 -/* Max number of USB devices that can be specified on the commandline. */ -#define MAX_USB_CMDLINE 8 - -/* Max number of bluetooth switches on the commandline. */ -#define MAX_BT_CMDLINE 10 - /* XXX: use a two level table to limit memory usage */ #define MAX_IOPORTS 65536 @@ -2787,6 +2781,11 @@ static int usb_device_del(const char *devname) return usb_device_del_addr(bus_num, addr); } +static int usb_parse(const char *cmdline) +{ + return usb_device_add(cmdline, 0); +} + void do_usb_add(Monitor *mon, const char *devname) { usb_device_add(devname, 1); @@ -4970,6 +4969,52 @@ char *qemu_find_file(int type, const char *name) return buf; } +struct device_config { + enum { + DEV_GENERIC, /* -device */ + DEV_USB, /* -usbdevice */ + DEV_BT, /* -bt */ + } type; + const char *cmdline; + TAILQ_ENTRY(device_config) next; +}; +TAILQ_HEAD(, device_config) device_configs = TAILQ_HEAD_INITIALIZER(device_configs); + +static void add_device_config(int type, const char *cmdline) +{ + struct device_config *conf; + + conf = qemu_mallocz(sizeof(*conf)); + conf->type = type; + conf->cmdline = cmdline; + TAILQ_INSERT_TAIL(&device_configs, conf, next); +} + +static int foreach_device_config(int type, int (*func)(const char *cmdline)) +{ + struct device_config *conf; + int rc; + + TAILQ_FOREACH(conf, &device_configs, next) { + if (conf->type != type) + continue; + rc = func(conf->cmdline); + if (0 != rc) + return rc; + } + return 0; +} + +static int generic_parse(const char *cmdline) +{ + DeviceState *dev; + + dev = qdev_device_add(cmdline); + if (!dev) + return -1; + return 0; +} + int main(int argc, char **argv, char **envp) { const char *gdbstub_dev = NULL; @@ -4984,8 +5029,6 @@ int main(int argc, char **argv, char **envp) int cyls, heads, secs, translation; const char *net_clients[MAX_NET_CLIENTS]; int nb_net_clients; - const char *bt_opts[MAX_BT_CMDLINE]; - int nb_bt_opts; int hda_index; int optind; const char *r, *optarg; @@ -5000,8 +5043,6 @@ int main(int argc, char **argv, char **envp) const char *loadvm = NULL; QEMUMachine *machine; const char *cpu_model; - const char *usb_devices[MAX_USB_CMDLINE]; - int usb_devices_index; #ifndef _WIN32 int fds[2]; #endif @@ -5081,10 +5122,7 @@ int main(int argc, char **argv, char **envp) node_cpumask[i] = 0; } - usb_devices_index = 0; - nb_net_clients = 0; - nb_bt_opts = 0; nb_drives = 0; nb_drives_opt = 0; nb_numa_nodes = 0; @@ -5331,11 +5369,7 @@ int main(int argc, char **argv, char **envp) break; #endif case QEMU_OPTION_bt: - if (nb_bt_opts >= MAX_BT_CMDLINE) { - fprintf(stderr, "qemu: too many bluetooth options\n"); - exit(1); - } - bt_opts[nb_bt_opts++] = optarg; + add_device_config(DEV_BT, optarg); break; #ifdef HAS_AUDIO case QEMU_OPTION_audio_help: @@ -5577,12 +5611,10 @@ int main(int argc, char **argv, char **envp) break; case QEMU_OPTION_usbdevice: usb_enabled = 1; - if (usb_devices_index >= MAX_USB_CMDLINE) { - fprintf(stderr, "Too many USB devices\n"); - exit(1); - } - usb_devices[usb_devices_index] = optarg; - usb_devices_index++; + add_device_config(DEV_USB, optarg); + break; + case QEMU_OPTION_device: + add_device_config(DEV_GENERIC, optarg); break; case QEMU_OPTION_smp: smp_cpus = atoi(optarg); @@ -5893,9 +5925,8 @@ int main(int argc, char **argv, char **envp) net_client_check(); /* init the bluetooth world */ - for (i = 0; i < nb_bt_opts; i++) - if (bt_parse(bt_opts[i])) - exit(1); + if (foreach_device_config(DEV_BT, bt_parse)) + exit(1); /* init the memory */ if (ram_size == 0) @@ -6083,14 +6114,13 @@ int main(int argc, char **argv, char **envp) /* init USB devices */ if (usb_enabled) { - for(i = 0; i < usb_devices_index; i++) { - if (usb_device_add(usb_devices[i], 0) < 0) { - fprintf(stderr, "Warning: could not add USB device %s\n", - usb_devices[i]); - } - } + foreach_device_config(DEV_USB, usb_parse); } + /* init generic devices */ + if (foreach_device_config(DEV_GENERIC, generic_parse)) + exit(1); + if (!display_state) dumb_display_init(); /* just use the first displaystate for the moment */ -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 05/13] qdev: add -device command line option. 2009-07-03 10:22 ` [Qemu-devel] [PATCH 05/13] qdev: add -device command line option Gerd Hoffmann @ 2009-07-07 15:38 ` Gerd Hoffmann 0 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-07 15:38 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel [-- Attachment #1: Type: text/plain, Size: 438 bytes --] On 07/03/09 12:22, Gerd Hoffmann wrote: > Add a linked list where command line options can be saved. > Use it for the new -device and for the -usbdevice and -bt switches. Oops, this one doesn't build: vl.c must include qdev.h, updated patch attached. My testbuild script didn't abort at failures due to a bug and a patch later in my patch queue "fixes" it by adding a indirect qdev.h reference, so I didn't notice. cheers, Gerd [-- Attachment #2: 0001-qdev-add-device-command-line-option.patch --] [-- Type: text/plain, Size: 6804 bytes --] >From 4f9a4ea2b909b38e326d87434a6b32454c9c1166 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann <kraxel@redhat.com> Date: Tue, 30 Jun 2009 17:19:19 +0200 Subject: [PATCH] qdev: add -device command line option. Add a linked list where command line options can be saved. Use it for the new -device and for the -usbdevice and -bt switches. --- hw/qdev.c | 4 ++- qemu-options.hx | 2 + vl.c | 97 ++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 69 insertions(+), 34 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 6bc2530..82bcd04 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -124,8 +124,10 @@ DeviceState *qdev_device_add(const char *cmdline) if (params) { while (params[0]) { - if (2 != sscanf(params, "%31[^=]=%255[^,]%n", tag, value, &n)) + if (2 != sscanf(params, "%31[^=]=%255[^,]%n", tag, value, &n)) { + fprintf(stderr, "parse error at \"%s\"\n", params); break; + } params += n; if (strcmp(tag, "addr") == 0) continue; diff --git a/qemu-options.hx b/qemu-options.hx index a94f9d3..67d7bd0 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -364,6 +364,8 @@ Network adapter that supports CDC ethernet and RNDIS protocols. @end table ETEXI +DEF("device", HAS_ARG, QEMU_OPTION_device, + "-device driver[,options] add device\n") DEF("name", HAS_ARG, QEMU_OPTION_name, "-name string set the name of the guest\n") STEXI diff --git a/vl.c b/vl.c index 7b7489c..1b1852a 100644 --- a/vl.c +++ b/vl.c @@ -142,6 +142,7 @@ int main(int argc, char **argv) #include "hw/watchdog.h" #include "hw/smbios.h" #include "hw/xen.h" +#include "hw/qdev.h" #include "bt-host.h" #include "net.h" #include "monitor.h" @@ -181,12 +182,6 @@ int main(int argc, char **argv) #define DEFAULT_RAM_SIZE 128 -/* Max number of USB devices that can be specified on the commandline. */ -#define MAX_USB_CMDLINE 8 - -/* Max number of bluetooth switches on the commandline. */ -#define MAX_BT_CMDLINE 10 - /* XXX: use a two level table to limit memory usage */ #define MAX_IOPORTS 65536 @@ -2787,6 +2782,11 @@ static int usb_device_del(const char *devname) return usb_device_del_addr(bus_num, addr); } +static int usb_parse(const char *cmdline) +{ + return usb_device_add(cmdline, 0); +} + void do_usb_add(Monitor *mon, const char *devname) { usb_device_add(devname, 1); @@ -4970,6 +4970,52 @@ char *qemu_find_file(int type, const char *name) return buf; } +struct device_config { + enum { + DEV_GENERIC, /* -device */ + DEV_USB, /* -usbdevice */ + DEV_BT, /* -bt */ + } type; + const char *cmdline; + TAILQ_ENTRY(device_config) next; +}; +TAILQ_HEAD(, device_config) device_configs = TAILQ_HEAD_INITIALIZER(device_configs); + +static void add_device_config(int type, const char *cmdline) +{ + struct device_config *conf; + + conf = qemu_mallocz(sizeof(*conf)); + conf->type = type; + conf->cmdline = cmdline; + TAILQ_INSERT_TAIL(&device_configs, conf, next); +} + +static int foreach_device_config(int type, int (*func)(const char *cmdline)) +{ + struct device_config *conf; + int rc; + + TAILQ_FOREACH(conf, &device_configs, next) { + if (conf->type != type) + continue; + rc = func(conf->cmdline); + if (0 != rc) + return rc; + } + return 0; +} + +static int generic_parse(const char *cmdline) +{ + DeviceState *dev; + + dev = qdev_device_add(cmdline); + if (!dev) + return -1; + return 0; +} + int main(int argc, char **argv, char **envp) { const char *gdbstub_dev = NULL; @@ -4984,8 +5030,6 @@ int main(int argc, char **argv, char **envp) int cyls, heads, secs, translation; const char *net_clients[MAX_NET_CLIENTS]; int nb_net_clients; - const char *bt_opts[MAX_BT_CMDLINE]; - int nb_bt_opts; int hda_index; int optind; const char *r, *optarg; @@ -5000,8 +5044,6 @@ int main(int argc, char **argv, char **envp) const char *loadvm = NULL; QEMUMachine *machine; const char *cpu_model; - const char *usb_devices[MAX_USB_CMDLINE]; - int usb_devices_index; #ifndef _WIN32 int fds[2]; #endif @@ -5081,10 +5123,7 @@ int main(int argc, char **argv, char **envp) node_cpumask[i] = 0; } - usb_devices_index = 0; - nb_net_clients = 0; - nb_bt_opts = 0; nb_drives = 0; nb_drives_opt = 0; nb_numa_nodes = 0; @@ -5331,11 +5370,7 @@ int main(int argc, char **argv, char **envp) break; #endif case QEMU_OPTION_bt: - if (nb_bt_opts >= MAX_BT_CMDLINE) { - fprintf(stderr, "qemu: too many bluetooth options\n"); - exit(1); - } - bt_opts[nb_bt_opts++] = optarg; + add_device_config(DEV_BT, optarg); break; #ifdef HAS_AUDIO case QEMU_OPTION_audio_help: @@ -5577,12 +5612,10 @@ int main(int argc, char **argv, char **envp) break; case QEMU_OPTION_usbdevice: usb_enabled = 1; - if (usb_devices_index >= MAX_USB_CMDLINE) { - fprintf(stderr, "Too many USB devices\n"); - exit(1); - } - usb_devices[usb_devices_index] = optarg; - usb_devices_index++; + add_device_config(DEV_USB, optarg); + break; + case QEMU_OPTION_device: + add_device_config(DEV_GENERIC, optarg); break; case QEMU_OPTION_smp: smp_cpus = atoi(optarg); @@ -5893,9 +5926,8 @@ int main(int argc, char **argv, char **envp) net_client_check(); /* init the bluetooth world */ - for (i = 0; i < nb_bt_opts; i++) - if (bt_parse(bt_opts[i])) - exit(1); + if (foreach_device_config(DEV_BT, bt_parse)) + exit(1); /* init the memory */ if (ram_size == 0) @@ -6083,14 +6115,13 @@ int main(int argc, char **argv, char **envp) /* init USB devices */ if (usb_enabled) { - for(i = 0; i < usb_devices_index; i++) { - if (usb_device_add(usb_devices[i], 0) < 0) { - fprintf(stderr, "Warning: could not add USB device %s\n", - usb_devices[i]); - } - } + foreach_device_config(DEV_USB, usb_parse); } + /* init generic devices */ + if (foreach_device_config(DEV_GENERIC, generic_parse)) + exit(1); + if (!display_state) dumb_display_init(); /* just use the first displaystate for the moment */ -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 06/13] qdev: add no_user, alias and desc 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann ` (4 preceding siblings ...) 2009-07-03 10:22 ` [Qemu-devel] [PATCH 05/13] qdev: add -device command line option Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 07/13] qdev: es1370 description Gerd Hoffmann ` (6 subsequent siblings) 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann no_user: prevent users from adding certain devices. desc: description of the device. alias: to allow user friendly shortcuts on the command line, i.e. -device usbmouse instead of -device "QEMU USB Mouse" or -device lsi instead of -device lsi53c895a Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/qdev.c | 26 +++++++++++++++++++++++++- hw/qdev.h | 3 +++ 2 files changed, 28 insertions(+), 1 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 82bcd04..d72a8ef 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -50,6 +50,7 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name) { DeviceInfo *info; + /* first check device names */ for (info = device_info_list; info != NULL; info = info->next) { if (bus_info && info->bus_info != bus_info) continue; @@ -57,6 +58,17 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name) continue; return info; } + + /* failing that check the aliases */ + for (info = device_info_list; info != NULL; info = info->next) { + if (bus_info && info->bus_info != bus_info) + continue; + if (!info->alias) + continue; + if (strcmp(info->alias, name) != 0) + continue; + return info; + } return NULL; } @@ -104,7 +116,14 @@ DeviceState *qdev_device_add(const char *cmdline) } if (strcmp(driver, "?") == 0) { for (info = device_info_list; info != NULL; info = info->next) { - fprintf(stderr, "name \"%s\", bus %s\n", info->name, info->bus_info->name); + fprintf(stderr, "name \"%s\", bus %s", info->name, info->bus_info->name); + if (info->alias) + fprintf(stderr, ", alias \"%s\"", info->alias); + if (info->desc) + fprintf(stderr, ", desc \"%s\"", info->desc); + if (info->no_user) + fprintf(stderr, ", no-user"); + fprintf(stderr, "\n"); } return NULL; } @@ -119,6 +138,11 @@ DeviceState *qdev_device_add(const char *cmdline) info->bus_info->name); return NULL; } + if (info->no_user) { + fprintf(stderr, "device \"%s\" can't be added via command line\n", + info->name); + return NULL; + } qdev = info->bus_info->add(driver, strlen(addr) ? addr : NULL); diff --git a/hw/qdev.h b/hw/qdev.h index a856576..03413b1 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -80,8 +80,11 @@ typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv, struct DeviceInfo { const char *name; + const char *alias; + const char *desc; size_t size; Property *props; + int no_user; /* Private to qdev / bus. */ qdev_initfn init; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 07/13] qdev: es1370 description 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann ` (5 preceding siblings ...) 2009-07-03 10:22 ` [Qemu-devel] [PATCH 06/13] qdev: add no_user, alias and desc Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 08/13] qdev: convert all vga Gerd Hoffmann ` (5 subsequent siblings) 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/es1370.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/hw/es1370.c b/hw/es1370.c index baad7cc..0cfdb76 100644 --- a/hw/es1370.c +++ b/hw/es1370.c @@ -1054,6 +1054,7 @@ int es1370_init (PCIBus *bus) static PCIDeviceInfo es1370_info = { .qdev.name = "ES1370", + .qdev.desc = "Ensoniq AudioPCI Sound Card", .qdev.size = sizeof (PCIES1370State), .init = es1370_initfn, }; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 08/13] qdev: convert all vga 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann ` (6 preceding siblings ...) 2009-07-03 10:22 ` [Qemu-devel] [PATCH 07/13] qdev: es1370 description Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 09/13] qdev/pci: hook up i440fx Gerd Hoffmann ` (4 subsequent siblings) 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/cirrus_vga.c | 85 ++++++++++++++++++++++++++--------------------- hw/vga.c | 98 ++++++++++++++++++++++++++++++++++-------------------- hw/vmware_vga.c | 26 +++++++++++--- 3 files changed, 129 insertions(+), 80 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 902b3ee..1d800e9 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -3301,46 +3301,55 @@ static void pci_cirrus_write_config(PCIDevice *d, cirrus_update_memory_access(s); } +static void pci_cirrus_vga_initfn(PCIDevice *dev) +{ + PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev); + CirrusVGAState *s = &d->cirrus_vga; + uint8_t *pci_conf = d->dev.config; + int device_id = CIRRUS_ID_CLGD5446; + + /* setup VGA */ + vga_common_init(&s->vga, VGA_RAM_SIZE); + cirrus_init_common(s, device_id, 1); + s->vga.pci_dev = (PCIDevice *)d; + s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate, + s->vga.screen_dump, s->vga.text_update, + &s->vga); + + /* setup PCI */ + pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CIRRUS); + pci_config_set_device_id(pci_conf, device_id); + pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS; + pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA); + pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; + + /* setup memory space */ + /* memory #0 LFB */ + /* memory #1 memory-mapped I/O */ + /* XXX: s->vga.vram_size must be a power of two */ + pci_register_bar((PCIDevice *)d, 0, 0x2000000, + PCI_ADDRESS_SPACE_MEM_PREFETCH, cirrus_pci_lfb_map); + if (device_id == CIRRUS_ID_CLGD5446) { + pci_register_bar((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE, + PCI_ADDRESS_SPACE_MEM, cirrus_pci_mmio_map); + } + /* XXX: ROM BIOS */ +} + void pci_cirrus_vga_init(PCIBus *bus) { - PCICirrusVGAState *d; - uint8_t *pci_conf; - CirrusVGAState *s; - int device_id; - - device_id = CIRRUS_ID_CLGD5446; - - /* setup PCI configuration registers */ - d = (PCICirrusVGAState *)pci_register_device(bus, "Cirrus VGA", - sizeof(PCICirrusVGAState), - -1, NULL, pci_cirrus_write_config); - pci_conf = d->dev.config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CIRRUS); - pci_config_set_device_id(pci_conf, device_id); - pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS; - pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA); - pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; - - /* setup VGA */ - s = &d->cirrus_vga; - vga_common_init(&s->vga, VGA_RAM_SIZE); - cirrus_init_common(s, device_id, 1); - - s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate, - s->vga.screen_dump, s->vga.text_update, - &s->vga); + pci_create_simple(bus, -1, "Cirrus VGA"); +} - s->vga.pci_dev = (PCIDevice *)d; +static PCIDeviceInfo cirrus_vga_info = { + .qdev.name = "Cirrus VGA", + .qdev.size = sizeof(PCICirrusVGAState), + .init = pci_cirrus_vga_initfn, + .config_write = pci_cirrus_write_config, +}; - /* setup memory space */ - /* memory #0 LFB */ - /* memory #1 memory-mapped I/O */ - /* XXX: s->vga.vram_size must be a power of two */ - pci_register_bar((PCIDevice *)d, 0, 0x2000000, - PCI_ADDRESS_SPACE_MEM_PREFETCH, cirrus_pci_lfb_map); - if (device_id == CIRRUS_ID_CLGD5446) { - pci_register_bar((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE, - PCI_ADDRESS_SPACE_MEM, cirrus_pci_mmio_map); - } - /* XXX: ROM BIOS */ +static void cirrus_vga_register(void) +{ + pci_qdev_register(&cirrus_vga_info); } +device_init(cirrus_vga_register); diff --git a/hw/vga.c b/hw/vga.c index 403f6ff..e1a470d 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -2480,52 +2480,78 @@ static void pci_vga_write_config(PCIDevice *d, s->map_addr = 0; } -int pci_vga_init(PCIBus *bus, - unsigned long vga_bios_offset, int vga_bios_size) -{ - PCIVGAState *d; - VGAState *s; - uint8_t *pci_conf; - - d = (PCIVGAState *)pci_register_device(bus, "VGA", - sizeof(PCIVGAState), - -1, NULL, pci_vga_write_config); - if (!d) - return -1; - s = &d->vga_state; - - vga_common_init(s, VGA_RAM_SIZE); - vga_init(s); - - s->ds = graphic_console_init(s->update, s->invalidate, - s->screen_dump, s->text_update, s); - - s->pci_dev = &d->dev; - - pci_conf = d->dev.config; - // dummy VGA (same as Bochs ID) - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_QEMU); - pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_QEMU_VGA); - pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA); - pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type - - /* XXX: VGA_RAM_SIZE must be a power of two */ - pci_register_bar(&d->dev, 0, VGA_RAM_SIZE, - PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map); - if (vga_bios_size != 0) { +static void pci_vga_initfn(PCIDevice *dev) +{ + PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev); + VGAState *s = &d->vga_state; + uint8_t *pci_conf = d->dev.config; + + // vga + console init + vga_common_init(s, VGA_RAM_SIZE); + vga_init(s); + s->pci_dev = &d->dev; + s->ds = graphic_console_init(s->update, s->invalidate, + s->screen_dump, s->text_update, s); + + // dummy VGA (same as Bochs ID) + pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_QEMU); + pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_QEMU_VGA); + pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA); + pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type + + /* XXX: VGA_RAM_SIZE must be a power of two */ + pci_register_bar(&d->dev, 0, VGA_RAM_SIZE, + PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map); + + if (s->bios_size) { unsigned int bios_total_size; - s->bios_offset = vga_bios_offset; - s->bios_size = vga_bios_size; /* must be a power of two */ bios_total_size = 1; - while (bios_total_size < vga_bios_size) + while (bios_total_size < s->bios_size) bios_total_size <<= 1; pci_register_bar(&d->dev, PCI_ROM_SLOT, bios_total_size, - PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map); + PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map); } +} + +int pci_vga_init(PCIBus *bus, + unsigned long vga_bios_offset, int vga_bios_size) +{ + DeviceState *qdev; + + qdev = pci_create("VGA", NULL); + qdev_prop_set_uint32(qdev, "bios-offset", vga_bios_offset); + qdev_prop_set_uint32(qdev, "bios-size", vga_bios_offset); + qdev_init(qdev); + return 0; } +static PCIDeviceInfo vga_info = { + .qdev.name = "VGA", + .qdev.size = sizeof(PCIVGAState), + .init = pci_vga_initfn, + .config_write = pci_vga_write_config, + .qdev.props = (Property[]) { + { + .name = "bios-offset", + .info = &qdev_prop_hex32, + .offset = offsetof(PCIVGAState, vga_state.bios_offset), + },{ + .name = "bios-size", + .info = &qdev_prop_hex32, + .offset = offsetof(PCIVGAState, vga_state.bios_size), + }, + {/* end of list */} + } +}; + +static void vga_register(void) +{ + pci_qdev_register(&vga_info); +} +device_init(vga_register); + /********************************************************/ /* vga screen dump */ diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index accdac4..5ceebf1 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -1210,14 +1210,11 @@ static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num, iomemtype); } -void pci_vmsvga_init(PCIBus *bus) +static void pci_vmsvga_initfn(PCIDevice *dev) { - struct pci_vmsvga_state_s *s; + struct pci_vmsvga_state_s *s = + DO_UPCAST(struct pci_vmsvga_state_s, card, dev); - /* Setup PCI configuration */ - s = (struct pci_vmsvga_state_s *) - pci_register_device(bus, "QEMUware SVGA", - sizeof(struct pci_vmsvga_state_s), -1, NULL, NULL); pci_config_set_vendor_id(s->card.config, PCI_VENDOR_ID_VMWARE); pci_config_set_device_id(s->card.config, SVGA_PCI_DEVICE_ID); s->card.config[PCI_COMMAND] = 0x07; /* I/O + Memory */ @@ -1240,3 +1237,20 @@ void pci_vmsvga_init(PCIBus *bus) register_savevm("vmware_vga", 0, 0, pci_vmsvga_save, pci_vmsvga_load, s); } + +void pci_vmsvga_init(PCIBus *bus) +{ + pci_create_simple(bus, -1, "QEMUware SVGA"); +} + +static PCIDeviceInfo vmsvga_info = { + .qdev.name = "QEMUware SVGA", + .qdev.size = sizeof(struct pci_vmsvga_state_s), + .init = pci_vmsvga_initfn, +}; + +static void vmsvga_register(void) +{ + pci_qdev_register(&vmsvga_info); +} +device_init(vmsvga_register); -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 09/13] qdev/pci: hook up i440fx. 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann ` (7 preceding siblings ...) 2009-07-03 10:22 ` [Qemu-devel] [PATCH 08/13] qdev: convert all vga Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 10/13] qdev: add user-specified identifier to devices Gerd Hoffmann ` (3 subsequent siblings) 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Hook i44fx pcihost into sysbus. Convert Host bridge and ISA bridge pci devices to qdev. Tag as no-user. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/pci_host.h | 3 ++ hw/piix_pci.c | 108 +++++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 85 insertions(+), 26 deletions(-) diff --git a/hw/pci_host.h b/hw/pci_host.h index 757b0e2..48862b5 100644 --- a/hw/pci_host.h +++ b/hw/pci_host.h @@ -28,6 +28,8 @@ /* debug PCI */ //#define DEBUG_PCI +#include "sysbus.h" + #ifdef DEBUG_PCI #define PCI_DPRINTF(fmt, ...) \ do { printf("pci_host_data: " fmt , ## __VA_ARGS__); } while (0) @@ -36,6 +38,7 @@ do { printf("pci_host_data: " fmt , ## __VA_ARGS__); } while (0) #endif typedef struct { + SysBusDevice busdev; uint32_t config_reg; PCIBus *bus; } PCIHostState; diff --git a/hw/piix_pci.c b/hw/piix_pci.c index fce01d4..a5d42d1 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -25,6 +25,7 @@ #include "hw.h" #include "pc.h" #include "pci.h" +#include "sysbus.h" typedef uint32_t pci_addr_t; #include "pci_host.h" @@ -169,16 +170,9 @@ static int i440fx_load(QEMUFile* f, void *opaque, int version_id) return 0; } -PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic) +static void i440fx_pcihost_initfn(SysBusDevice *dev) { - PCIBus *b; - PCIDevice *d; - I440FXState *s; - - s = qemu_mallocz(sizeof(I440FXState)); - b = pci_register_bus(NULL, "pci", - piix3_set_irq, pci_slot_get_pirq, pic, 0, 4); - s->bus = b; + I440FXState *s = FROM_SYSBUS(I440FXState, dev); register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s); register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s); @@ -189,10 +183,10 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic) register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s); register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s); register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s); +} - d = pci_register_device(b, "i440FX", sizeof(PCIDevice), 0, - NULL, i440fx_write_config); - +static void i440fx_initfn(PCIDevice *d) +{ pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL); pci_config_set_device_id(d->config, PCI_DEVICE_ID_INTEL_82441); d->config[0x08] = 0x02; // revision @@ -202,7 +196,25 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic) d->config[0x72] = 0x02; /* SMRAM */ register_savevm("I440FX", 0, 2, i440fx_save, i440fx_load, d); +} + +PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic) +{ + DeviceState *dev; + PCIBus *b; + PCIDevice *d; + I440FXState *s; + + dev = qdev_create(NULL, "i440FX-pcihost"); + s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev)); + b = pci_register_bus(&s->busdev.qdev, "pci", + piix3_set_irq, pci_slot_get_pirq, pic, 0, 4); + s->bus = b; + qdev_init(dev); + + d = pci_create_simple(b, 0, "i440FX"); *pi440fx_state = d; + return b; } @@ -326,49 +338,93 @@ static int piix_load(QEMUFile* f, void *opaque, int version_id) return pci_device_load(d, f); } -int piix3_init(PCIBus *bus, int devfn) +static void piix3_initfn(PCIDevice *d) { - PCIDevice *d; uint8_t *pci_conf; - d = pci_register_device(bus, "PIIX3", sizeof(PCIDevice), - devfn, NULL, NULL); register_savevm("PIIX3", 0, 2, piix_save, piix_load, d); - piix3_dev = d; pci_conf = d->config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_0); // 82371SB PIIX3 PCI-to-ISA bridge (Step A1) pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA); pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION; // header_type = PCI_multifunction, generic + piix3_dev = d; piix3_reset(d); qemu_register_reset(piix3_reset, d); - return d->devfn; } -int piix4_init(PCIBus *bus, int devfn) +static void piix4_initfn(PCIDevice *d) { - PCIDevice *d; uint8_t *pci_conf; - d = pci_register_device(bus, "PIIX4", sizeof(PCIDevice), - devfn, NULL, NULL); register_savevm("PIIX4", 0, 2, piix_save, piix_load, d); - piix4_dev = d; pci_conf = d->config; - pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_0); // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA); pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION; // header_type = PCI_multifunction, generic - + piix4_dev = d; piix4_reset(d); qemu_register_reset(piix4_reset, d); +} + +int piix3_init(PCIBus *bus, int devfn) +{ + PCIDevice *d; + + d = pci_create_simple(bus, devfn, "PIIX3"); return d->devfn; } + +int piix4_init(PCIBus *bus, int devfn) +{ + PCIDevice *d; + + d = pci_create_simple(bus, devfn, "PIIX4"); + return d->devfn; +} + +static PCIDeviceInfo i440fx_info[] = { + { + .qdev.name = "i440FX", + .qdev.desc = "Host bridge", + .qdev.size = sizeof(PCIDevice), + .qdev.no_user = 1, + .init = i440fx_initfn, + .config_write = i440fx_write_config, + },{ + .qdev.name = "PIIX3", + .qdev.desc = "ISA bridge", + .qdev.size = sizeof(PCIDevice), + .qdev.no_user = 1, + .init = piix3_initfn, + },{ + .qdev.name = "PIIX4", + .qdev.desc = "ISA bridge", + .qdev.size = sizeof(PCIDevice), + .qdev.no_user = 1, + .init = piix4_initfn, + },{ + /* end of list */ + } +}; + +static SysBusDeviceInfo i440fx_pcihost_info = { + .init = i440fx_pcihost_initfn, + .qdev.name = "i440FX-pcihost", + .qdev.size = sizeof(I440FXState), + .qdev.no_user = 1, +}; + +static void i440fx_register(void) +{ + sysbus_register_withprop(&i440fx_pcihost_info); + pci_qdev_register_many(i440fx_info); +} +device_init(i440fx_register); -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 10/13] qdev: add user-specified identifier to devices. 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann ` (8 preceding siblings ...) 2009-07-03 10:22 ` [Qemu-devel] [PATCH 09/13] qdev/pci: hook up i440fx Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 11/13] switch balloon initialization to -device Gerd Hoffmann ` (2 subsequent siblings) 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Add id field to DeviceState. Make qdev_device_add() fill it if supplied on the command line (i.e. -device foo,id=bar). Make "info qtree" print it. This helps users and management apps identifying devices in monitor output, which is especially useful with otherwise identical devices such as two virtio disks. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/qdev.c | 5 ++++- hw/qdev.h | 1 + 2 files changed, 5 insertions(+), 1 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index d72a8ef..979ed4f 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -147,6 +147,7 @@ DeviceState *qdev_device_add(const char *cmdline) qdev = info->bus_info->add(driver, strlen(addr) ? addr : NULL); if (params) { + get_param_value(qdev->id, sizeof(qdev->id), "id", params); while (params[0]) { if (2 != sscanf(params, "%31[^=]=%255[^,]%n", tag, value, &n)) { fprintf(stderr, "parse error at \"%s\"\n", params); @@ -155,6 +156,8 @@ DeviceState *qdev_device_add(const char *cmdline) params += n; if (strcmp(tag, "addr") == 0) continue; + if (strcmp(tag, "id") == 0) + continue; if (-1 == qdev_prop_parse(qdev, tag, value)) { fprintf(stderr, "can't set property \"%s\" to \"%s\" for \"%s\"\n", tag, value, driver); @@ -329,7 +332,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props, static void qdev_print(Monitor *mon, DeviceState *dev, int indent) { BusState *child; - qdev_printf("dev: %s\n", dev->info->name); + qdev_printf("dev: %s, id \"%s\"\n", dev->info->name, dev->id); indent += 2; if (dev->num_gpio_in) { qdev_printf("gpio-in %d\n", dev->num_gpio_in); diff --git a/hw/qdev.h b/hw/qdev.h index 03413b1..cf6083f 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -17,6 +17,7 @@ typedef struct BusInfo BusInfo; /* This structure should not be accessed directly. We declare it here so that it can be embedded in individual device state structures. */ struct DeviceState { + char id[32]; DeviceInfo *info; BusState *parent_bus; int num_gpio_out; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 11/13] switch balloon initialization to -device. 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann ` (9 preceding siblings ...) 2009-07-03 10:22 ` [Qemu-devel] [PATCH 10/13] qdev: add user-specified identifier to devices Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 12/13] qdev: add id= support for pci nics Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 13/13] qdev: print device id in "info pci" Gerd Hoffmann 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann With that patch applied "-balloon virtio,args" becomes a shortcut for "-device virtio-balloon-pci,args". Side effects: - ballon device gains support for id=<tag>. - ballon device is off by default now. - initialization order changes, which may in different pci slot assignment depending on the VM configuration. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/pc.c | 6 ----- sysemu.h | 2 - vl.c | 65 +++++++++++++++++++++++++++++++++++++------------------------ 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 2b89356..ccd2fed 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1407,12 +1407,6 @@ static void pc_init1(ram_addr_t ram_size, } } - /* Add virtio balloon device */ - if (pci_enabled && virtio_balloon) { - qdev = pci_create("virtio-balloon-pci", virtio_balloon_devaddr); - qdev_init(qdev); - } - /* Add virtio console devices */ if (pci_enabled) { for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { diff --git a/sysemu.h b/sysemu.h index 06dc4c6..9a83bfe 100644 --- a/sysemu.h +++ b/sysemu.h @@ -116,8 +116,6 @@ extern int win2k_install_hack; extern int rtc_td_hack; extern int alt_grab; extern int usb_enabled; -extern int virtio_balloon; -extern const char *virtio_balloon_devaddr; extern int smp_cpus; extern int cursor_hide; extern int graphic_rotate; diff --git a/vl.c b/vl.c index ca82f80..b455cfc 100644 --- a/vl.c +++ b/vl.c @@ -236,8 +236,6 @@ int smp_cpus = 1; const char *vnc_display; int acpi_enabled = 1; int no_hpet = 0; -int virtio_balloon = 1; -const char *virtio_balloon_devaddr; int fd_bootchk = 1; int no_reboot = 0; int no_shutdown = 0; @@ -4762,29 +4760,6 @@ static void select_vgahw (const char *p) } } -#ifdef TARGET_I386 -static int balloon_parse(const char *arg) -{ - char buf[128]; - const char *p; - - if (!strcmp(arg, "none")) { - virtio_balloon = 0; - } else if (!strncmp(arg, "virtio", 6)) { - virtio_balloon = 1; - if (arg[6] == ',') { - p = arg + 7; - if (get_param_value(buf, sizeof(buf), "addr", p)) { - virtio_balloon_devaddr = strdup(buf); - } - } - } else { - return -1; - } - return 0; -} -#endif - #ifdef _WIN32 static BOOL WINAPI qemu_ctrl_handler(DWORD type) { @@ -4990,6 +4965,24 @@ static void add_device_config(int type, const char *cmdline) TAILQ_INSERT_TAIL(&device_configs, conf, next); } +#ifdef TARGET_I386 +static void add_device_config_params(int type, const char *driver, + const char *params) +{ + char *buf; + size_t len,pos; + + len = strlen(driver) + 1; + if (params) + len += strlen(params) + 1; + buf = qemu_mallocz(len); + pos = snprintf(buf, len, "%s", driver); + if (params) + pos += snprintf(buf+pos, len-pos, ",%s", params); + add_device_config(type, buf); +} +#endif + static int foreach_device_config(int type, int (*func)(const char *cmdline)) { struct device_config *conf; @@ -5015,6 +5008,26 @@ static int generic_parse(const char *cmdline) return 0; } +#ifdef TARGET_I386 +static int add_device_balloon(const char *arg) +{ + const char *name = NULL, *params = NULL; + + if (!strcmp(arg, "none")) + return 0; + if (!strncmp(arg, "virtio", 6)) { + name = "virtio-balloon-pci"; + if (arg[6] == ',') + params = arg+7; + } + if (!name) + return -1; + + add_device_config_params(DEV_GENERIC, name, params); + return 0; +} +#endif + int main(int argc, char **argv, char **envp) { const char *gdbstub_dev = NULL; @@ -5635,7 +5648,7 @@ int main(int argc, char **argv, char **envp) no_hpet = 1; break; case QEMU_OPTION_balloon: - if (balloon_parse(optarg) < 0) { + if (add_device_balloon(optarg) < 0) { fprintf(stderr, "Unknown -balloon argument %s\n", optarg); exit(1); } -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 12/13] qdev: add id= support for pci nics. 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann ` (10 preceding siblings ...) 2009-07-03 10:22 ` [Qemu-devel] [PATCH 11/13] switch balloon initialization to -device Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 13/13] qdev: print device id in "info pci" Gerd Hoffmann 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/pci.c | 1 + net.c | 5 ++++- net.h | 1 + 3 files changed, 6 insertions(+), 1 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index af72468..5acf0d9 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -820,6 +820,7 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, for (i = 0; pci_nic_models[i]; i++) { if (strcmp(nd->model, pci_nic_models[i]) == 0) { dev = pci_create(pci_nic_names[i], devaddr); + snprintf(dev->id, sizeof(dev->id), "%s", nd->id); dev->nd = nd; qdev_init(dev); nd->private = dev; diff --git a/net.c b/net.c index 001ebcb..aeadd4a 100644 --- a/net.c +++ b/net.c @@ -2406,7 +2406,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p) } if (!strcmp(device, "nic")) { static const char * const nic_params[] = { - "vlan", "name", "macaddr", "model", "addr", "vectors", NULL + "vlan", "name", "macaddr", "model", "addr", "id", "vectors", NULL }; NICInfo *nd; uint8_t *macaddr; @@ -2444,6 +2444,9 @@ int net_client_init(Monitor *mon, const char *device, const char *p) if (get_param_value(buf, sizeof(buf), "addr", p)) { nd->devaddr = strdup(buf); } + if (get_param_value(buf, sizeof(buf), "id", p)) { + nd->id = strdup(buf); + } nd->nvectors = NIC_NVECTORS_UNSPECIFIED; if (get_param_value(buf, sizeof(buf), "vectors", p)) { char *endptr; diff --git a/net.h b/net.h index 64d5e22..c317671 100644 --- a/net.h +++ b/net.h @@ -95,6 +95,7 @@ struct NICInfo { const char *model; const char *name; const char *devaddr; + const char *id; VLANState *vlan; void *private; int used; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 13/13] qdev: print device id in "info pci". 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann ` (11 preceding siblings ...) 2009-07-03 10:22 ` [Qemu-devel] [PATCH 12/13] qdev: add id= support for pci nics Gerd Hoffmann @ 2009-07-03 10:22 ` Gerd Hoffmann 12 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-03 10:22 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/pci.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 5acf0d9..3410ea7 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -738,6 +738,7 @@ static void pci_info_device(PCIDevice *d) } } } + monitor_printf(mon, " id \"%s\"\n", d->qdev.id); if (class == 0x0604 && d->config[0x19] != 0) { pci_for_each_device(d->config[0x19], pci_info_device); } -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH v2 0/13] qdev patches: properties, -device switch, id=<tag> & more. @ 2009-07-10 11:26 Gerd Hoffmann 2009-07-10 11:26 ` [Qemu-devel] [PATCH 10/13] qdev: add user-specified identifier to devices Gerd Hoffmann 0 siblings, 1 reply; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-10 11:26 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Hi, This patch is a repost of the patch series posted last friday. What is in there? First the qdev property rework. Quite big one, but as it puts the way properties work upside down it can hardly be split into smaller pieces. Support for property default values added since I posted it last time. The patch description is much better too. Otherwise it is unchanged. The other patches are building on top of the properties. They are a bunch of little, self-contained and friendly patches. They bring: * A new, generic -device switch to add devices to your VM. * Support for attaching user-specified ids to devices. * A few more devices being switched to qdev. v2 brings some minor changes: * rebased, resolved some conflicts. * picked up the *_dev name convention for bus_info methods. * folded in the two incremental fixes posted earlier this week. cheers, Gerd ^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 10/13] qdev: add user-specified identifier to devices. 2009-07-10 11:26 [Qemu-devel] [PATCH v2 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann @ 2009-07-10 11:26 ` Gerd Hoffmann 2009-07-10 17:31 ` Paul Brook 0 siblings, 1 reply; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-10 11:26 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Add id field to DeviceState. Make qdev_device_add() fill it if supplied on the command line (i.e. -device foo,id=bar). Make "info qtree" print it. This helps users and management apps identifying devices in monitor output, which is especially useful with otherwise identical devices such as two virtio disks. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/qdev.c | 5 ++++- hw/qdev.h | 1 + 2 files changed, 5 insertions(+), 1 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index dcca6ac..a075e86 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -153,6 +153,7 @@ DeviceState *qdev_device_add(const char *cmdline) qdev = info->bus_info->add_dev(driver, strlen(addr) ? addr : NULL); if (params) { + get_param_value(qdev->id, sizeof(qdev->id), "id", params); while (params[0]) { if (2 != sscanf(params, "%31[^=]=%255[^,]%n", tag, value, &n)) { fprintf(stderr, "parse error at \"%s\"\n", params); @@ -161,6 +162,8 @@ DeviceState *qdev_device_add(const char *cmdline) params += n; if (strcmp(tag, "addr") == 0) continue; + if (strcmp(tag, "id") == 0) + continue; if (-1 == qdev_prop_parse(qdev, tag, value)) { fprintf(stderr, "can't set property \"%s\" to \"%s\" for \"%s\"\n", tag, value, driver); @@ -336,7 +339,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props, static void qdev_print(Monitor *mon, DeviceState *dev, int indent) { BusState *child; - qdev_printf("dev: %s\n", dev->info->name); + qdev_printf("dev: %s, id \"%s\"\n", dev->info->name, dev->id); indent += 2; if (dev->num_gpio_in) { qdev_printf("gpio-in %d\n", dev->num_gpio_in); diff --git a/hw/qdev.h b/hw/qdev.h index 15c1481..c61ef4a 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -17,6 +17,7 @@ typedef struct BusInfo BusInfo; /* This structure should not be accessed directly. We declare it here so that it can be embedded in individual device state structures. */ struct DeviceState { + char id[32]; DeviceInfo *info; BusState *parent_bus; int num_gpio_out; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 10/13] qdev: add user-specified identifier to devices. 2009-07-10 11:26 ` [Qemu-devel] [PATCH 10/13] qdev: add user-specified identifier to devices Gerd Hoffmann @ 2009-07-10 17:31 ` Paul Brook 2009-07-10 19:03 ` Gerd Hoffmann 0 siblings, 1 reply; 18+ messages in thread From: Paul Brook @ 2009-07-10 17:31 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann On Friday 10 July 2009, Gerd Hoffmann wrote: > struct DeviceState { > + char id[32]; Fixed size buffers are almost always wrong. Why 31 characters? Paul ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH 10/13] qdev: add user-specified identifier to devices. 2009-07-10 17:31 ` Paul Brook @ 2009-07-10 19:03 ` Gerd Hoffmann 0 siblings, 0 replies; 18+ messages in thread From: Gerd Hoffmann @ 2009-07-10 19:03 UTC (permalink / raw) To: Paul Brook; +Cc: qemu-devel On 07/10/09 19:31, Paul Brook wrote: > On Friday 10 July 2009, Gerd Hoffmann wrote: >> struct DeviceState { >> + char id[32]; > > Fixed size buffers are almost always wrong. Why 31 characters? 640k is enougth for everybody ;) I'll fix it up and make it dynamic. cheers, Gerd ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2009-07-10 19:05 UTC | newest] Thread overview: 18+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-07-03 10:22 [Qemu-devel] [PATCH 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 01/13] qdev: rework device properties Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 02/13] qdev: factor out driver search to qdev_find_info() Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 03/13] qdev/pci: make pci_create return DeviceState instead of PCIDevice Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 04/13] qdev: add generic qdev_device_add() Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 05/13] qdev: add -device command line option Gerd Hoffmann 2009-07-07 15:38 ` Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 06/13] qdev: add no_user, alias and desc Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 07/13] qdev: es1370 description Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 08/13] qdev: convert all vga Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 09/13] qdev/pci: hook up i440fx Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 10/13] qdev: add user-specified identifier to devices Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 11/13] switch balloon initialization to -device Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 12/13] qdev: add id= support for pci nics Gerd Hoffmann 2009-07-03 10:22 ` [Qemu-devel] [PATCH 13/13] qdev: print device id in "info pci" Gerd Hoffmann -- strict thread matches above, loose matches on Subject: below -- 2009-07-10 11:26 [Qemu-devel] [PATCH v2 0/13] qdev patches: properties, -device switch, id=<tag> & more Gerd Hoffmann 2009-07-10 11:26 ` [Qemu-devel] [PATCH 10/13] qdev: add user-specified identifier to devices Gerd Hoffmann 2009-07-10 17:31 ` Paul Brook 2009-07-10 19:03 ` Gerd Hoffmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).