Patchwork sparc32_dma: separate ledma and espdma

login
register
mail settings
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 - Oct. 31, 2010, 11:11 a.m.
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);
Bob Breuer - Dec. 17, 2010, 8:36 p.m.
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
Blue Swirl - Dec. 17, 2010, 8:56 p.m.
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);