ESP and Lance DMA controllers are not identical. Separate the controllers on VMState and instantiation level.
NB: This change breaks savevm and migration compatibility. Signed-off-by: Blue Swirl <blauwir...@gmail.com> --- Perhaps the compat properties could be used to retain compatibility. But if nobody cares (as I suspect), let's just break it. Further changes can either use s->is_ledma or make the state structures separate. hw/sparc32_dma.c | 65 ++++++++++++++++++++++++++++++++++++++++++++--------- hw/sun4m.c | 16 ++++++------ 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c index 0904188..f0c5d88 100644 --- a/hw/sparc32_dma.c +++ b/hw/sparc32_dma.c @@ -65,6 +65,7 @@ struct DMAState { qemu_irq irq; void *iommu; qemu_irq gpio[2]; + int is_ledma; }; enum { @@ -239,18 +240,29 @@ static void dma_reset(DeviceState *d) s->dmaregs[0] = DMA_VER; } -static const VMStateDescription vmstate_dma = { - .name ="sparc32_dma", - .version_id = 2, - .minimum_version_id = 2, - .minimum_version_id_old = 2, +static const VMStateDescription vmstate_ledma = { + .name ="ledma", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, .fields = (VMStateField []) { VMSTATE_UINT32_ARRAY(dmaregs, DMAState, DMA_REGS), VMSTATE_END_OF_LIST() } }; -static int sparc32_dma_init1(SysBusDevice *dev) +static const VMStateDescription vmstate_espdma = { + .name ="espdma", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT32_ARRAY(dmaregs, DMAState, DMA_REGS), + VMSTATE_END_OF_LIST() + } +}; + +static int sparc32_dma_common_init(SysBusDevice *dev) { DMAState *s = FROM_SYSBUS(DMAState, dev); int dma_io_memory; @@ -266,11 +278,41 @@ static int sparc32_dma_init1(SysBusDevice *dev) return 0; } -static SysBusDeviceInfo sparc32_dma_info = { - .init = sparc32_dma_init1, - .qdev.name = "sparc32_dma", +static int ledma_init(SysBusDevice *dev) +{ + DMAState *s = FROM_SYSBUS(DMAState, dev); + + s->is_ledma = 1; + + return sparc32_dma_common_init(dev); +} + +static int espdma_init(SysBusDevice *dev) +{ + DMAState *s = FROM_SYSBUS(DMAState, dev); + + s->is_ledma = 0; + + return sparc32_dma_common_init(dev); +} + +static SysBusDeviceInfo ledma_info = { + .init = ledma_init, + .qdev.name = "ledma", + .qdev.size = sizeof(DMAState), + .qdev.vmsd = &vmstate_ledma, + .qdev.reset = dma_reset, + .qdev.props = (Property[]) { + DEFINE_PROP_PTR("iommu_opaque", DMAState, iommu), + DEFINE_PROP_END_OF_LIST(), + } +}; + +static SysBusDeviceInfo espdma_info = { + .init = espdma_init, + .qdev.name = "espdma", .qdev.size = sizeof(DMAState), - .qdev.vmsd = &vmstate_dma, + .qdev.vmsd = &vmstate_espdma, .qdev.reset = dma_reset, .qdev.props = (Property[]) { DEFINE_PROP_PTR("iommu_opaque", DMAState, iommu), @@ -280,7 +322,8 @@ static SysBusDeviceInfo sparc32_dma_info = { static void sparc32_dma_register_devices(void) { - sysbus_register_withprop(&sparc32_dma_info); + sysbus_register_withprop(&ledma_info); + sysbus_register_withprop(&espdma_info); } device_init(sparc32_dma_register_devices) diff --git a/hw/sun4m.c b/hw/sun4m.c index 4795b3f..302a7b7 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -378,12 +378,12 @@ static void *iommu_init(target_phys_addr_t addr, uint32_t version, qemu_irq irq) } static void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq parent_irq, - void *iommu, qemu_irq *dev_irq) + void *iommu, qemu_irq *dev_irq, const char *name) { DeviceState *dev; SysBusDevice *s; - dev = qdev_create(NULL, "sparc32_dma"); + dev = qdev_create(NULL, name); qdev_prop_set_ptr(dev, "iommu_opaque", iommu); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); @@ -862,10 +862,10 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size, } espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[18], - iommu, &espdma_irq); + iommu, &espdma_irq, "espdma"); ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, - slavio_irq[16], iommu, &ledma_irq); + slavio_irq[16], iommu, &ledma_irq, "ledma"); if (graphic_depth != 8 && graphic_depth != 24) { fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); @@ -1524,10 +1524,10 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, sbi_irq[0]); espdma = sparc32_dma_init(hwdef->espdma_base, sbi_irq[3], - iounits[0], &espdma_irq); + iounits[0], &espdma_irq, "espdma"); ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[4], - iounits[0], &ledma_irq); + iounits[0], &ledma_irq, "ledma"); if (graphic_depth != 8 && graphic_depth != 24) { fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); @@ -1707,10 +1707,10 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size, slavio_irq[1]); espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[2], - iommu, &espdma_irq); + iommu, &espdma_irq, "espdma"); ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, - slavio_irq[3], iommu, &ledma_irq); + slavio_irq[3], iommu, &ledma_irq, "ledma"); if (graphic_depth != 8 && graphic_depth != 24) { fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); -- 1.6.2.4