| Submitter | Blue Swirl |
|---|---|
| Date | Oct. 31, 2010, 11:11 a.m. |
| Message ID | <AANLkTim+QOaRxb41s0nOgGOcsNtTm6kCYq6Whu5suVV5@mail.gmail.com> |
| Download | mbox | patch |
| Permalink | /patch/69704/ |
| State | New |
| Headers | show |
Comments
Blue Swirl wrote: > 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 <blauwirbel@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(-) > This change never made it in, and I found a case that may benefit from it. The ledma seems to have an extra register that Solaris 9 reads, address 0x78400020 on SS-5, and the OBP properties of a SS-20 do indicate that there could be up to 32 bytes of registers: ok cd /iommu/sbus/ledma ok .attributes burst-sizes 0000003f reg 0000000f 00400010 00000020 name ledma As a hack, you can get Solaris 9 to boot single user by adding this one line to sun4m_hw_init() in sun4m.c: empty_slot_init(hwdef->dma_base + 32ULL, 16); Bob
On Fri, Dec 17, 2010 at 8:36 PM, Bob Breuer <breuerr@mc.net> wrote: > Blue Swirl wrote: >> 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 <blauwirbel@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(-) >> > > This change never made it in, and I found a case that may benefit from it. > > The ledma seems to have an extra register that Solaris 9 reads, address > 0x78400020 on SS-5, and the OBP properties of a SS-20 do indicate that > there could be up to 32 bytes of registers: > ok cd /iommu/sbus/ledma > ok .attributes > burst-sizes 0000003f > reg 0000000f 00400010 00000020 > name ledma Interesting. It looks like the size was 0x20 on all machines that had ledma. The older machines didn't have ledma but lebuffer and that was much bigger. > As a hack, you can get Solaris 9 to boot single user by adding this one > line to sun4m_hw_init() in sun4m.c: > empty_slot_init(hwdef->dma_base + 32ULL, 16); Care to send a patch?
Patch
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);
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 <blauwirbel@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(-) 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);