mirror of
https://github.com/qemu/qemu.git
synced 2024-11-24 11:23:43 +08:00
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 <kraxel@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
f114784f69
commit
ee6847d19b
2
Makefile
2
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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
22
hw/armv7m.c
22
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)
|
||||
|
@ -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);
|
||||
|
@ -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}
|
||||
}
|
||||
};
|
||||
|
@ -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)
|
||||
|
90
hw/escc.c
90
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 */}
|
||||
}
|
||||
};
|
||||
|
||||
|
14
hw/esp.c
14
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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
44
hw/fdc.c
44
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 */}
|
||||
}
|
||||
};
|
||||
|
||||
|
11
hw/i2c.c
11
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;
|
||||
}
|
||||
|
2
hw/i2c.h
2
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);
|
||||
|
@ -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)
|
||||
|
14
hw/iommu.c
14
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 */}
|
||||
}
|
||||
};
|
||||
|
||||
|
39
hw/m48t59.c
39
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)
|
||||
|
@ -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]);
|
||||
|
@ -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]);
|
||||
|
4
hw/pc.c
4
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);
|
||||
}
|
||||
}
|
||||
|
17
hw/pci.c
17
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;
|
||||
|
19
hw/pcnet.c
19
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
|
||||
}
|
||||
|
||||
|
32
hw/qdev-addr.c
Normal file
32
hw/qdev-addr.c
Normal file
@ -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);
|
||||
}
|
2
hw/qdev-addr.h
Normal file
2
hw/qdev-addr.h
Normal file
@ -0,0 +1,2 @@
|
||||
extern PropertyInfo qdev_prop_taddr;
|
||||
void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value);
|
246
hw/qdev-properties.c
Normal file
246
hw/qdev-properties.c
Normal file
@ -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++;
|
||||
}
|
||||
}
|
||||
|
141
hw/qdev.c
141
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) {
|
||||
|
73
hw/qdev.h
73
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
|
||||
|
@ -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 */}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 */}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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 */}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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]);
|
||||
|
36
hw/sun4m.c
36
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 */}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 */}
|
||||
}
|
||||
};
|
||||
|
||||
|
65
hw/tcx.c
65
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)
|
||||
|
12
hw/xilinx.h
12
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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user