From ee6847d19be16c789b8bd4e553b7cd6701ba1245 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 15 Jul 2009 13:43:31 +0200 Subject: [PATCH] qdev: rework device properties. 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 Signed-off-by: Anthony Liguori --- Makefile | 2 +- Makefile.hw | 2 +- hw/arm_sysctl.c | 20 +++- hw/armv7m.c | 22 +++- hw/axis_dev88.c | 2 +- hw/cs4231.c | 2 +- hw/eccmemctl.c | 21 +++- hw/escc.c | 90 ++++++++++------ hw/esp.c | 14 ++- hw/etraxfs.c | 2 +- hw/etraxfs_pic.c | 18 +++- hw/fdc.c | 44 +++++--- hw/i2c.c | 11 +- hw/i2c.h | 2 +- hw/integratorcp.c | 30 ++++-- hw/iommu.c | 14 +-- hw/m48t59.c | 39 +++++-- hw/mips_malta.c | 4 +- hw/musicpal.c | 2 +- hw/pc.c | 4 +- hw/pci.c | 17 ++- hw/pcnet.c | 19 +++- hw/qdev-addr.c | 32 ++++++ hw/qdev-addr.h | 2 + hw/qdev-properties.c | 246 ++++++++++++++++++++++++++++++++++++++++++ hw/qdev.c | 141 ++++-------------------- hw/qdev.h | 73 ++++++++----- hw/slavio_intctl.c | 29 +++-- hw/slavio_misc.c | 6 -- hw/slavio_timer.c | 31 ++++-- hw/smbus_eeprom.c | 10 +- hw/smc91c111.c | 2 +- hw/sparc32_dma.c | 13 ++- hw/stellaris.c | 2 +- hw/sun4m.c | 36 ++++--- 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/tcx.c | 65 ++++++++--- hw/xilinx.h | 12 +-- hw/xilinx_ethlite.c | 29 +++-- hw/xilinx_intc.c | 18 +++- hw/xilinx_timer.c | 32 ++++-- 47 files changed, 921 insertions(+), 391 deletions(-) create mode 100644 hw/qdev-addr.c create mode 100644 hw/qdev-addr.h create mode 100644 hw/qdev-properties.c diff --git a/Makefile b/Makefile index caf85309db..a3ae99fd2f 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/Makefile.hw b/Makefile.hw index f7a9507ea5..571e5184f7 100644 --- a/Makefile.hw +++ b/Makefile.hw @@ -26,7 +26,7 @@ obj-y += m48t59.o escc.o # SCSI layer obj-y += lsi53c895a.o esp.o -obj-y += dma-helpers.o sysbus.o +obj-y += dma-helpers.o sysbus.o qdev-addr.o all: $(HWLIB) # Dummy command so that make thinks it has done something diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c index c9d1e3ff15..bb005c8015 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 297a3e1f0c..2e66d7e934 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 79a4d7106e..f93f43145c 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/cs4231.c b/hw/cs4231.c index 6d45be3ee1..f13815b4e7 100644 --- a/hw/cs4231.c +++ b/hw/cs4231.c @@ -185,7 +185,7 @@ static SysBusDeviceInfo cs4231_info = { .init = cs4231_init1, .qdev.name = "SUNW,CS4231", .qdev.size = sizeof(CSState), - .qdev.props = (DevicePropList[]) { + .qdev.props = (Property[]) { {.name = NULL} } }; diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c index d05962b70c..c5d6449081 100644 --- a/hw/eccmemctl.c +++ b/hw/eccmemctl.c @@ -321,7 +321,6 @@ static void ecc_init1(SysBusDevice *dev) ECCState *s = FROM_SYSBUS(ECCState, dev); sysbus_init_irq(dev, &s->irq); - s->version = qdev_get_prop_int(&dev->qdev, "version", -1); s->regs[0] = s->version; ecc_io_memory = cpu_register_io_memory(ecc_mem_read, ecc_mem_write, s); sysbus_init_mmio(dev, ECC_SIZE, ecc_io_memory); @@ -342,7 +341,7 @@ void ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version) SysBusDevice *s; dev = qdev_create(NULL, "eccmemctl"); - qdev_set_prop_int(dev, "version", version); + qdev_prop_set_uint32(dev, "version", version); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_connect_irq(s, 0, irq); @@ -352,9 +351,25 @@ void ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version) } } +static SysBusDeviceInfo ecc_info = { + .init = ecc_init1, + .qdev.name = "eccmemctl", + .qdev.size = sizeof(ECCState), + .qdev.props = (Property[]) { + { + .name = "version", + .info = &qdev_prop_uint32, + .offset = offsetof(ECCState, version), + .defval = (uint32_t[]) { -1 }, + }, + {/* end of list */} + } +}; + + static void ecc_register_devices(void) { - sysbus_register_dev("eccmemctl", sizeof(ECCState), ecc_init1); + sysbus_register_withprop(&ecc_info); } device_init(ecc_register_devices) diff --git a/hw/escc.c b/hw/escc.c index 93bc4bde39..9abd092ae3 100644 --- a/hw/escc.c +++ b/hw/escc.c @@ -120,6 +120,8 @@ struct SerialState { struct ChannelState chn[2]; int it_shift; int mmio_index; + uint32_t disabled; + uint32_t frequency; }; #define SERIAL_CTRL 0 @@ -732,13 +734,13 @@ int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, SerialState *d; dev = qdev_create(NULL, "escc"); - qdev_set_prop_int(dev, "disabled", 0); - qdev_set_prop_int(dev, "frequency", clock); - qdev_set_prop_int(dev, "it_shift", it_shift); - qdev_set_prop_ptr(dev, "chrB", chrB); - qdev_set_prop_ptr(dev, "chrA", chrA); - qdev_set_prop_int(dev, "chnBtype", ser); - qdev_set_prop_int(dev, "chnAtype", ser); + qdev_prop_set_uint32(dev, "disabled", 0); + qdev_prop_set_uint32(dev, "frequency", clock); + qdev_prop_set_uint32(dev, "it_shift", it_shift); + qdev_prop_set_ptr(dev, "chrB", chrB); + qdev_prop_set_ptr(dev, "chrA", chrA); + qdev_prop_set_uint32(dev, "chnBtype", ser); + qdev_prop_set_uint32(dev, "chnAtype", ser); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_connect_irq(s, 0, irqA); @@ -895,13 +897,13 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq, SysBusDevice *s; dev = qdev_create(NULL, "escc"); - qdev_set_prop_int(dev, "disabled", disabled); - qdev_set_prop_int(dev, "frequency", clock); - qdev_set_prop_int(dev, "it_shift", it_shift); - qdev_set_prop_ptr(dev, "chrB", NULL); - qdev_set_prop_ptr(dev, "chrA", NULL); - qdev_set_prop_int(dev, "chnBtype", mouse); - qdev_set_prop_int(dev, "chnAtype", kbd); + qdev_prop_set_uint32(dev, "disabled", disabled); + qdev_prop_set_uint32(dev, "frequency", clock); + qdev_prop_set_uint32(dev, "it_shift", it_shift); + qdev_prop_set_ptr(dev, "chrB", NULL); + qdev_prop_set_ptr(dev, "chrA", NULL); + qdev_prop_set_uint32(dev, "chnBtype", mouse); + qdev_prop_set_uint32(dev, "chnAtype", kbd); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_connect_irq(s, 0, irq); @@ -914,19 +916,13 @@ static void escc_init1(SysBusDevice *dev) SerialState *s = FROM_SYSBUS(SerialState, dev); int io; unsigned int i; - uint32_t clock, disabled; - s->it_shift = qdev_get_prop_int(&dev->qdev, "it_shift", 0); - clock = qdev_get_prop_int(&dev->qdev, "frequency", 0); - s->chn[0].chr = qdev_get_prop_ptr(&dev->qdev, "chrB"); - s->chn[1].chr = qdev_get_prop_ptr(&dev->qdev, "chrA"); - disabled = qdev_get_prop_int(&dev->qdev, "disabled", 0); - s->chn[0].disabled = disabled; - s->chn[1].disabled = disabled; + s->chn[0].disabled = s->disabled; + s->chn[1].disabled = s->disabled; for (i = 0; i < 2; i++) { sysbus_init_irq(dev, &s->chn[i].irq); s->chn[i].chn = 1 - i; - s->chn[i].clock = clock / 2; + s->chn[i].clock = s->frequency / 2; if (s->chn[i].chr) { qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive, serial_receive1, serial_event, &s->chn[i]); @@ -934,8 +930,6 @@ static void escc_init1(SysBusDevice *dev) } s->chn[0].otherchn = &s->chn[1]; s->chn[1].otherchn = &s->chn[0]; - s->chn[0].type = qdev_get_prop_int(&dev->qdev, "chnBtype", 0); - s->chn[1].type = qdev_get_prop_int(&dev->qdev, "chnAtype", 0); io = cpu_register_io_memory(escc_mem_read, escc_mem_write, s); sysbus_init_mmio(dev, ESCC_SIZE << s->it_shift, io); @@ -957,15 +951,43 @@ static SysBusDeviceInfo escc_info = { .init = escc_init1, .qdev.name = "escc", .qdev.size = sizeof(SerialState), - .qdev.props = (DevicePropList[]) { - {.name = "frequency", .type = PROP_TYPE_INT}, - {.name = "it_shift", .type = PROP_TYPE_INT}, - {.name = "disabled", .type = PROP_TYPE_INT}, - {.name = "chrB", .type = PROP_TYPE_PTR}, - {.name = "chrA", .type = PROP_TYPE_PTR}, - {.name = "chnBtype", .type = PROP_TYPE_INT}, - {.name = "chnAtype", .type = PROP_TYPE_INT}, - {.name = NULL} + .qdev.props = (Property[]) { + { + .name = "frequency", + .info = &qdev_prop_uint32, + .offset = offsetof(SerialState, frequency), + }, + { + .name = "it_shift", + .info = &qdev_prop_uint32, + .offset = offsetof(SerialState, it_shift), + }, + { + .name = "disabled", + .info = &qdev_prop_uint32, + .offset = offsetof(SerialState, disabled), + }, + { + .name = "chrB", + .info = &qdev_prop_ptr, + .offset = offsetof(SerialState, chn[1].chr), + }, + { + .name = "chrA", + .info = &qdev_prop_ptr, + .offset = offsetof(SerialState, chn[0].chr), + }, + { + .name = "chnBtype", + .info = &qdev_prop_uint32, + .offset = offsetof(SerialState, chn[1].type), + }, + { + .name = "chnAtype", + .info = &qdev_prop_uint32, + .offset = offsetof(SerialState, chn[0].type), + }, + {/* end of list */} } }; diff --git a/hw/esp.c b/hw/esp.c index 88d42a14fa..9eacccbf8d 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 94cd6bc81d..c2eca5275e 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 1c67427957..e6272189bb 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/fdc.c b/hw/fdc.c index 3959b112ef..fa154a30cb 100644 --- a/hw/fdc.c +++ b/hw/fdc.c @@ -511,6 +511,8 @@ struct fdctrl_t { /* Floppy drives */ fdrive_t drives[MAX_FD]; int reset_sensei; + uint32_t strict_io; + uint32_t mem_mapped; }; static uint32_t fdctrl_read (void *opaque, uint32_t reg) @@ -1898,9 +1900,9 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped, fdctrl_t *fdctrl; dev = qdev_create(NULL, "fdc"); - qdev_set_prop_int(dev, "strict_io", 0); - qdev_set_prop_int(dev, "mem_mapped", mem_mapped); - qdev_set_prop_int(dev, "sun4m", 0); + qdev_prop_set_uint32(dev, "strict_io", 0); + qdev_prop_set_uint32(dev, "mem_mapped", mem_mapped); + qdev_prop_set_uint32(dev, "sun4m", 0); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_connect_irq(s, 0, irq); @@ -1931,9 +1933,9 @@ fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base, fdctrl_t *fdctrl; dev = qdev_create(NULL, "fdc"); - qdev_set_prop_int(dev, "strict_io", 1); - qdev_set_prop_int(dev, "mem_mapped", 1); - qdev_set_prop_int(dev, "sun4m", 1); + qdev_prop_set_uint32(dev, "strict_io", 1); + qdev_prop_set_uint32(dev, "mem_mapped", 1); + qdev_prop_set_uint32(dev, "sun4m", 1); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_connect_irq(s, 0, irq); @@ -1953,7 +1955,7 @@ static void fdc_init1(SysBusDevice *dev) sysbus_init_irq(dev, &s->irq); qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1); - if (qdev_get_prop_int(&dev->qdev, "strict_io", 0)) { + if (s->strict_io) { io = cpu_register_io_memory(fdctrl_mem_read_strict, fdctrl_mem_write_strict, s); } else { @@ -1967,12 +1969,28 @@ static SysBusDeviceInfo fdc_info = { .init = fdc_init1, .qdev.name = "fdc", .qdev.size = sizeof(fdctrl_t), - .qdev.props = (DevicePropList[]) { - {.name = "io_base", .type = PROP_TYPE_INT}, - {.name = "strict_io", .type = PROP_TYPE_INT}, - {.name = "mem_mapped", .type = PROP_TYPE_INT}, - {.name = "sun4m", .type = PROP_TYPE_INT}, - {.name = NULL} + .qdev.props = (Property[]) { + { + .name = "io_base", + .info = &qdev_prop_uint32, + .offset = offsetof(fdctrl_t, io_base), + }, + { + .name = "strict_io", + .info = &qdev_prop_uint32, + .offset = offsetof(fdctrl_t, strict_io), + }, + { + .name = "mem_mapped", + .info = &qdev_prop_uint32, + .offset = offsetof(fdctrl_t, mem_mapped), + }, + { + .name = "sun4m", + .info = &qdev_prop_uint32, + .offset = offsetof(fdctrl_t, sun4m), + }, + {/* end of properties */} } }; diff --git a/hw/i2c.c b/hw/i2c.c index 98aa7fcd24..42a5d7a6b8 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 c4df39988c..479ff4b9f9 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 50eae0c340..ddc8d8556f 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/iommu.c b/hw/iommu.c index f12b79756b..abf517f1dc 100644 --- a/hw/iommu.c +++ b/hw/iommu.c @@ -373,7 +373,7 @@ void *iommu_init(target_phys_addr_t addr, uint32_t version, qemu_irq irq) IOMMUState *d; dev = qdev_create(NULL, "iommu"); - qdev_set_prop_int(dev, "version", version); + qdev_prop_set_uint32(dev, "version", version); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_connect_irq(s, 0, irq); @@ -391,8 +391,6 @@ static void iommu_init1(SysBusDevice *dev) sysbus_init_irq(dev, &s->irq); - s->version = qdev_get_prop_int(&dev->qdev, "version", 0); - io = cpu_register_io_memory(iommu_mem_read, iommu_mem_write, s); sysbus_init_mmio(dev, IOMMU_NREGS * sizeof(uint32_t), io); @@ -405,9 +403,13 @@ static SysBusDeviceInfo iommu_info = { .init = iommu_init1, .qdev.name = "iommu", .qdev.size = sizeof(IOMMUState), - .qdev.props = (DevicePropList[]) { - {.name = "version", .type = PROP_TYPE_INT}, - {.name = NULL} + .qdev.props = (Property[]) { + { + .name = "version", + .info = &qdev_prop_uint32, + .offset = offsetof(IOMMUState, version), + }, + {/* end of property list */} } }; diff --git a/hw/m48t59.c b/hw/m48t59.c index 798d292853..7e53dceb37 100644 --- a/hw/m48t59.c +++ b/hw/m48t59.c @@ -43,11 +43,11 @@ struct m48t59_t { SysBusDevice busdev; /* Model parameters */ - int type; // 2 = m48t02, 8 = m48t08, 59 = m48t59 + uint32_t type; // 2 = m48t02, 8 = m48t08, 59 = m48t59 /* Hardware parameters */ qemu_irq IRQ; uint32_t io_base; - uint16_t size; + uint32_t size; /* RTC management */ time_t time_offset; time_t stop_time; @@ -623,9 +623,9 @@ m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base, m48t59_t *d; dev = qdev_create(NULL, "m48t59"); - qdev_set_prop_int(dev, "type", type); - qdev_set_prop_int(dev, "size", size); - qdev_set_prop_int(dev, "io_base", io_base); + qdev_prop_set_uint32(dev, "type", type); + qdev_prop_set_uint32(dev, "size", size); + qdev_prop_set_uint32(dev, "io_base", io_base); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_connect_irq(s, 0, IRQ); @@ -647,11 +647,8 @@ static void m48t59_init1(SysBusDevice *dev) m48t59_t *s = FROM_SYSBUS(m48t59_t, dev); int mem_index; - s->size = qdev_get_prop_int(&dev->qdev, "size", -1); s->buffer = qemu_mallocz(s->size); sysbus_init_irq(dev, &s->IRQ); - s->io_base = qdev_get_prop_int(&dev->qdev, "io_base", 0); - s->type = qdev_get_prop_int(&dev->qdev, "type", -1); mem_index = cpu_register_io_memory(nvram_read, nvram_write, s); sysbus_init_mmio(dev, s->size, mem_index); @@ -666,9 +663,33 @@ static void m48t59_init1(SysBusDevice *dev) register_savevm("m48t59", -1, 1, m48t59_save, m48t59_load, s); } +static SysBusDeviceInfo m48t59_info = { + .init = m48t59_init1, + .qdev.name = "m48t59", + .qdev.size = sizeof(m48t59_t), + .qdev.props = (Property[]) { + { + .name = "size", + .info = &qdev_prop_uint32, + .offset = offsetof(m48t59_t, size), + .defval = (uint32_t[]) { -1 }, + },{ + .name = "type", + .info = &qdev_prop_uint32, + .offset = offsetof(m48t59_t, type), + .defval = (uint32_t[]) { -1 }, + },{ + .name = "io_base", + .info = &qdev_prop_hex32, + .offset = offsetof(m48t59_t, io_base), + }, + {/* end of list */} + } +}; + static void m48t59_register_devices(void) { - sysbus_register_dev("m48t59", sizeof(m48t59_t), m48t59_init1); + sysbus_register_withprop(&m48t59_info); } device_init(m48t59_register_devices) diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 853ec2b8dc..7728e58c5e 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 10be69be82..e6367919fc 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 b47c95d72a..7bb67ea9e7 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1402,8 +1402,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 3182116563..b3856e72ab 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -59,6 +59,15 @@ static struct BusInfo pci_bus_info = { .name = "PCI", .size = sizeof(PCIBus), .print_dev = 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); @@ -770,7 +779,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; } @@ -813,7 +822,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; @@ -891,7 +900,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); @@ -918,7 +927,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 4519780cf8..22ab6beaf3 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-addr.c b/hw/qdev-addr.c new file mode 100644 index 0000000000..305c2d37b0 --- /dev/null +++ b/hw/qdev-addr.c @@ -0,0 +1,32 @@ +#include "qdev.h" +#include "qdev-addr.h" +#include "targphys.h" + +/* --- target physical address --- */ + +static int parse_taddr(DeviceState *dev, Property *prop, const char *str) +{ + target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop); + + *ptr = strtoull(str, NULL, 16); + return 0; +} + +static int print_taddr(DeviceState *dev, Property *prop, char *dest, size_t len) +{ + target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop); + return snprintf(dest, len, "0x" TARGET_FMT_plx, *ptr); +} + +PropertyInfo qdev_prop_taddr = { + .name = "taddr", + .type = PROP_TYPE_TADDR, + .size = sizeof(target_phys_addr_t), + .parse = parse_taddr, + .print = print_taddr, +}; + +void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value) +{ + qdev_prop_set(dev, name, &value, PROP_TYPE_TADDR); +} diff --git a/hw/qdev-addr.h b/hw/qdev-addr.h new file mode 100644 index 0000000000..f02bd7af18 --- /dev/null +++ b/hw/qdev-addr.h @@ -0,0 +1,2 @@ +extern PropertyInfo qdev_prop_taddr; +void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value); diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c new file mode 100644 index 0000000000..8b0d0ffce7 --- /dev/null +++ b/hw/qdev-properties.c @@ -0,0 +1,246 @@ +#include "qdev.h" + +void *qdev_get_prop_ptr(DeviceState *dev, Property *prop) +{ + void *ptr = dev; + ptr += prop->offset; + return ptr; +} + +/* --- 16bit integer --- */ + +static int parse_uint16(DeviceState *dev, Property *prop, const char *str) +{ + uint16_t *ptr = qdev_get_prop_ptr(dev, prop); + const char *fmt; + + /* accept both hex and decimal */ + fmt = strncasecmp(str, "0x",2) == 0 ? "%" PRIx16 : "%" PRIu16; + if (sscanf(str, fmt, ptr) != 1) + return -1; + return 0; +} + +static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len) +{ + uint16_t *ptr = qdev_get_prop_ptr(dev, prop); + return snprintf(dest, len, "%" PRIu16, *ptr); +} + +PropertyInfo qdev_prop_uint16 = { + .name = "uint16", + .type = PROP_TYPE_UINT16, + .size = sizeof(uint16_t), + .parse = parse_uint16, + .print = print_uint16, +}; + +/* --- 32bit integer --- */ + +static int parse_uint32(DeviceState *dev, Property *prop, const char *str) +{ + uint32_t *ptr = qdev_get_prop_ptr(dev, prop); + const char *fmt; + + /* accept both hex and decimal */ + fmt = strncasecmp(str, "0x",2) == 0 ? "%" PRIx32 : "%" PRIu32; + if (sscanf(str, fmt, ptr) != 1) + return -1; + return 0; +} + +static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len) +{ + uint32_t *ptr = qdev_get_prop_ptr(dev, prop); + return snprintf(dest, len, "%" PRIu32, *ptr); +} + +PropertyInfo qdev_prop_uint32 = { + .name = "uint32", + .type = PROP_TYPE_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 = qdev_get_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 = qdev_get_prop_ptr(dev, prop); + return snprintf(dest, len, "0x%" PRIx32, *ptr); +} + +PropertyInfo qdev_prop_hex32 = { + .name = "hex32", + .type = PROP_TYPE_UINT32, + .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 = qdev_get_prop_ptr(dev, prop); + return snprintf(dest, len, "<%p>", *ptr); +} + +PropertyInfo qdev_prop_ptr = { + .name = "ptr", + .type = PROP_TYPE_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 = qdev_get_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 = qdev_get_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_macaddr = { + .name = "mac-addr", + .type = PROP_TYPE_MACADDR, + .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); +} + +void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type) +{ + Property *prop; + void *dst; + + prop = qdev_prop_find(dev, name); + if (!prop) { + fprintf(stderr, "%s: property \"%s.%s\" not found\n", + __FUNCTION__, dev->info->name, name); + abort(); + } + if (prop->info->type != type) { + fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n", + __FUNCTION__, dev->info->name, name); + abort(); + } + dst = qdev_get_prop_ptr(dev, prop); + memcpy(dst, src, prop->info->size); +} + +void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value) +{ + qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16); +} + +void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value) +{ + qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32); +} + +void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) +{ + qdev_prop_set(dev, name, &value, PROP_TYPE_PTR); +} + +void qdev_prop_set_defaults(DeviceState *dev, Property *props) +{ + char *dst; + + if (!props) + return; + while (props->name) { + if (props->defval) { + dst = qdev_get_prop_ptr(dev, props); + memcpy(dst, props->defval, props->info->size); + } + props++; + } +} + diff --git a/hw/qdev.c b/hw/qdev.c index 1bccf2ff27..64461e7eb2 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -30,16 +30,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); @@ -326,9 +226,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; @@ -338,24 +253,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) dev->parent_bus->info->print_dev(mon, dev, indent); LIST_FOREACH(child, &dev->child_bus, sibling) { diff --git a/hw/qdev.h b/hw/qdev.h index b18dbf91d6..9ecc9ec156 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 DeviceProperty DeviceProperty; +typedef struct PropertyInfo PropertyInfo; + +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; @@ -32,6 +33,7 @@ struct BusInfo { const char *name; size_t size; bus_dev_printfn print_dev; + Property *props; }; struct BusState { @@ -42,18 +44,36 @@ struct BusState { LIST_ENTRY(BusState) sibling; }; +struct Property { + const char *name; + PropertyInfo *info; + int offset; + void *defval; +}; + +enum PropertyType { + PROP_TYPE_UNSPEC = 0, + PROP_TYPE_UINT16, + PROP_TYPE_UINT32, + PROP_TYPE_TADDR, + PROP_TYPE_MACADDR, + PROP_TYPE_PTR, +}; + +struct PropertyInfo { + const char *name; + size_t size; + enum PropertyType type; + 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 +81,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 +88,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 +108,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__ @@ -124,4 +129,22 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name); void do_info_qtree(Monitor *mon); +/*** qdev-properties.c ***/ + +extern PropertyInfo qdev_prop_uint16; +extern PropertyInfo qdev_prop_uint32; +extern PropertyInfo qdev_prop_hex32; +extern PropertyInfo qdev_prop_ptr; +extern PropertyInfo qdev_prop_macaddr; + +/* Set properties between creation and init. */ +void *qdev_get_prop_ptr(DeviceState *dev, Property *prop); +int qdev_prop_parse(DeviceState *dev, const char *name, const char *value); +void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type); +void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value); +void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value); +/* FIXME: Remove opaque pointer properties. */ +void 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/slavio_intctl.c b/hw/slavio_intctl.c index 235e8c3745..188511e84f 100644 --- a/hw/slavio_intctl.c +++ b/hw/slavio_intctl.c @@ -69,6 +69,7 @@ typedef struct SLAVIO_INTCTLState { qemu_irq cpu_irqs[MAX_CPUS][MAX_PILS]; const uint32_t *intbit_to_level; uint32_t cputimer_lbit, cputimer_mbit; + uint32_t cputimer_bit; uint32_t pil_out[MAX_CPUS]; SLAVIO_CPUINTCTLState slaves[MAX_CPUS]; } SLAVIO_INTCTLState; @@ -388,17 +389,15 @@ static void slavio_intctl_reset(void *opaque) static void slavio_intctl_init1(SysBusDevice *dev) { SLAVIO_INTCTLState *s = FROM_SYSBUS(SLAVIO_INTCTLState, dev); - int io_memory, cputimer; + int io_memory; unsigned int i, j; qdev_init_gpio_in(&dev->qdev, slavio_set_irq_all, 32 + MAX_CPUS); io_memory = cpu_register_io_memory(slavio_intctlm_mem_read, slavio_intctlm_mem_write, s); sysbus_init_mmio(dev, INTCTLM_SIZE, io_memory); - s->intbit_to_level = qdev_get_prop_ptr(&dev->qdev, "intbit_to_level"); - cputimer = qdev_get_prop_int(&dev->qdev, "cputimer_bit", -1); - s->cputimer_mbit = 1 << cputimer; - s->cputimer_lbit = 1 << s->intbit_to_level[cputimer]; + s->cputimer_mbit = 1 << s->cputimer_bit; + s->cputimer_lbit = 1 << s->intbit_to_level[s->cputimer_bit]; for (i = 0; i < MAX_CPUS; i++) { for (j = 0; j < MAX_PILS; j++) { @@ -427,8 +426,8 @@ DeviceState *slavio_intctl_init(target_phys_addr_t addr, unsigned int i, j; dev = qdev_create(NULL, "slavio_intctl"); - qdev_set_prop_ptr(dev, "intbit_to_level", (void *)intbit_to_level); - qdev_set_prop_int(dev, "cputimer_bit", cputimer); + qdev_prop_set_ptr(dev, "intbit_to_level", (void *)intbit_to_level); + qdev_prop_set_uint32(dev, "cputimer_bit", cputimer); qdev_init(dev); s = sysbus_from_qdev(dev); @@ -450,10 +449,18 @@ static SysBusDeviceInfo slavio_intctl_info = { .init = slavio_intctl_init1, .qdev.name = "slavio_intctl", .qdev.size = sizeof(SLAVIO_INTCTLState), - .qdev.props = (DevicePropList[]) { - {.name = "intbit_to_level", .type = PROP_TYPE_PTR}, - {.name = "cputimer_bit", .type = PROP_TYPE_INT}, - {.name = NULL} + .qdev.props = (Property[]) { + { + .name = "intbit_to_level", + .info = &qdev_prop_ptr, + .offset = offsetof(SLAVIO_INTCTLState, intbit_to_level), + }, + { + .name = "cputimer_bit", + .info = &qdev_prop_uint32, + .offset = offsetof(SLAVIO_INTCTLState, cputimer_bit), + }, + {/* end of property list */} } }; diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c index 3d246eea22..23012a36d1 100644 --- a/hw/slavio_misc.c +++ b/hw/slavio_misc.c @@ -564,18 +564,12 @@ static SysBusDeviceInfo slavio_misc_info = { .init = slavio_misc_init1, .qdev.name = "slavio_misc", .qdev.size = sizeof(MiscState), - .qdev.props = (DevicePropList[]) { - {.name = NULL} - } }; static SysBusDeviceInfo apc_info = { .init = apc_init1, .qdev.name = "apc", .qdev.size = sizeof(MiscState), - .qdev.props = (DevicePropList[]) { - {.name = NULL} - } }; static void slavio_misc_register_devices(void) diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c index df9afb0eec..21924f8716 100644 --- a/hw/slavio_timer.c +++ b/hw/slavio_timer.c @@ -374,9 +374,9 @@ static SLAVIO_TIMERState *slavio_timer_init(target_phys_addr_t addr, SLAVIO_TIMERState *d; dev = qdev_create(NULL, "slavio_timer"); - qdev_set_prop_int(dev, "slave_index", slave_index); - qdev_set_prop_int(dev, "num_slaves", num_slaves); - qdev_set_prop_ptr(dev, "master", master); + qdev_prop_set_uint32(dev, "slave_index", slave_index); + qdev_prop_set_uint32(dev, "num_slaves", num_slaves); + qdev_prop_set_ptr(dev, "master", master); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_connect_irq(s, 0, irq); @@ -394,9 +394,6 @@ static void slavio_timer_init1(SysBusDevice *dev) QEMUBH *bh; sysbus_init_irq(dev, &s->irq); - s->num_slaves = qdev_get_prop_int(&dev->qdev, "num_slaves", 0); - s->slave_index = qdev_get_prop_int(&dev->qdev, "slave_index", 0); - s->master = qdev_get_prop_ptr(&dev->qdev, "master"); if (!s->master || s->slave_index < s->master->num_slaves) { bh = qemu_bh_new(slavio_timer_irq, s); @@ -438,11 +435,23 @@ static SysBusDeviceInfo slavio_timer_info = { .init = slavio_timer_init1, .qdev.name = "slavio_timer", .qdev.size = sizeof(SLAVIO_TIMERState), - .qdev.props = (DevicePropList[]) { - {.name = "num_slaves", .type = PROP_TYPE_INT}, - {.name = "slave_index", .type = PROP_TYPE_INT}, - {.name = "master", .type = PROP_TYPE_PTR}, - {.name = NULL} + .qdev.props = (Property[]) { + { + .name = "num_slaves", + .info = &qdev_prop_uint32, + .offset = offsetof(SLAVIO_TIMERState, num_slaves), + }, + { + .name = "slave_index", + .info = &qdev_prop_uint32, + .offset = offsetof(SLAVIO_TIMERState, slave_index), + }, + { + .name = "master", + .info = &qdev_prop_ptr, + .offset = offsetof(SLAVIO_TIMERState, master), + }, + {/* end of property list */} } }; diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c index 05a70d9b1c..c071fb1e13 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 cf8d864e5b..5f6956a663 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/sparc32_dma.c b/hw/sparc32_dma.c index a0678b5dbc..7633905af8 100644 --- a/hw/sparc32_dma.c +++ b/hw/sparc32_dma.c @@ -252,7 +252,7 @@ void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq parent_irq, DMAState *d; dev = qdev_create(NULL, "sparc32_dma"); - qdev_set_prop_ptr(dev, "iommu_opaque", iommu); + qdev_prop_set_ptr(dev, "iommu_opaque", iommu); qdev_init(dev); s = sysbus_from_qdev(dev); sysbus_connect_irq(s, 0, parent_irq); @@ -271,7 +271,6 @@ static void sparc32_dma_init1(SysBusDevice *dev) int dma_io_memory; sysbus_init_irq(dev, &s->irq); - s->iommu = qdev_get_prop_ptr(&dev->qdev, "iommu_opaque"); dma_io_memory = cpu_register_io_memory(dma_mem_read, dma_mem_write, s); sysbus_init_mmio(dev, DMA_SIZE, dma_io_memory); @@ -286,9 +285,13 @@ static SysBusDeviceInfo sparc32_dma_info = { .init = sparc32_dma_init1, .qdev.name = "sparc32_dma", .qdev.size = sizeof(DMAState), - .qdev.props = (DevicePropList[]) { - {.name = "iommu_opaque", .type = PROP_TYPE_PTR}, - {.name = NULL} + .qdev.props = (Property[]) { + { + .name = "iommu_opaque", + .info = &qdev_prop_ptr, + .offset = offsetof(DMAState, iommu), + }, + {/* end of property list */} } }; diff --git a/hw/stellaris.c b/hw/stellaris.c index 5f44bff5d0..d9434ca290 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 220eaae3eb..4954ba37da 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); @@ -410,9 +409,6 @@ static SysBusDeviceInfo idreg_info = { .init = idreg_init1, .qdev.name = "macio_idreg", .qdev.size = sizeof(SysBusDevice), - .qdev.props = (DevicePropList[]) { - {.name = NULL} - } }; static void idreg_register_devices(void) @@ -468,8 +464,8 @@ static SysBusDeviceInfo prom_info = { .init = prom_init1, .qdev.name = "openprom", .qdev.size = sizeof(SysBusDevice), - .qdev.props = (DevicePropList[]) { - {.name = NULL} + .qdev.props = (Property[]) { + {/* end of property list */} } }; @@ -480,12 +476,19 @@ static void prom_register_devices(void) device_init(prom_register_devices); +typedef struct RamDevice +{ + SysBusDevice busdev; + uint32_t size; +} RamDevice; + /* System RAM */ static void ram_init1(SysBusDevice *dev) { ram_addr_t RAM_size, ram_offset; + RamDevice *d = FROM_SYSBUS(RamDevice, dev); - RAM_size = qdev_get_prop_int(&dev->qdev, "size", 0); + RAM_size = d->size; ram_offset = qemu_ram_alloc(RAM_size); sysbus_init_mmio(dev, RAM_size, ram_offset); @@ -496,6 +499,7 @@ static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size, { DeviceState *dev; SysBusDevice *s; + RamDevice *d; /* allocate RAM */ if ((uint64_t)RAM_size > max_mem) { @@ -506,20 +510,26 @@ static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size, exit(1); } dev = qdev_create(NULL, "memory"); - qdev_set_prop_int(dev, "size", RAM_size); qdev_init(dev); s = sysbus_from_qdev(dev); + d = FROM_SYSBUS(RamDevice, s); + d->size = RAM_size; + sysbus_mmio_map(s, 0, addr); } static SysBusDeviceInfo ram_info = { .init = ram_init1, .qdev.name = "memory", - .qdev.size = sizeof(SysBusDevice), - .qdev.props = (DevicePropList[]) { - {.name = "size", .type = PROP_TYPE_INT}, - {.name = NULL} + .qdev.size = sizeof(RamDevice), + .qdev.props = (Property[]) { + { + .name = "size", + .info = &qdev_prop_uint32, + .offset = offsetof(RamDevice, size), + }, + {/* end of property list */} } }; diff --git a/hw/syborg.c b/hw/syborg.c index 5ca9977b24..d8d38d48e4 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 42c62744ce..2929ffd0b5 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 569c7f61cf..a372ec1dd5 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 84a099ed05..ffc85a56a0 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 e0a892d003..edd1f2229e 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 f430508018..f69342154a 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 4f5e3a178a..cf96c5fffe 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/tcx.c b/hw/tcx.c index 76acae809d..c5925240b5 100644 --- a/hw/tcx.c +++ b/hw/tcx.c @@ -26,6 +26,7 @@ #include "console.h" #include "pixel_ops.h" #include "sysbus.h" +#include "qdev-addr.h" #define MAXX 1024 #define MAXY 768 @@ -41,6 +42,7 @@ typedef struct TCXState { uint8_t *vram; uint32_t *vram24, *cplane; ram_addr_t vram_offset, vram24_offset, cplane_offset; + uint32_t vram_size; uint16_t width, height, depth; uint8_t r[256], g[256], b[256]; uint32_t palette[256]; @@ -520,11 +522,11 @@ void tcx_init(target_phys_addr_t addr, int vram_size, int width, int height, SysBusDevice *s; dev = qdev_create(NULL, "SUNW,tcx"); - qdev_set_prop_int(dev, "addr", addr); - qdev_set_prop_int(dev, "vram_size", vram_size); - qdev_set_prop_int(dev, "width", width); - qdev_set_prop_int(dev, "height", height); - qdev_set_prop_int(dev, "depth", depth); + qdev_prop_set_taddr(dev, "addr", addr); + qdev_prop_set_uint32(dev, "vram_size", vram_size); + qdev_prop_set_uint16(dev, "width", width); + qdev_prop_set_uint16(dev, "height", height); + qdev_prop_set_uint16(dev, "depth", depth); qdev_init(dev); s = sysbus_from_qdev(dev); /* 8-bit plane */ @@ -551,22 +553,16 @@ static void tcx_init1(SysBusDevice *dev) TCXState *s = FROM_SYSBUS(TCXState, dev); int io_memory, dummy_memory; ram_addr_t vram_offset; - int size, vram_size; + int size; uint8_t *vram_base; - vram_size = qdev_get_prop_int(&dev->qdev, "vram_size", -1); - - vram_offset = qemu_ram_alloc(vram_size * (1 + 4 + 4)); + vram_offset = qemu_ram_alloc(s->vram_size * (1 + 4 + 4)); vram_base = qemu_get_ram_ptr(vram_offset); - s->addr = qdev_get_prop_int(&dev->qdev, "addr", -1); s->vram_offset = vram_offset; - s->width = qdev_get_prop_int(&dev->qdev, "width", -1); - s->height = qdev_get_prop_int(&dev->qdev, "height", -1); - s->depth = qdev_get_prop_int(&dev->qdev, "depth", -1); /* 8-bit plane */ s->vram = vram_base; - size = vram_size; + size = s->vram_size; sysbus_init_mmio(dev, size, s->vram_offset); vram_offset += size; vram_base += size; @@ -584,7 +580,7 @@ static void tcx_init1(SysBusDevice *dev) if (s->depth == 24) { /* 24-bit plane */ - size = vram_size * 4; + size = s->vram_size * 4; s->vram24 = (uint32_t *)vram_base; s->vram24_offset = vram_offset; sysbus_init_mmio(dev, size, vram_offset); @@ -592,7 +588,7 @@ static void tcx_init1(SysBusDevice *dev) vram_base += size; /* Control plane */ - size = vram_size * 4; + size = s->vram_size * 4; s->cplane = (uint32_t *)vram_base; s->cplane_offset = vram_offset; sysbus_init_mmio(dev, size, vram_offset); @@ -678,9 +674,44 @@ static void tcx24_screen_dump(void *opaque, const char *filename) return; } +static SysBusDeviceInfo tcx_info = { + .init = tcx_init1, + .qdev.name = "SUNW,tcx", + .qdev.size = sizeof(TCXState), + .qdev.props = (Property[]) { + { + .name = "addr", + .info = &qdev_prop_taddr, + .offset = offsetof(TCXState, addr), + .defval = (target_phys_addr_t[]) { -1 }, + },{ + .name = "vram_size", + .info = &qdev_prop_hex32, + .offset = offsetof(TCXState, vram_size), + .defval = (uint32_t[]) { -1 }, + },{ + .name = "width", + .info = &qdev_prop_uint16, + .offset = offsetof(TCXState, width), + .defval = (uint16_t[]) { -1 }, + },{ + .name = "height", + .info = &qdev_prop_uint16, + .offset = offsetof(TCXState, height), + .defval = (uint16_t[]) { -1 }, + },{ + .name = "depth", + .info = &qdev_prop_uint16, + .offset = offsetof(TCXState, depth), + .defval = (uint16_t[]) { -1 }, + }, + {/* end of list */} + } +}; + static void tcx_register_devices(void) { - sysbus_register_dev("SUNW,tcx", sizeof(TCXState), tcx_init1); + sysbus_register_withprop(&tcx_info); } device_init(tcx_register_devices) diff --git a/hw/xilinx.h b/hw/xilinx.h index 9707a0e0b5..070679c24f 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 f4b40c7b73..b3fd25bb47 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 0540f52d03..3f08bf81b6 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 a64ad2d80b..efb6a04fb5 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)