All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] sparc32: ledma extra registers
@ 2010-12-18 17:09 Bob Breuer
  2010-12-18 18:53 ` [Qemu-devel] " Blue Swirl
  0 siblings, 1 reply; 10+ messages in thread
From: Bob Breuer @ 2010-12-18 17:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl

ledma has 0x20 bytes of registers according to OBP, and at least Solaris9
reads the 5th register which is beyond what we've mapped.  So let's setup
a flag (inspired by a previous patch from Blue Swirl) to identify ledma
from espdma, and map another 16 bytes of registers which return 0.

Signed-off-by: Bob Breuer <breuerr@mc.net>
---
 hw/sparc32_dma.c |   15 ++++++++++++++-
 hw/sun4m.c       |   16 +++++++++-------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index e78f025..56be8c8 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -44,6 +44,9 @@
 /* We need the mask, because one instance of the device is not page
    aligned (ledma, start address 0x0010) */
 #define DMA_MASK (DMA_SIZE - 1)
+/* ledma has more than 4 registers, Solaris reads the 5th one */
+#define DMA_ETH_SIZE (8 * sizeof(uint32_t))
+#define DMA_MAX_REG_OFFSET (2 * DMA_SIZE - 1)
 
 #define DMA_VER 0xa0000000
 #define DMA_INTR 1
@@ -65,6 +68,7 @@ struct DMAState {
     qemu_irq irq;
     void *iommu;
     qemu_irq gpio[2];
+    uint32_t is_ledma;
 };
 
 enum {
@@ -165,6 +169,9 @@ static uint32_t dma_mem_readl(void *opaque, target_phys_addr_t addr)
     DMAState *s = opaque;
     uint32_t saddr;
 
+    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
+        return 0; /* extra mystery register(s) */
+    }
     saddr = (addr & DMA_MASK) >> 2;
     trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
     return s->dmaregs[saddr];
@@ -175,6 +182,9 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
     DMAState *s = opaque;
     uint32_t saddr;
 
+    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
+        return; /* extra mystery register(s) */
+    }
     saddr = (addr & DMA_MASK) >> 2;
     trace_sparc32_dma_mem_writel(addr, s->dmaregs[saddr], val);
     switch (saddr) {
@@ -254,12 +264,14 @@ static int sparc32_dma_init1(SysBusDevice *dev)
 {
     DMAState *s = FROM_SYSBUS(DMAState, dev);
     int dma_io_memory;
+    int reg_size;
 
     sysbus_init_irq(dev, &s->irq);
 
     dma_io_memory = cpu_register_io_memory(dma_mem_read, dma_mem_write, s,
                                            DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, DMA_SIZE, dma_io_memory);
+    reg_size = s->is_ledma ? DMA_ETH_SIZE : DMA_SIZE;
+    sysbus_init_mmio(dev, reg_size, dma_io_memory);
 
     qdev_init_gpio_in(&dev->qdev, dma_set_irq, 1);
     qdev_init_gpio_out(&dev->qdev, s->gpio, 2);
@@ -275,6 +287,7 @@ static SysBusDeviceInfo sparc32_dma_info = {
     .qdev.reset = dma_reset,
     .qdev.props = (Property[]) {
         DEFINE_PROP_PTR("iommu_opaque", DMAState, iommu),
+        DEFINE_PROP_UINT32("is_ledma", DMAState, is_ledma, 0),
         DEFINE_PROP_END_OF_LIST(),
     }
 };
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 4795b3f..30e8a21 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -378,13 +378,14 @@ 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, int is_ledma)
 {
     DeviceState *dev;
     SysBusDevice *s;
 
     dev = qdev_create(NULL, "sparc32_dma");
     qdev_prop_set_ptr(dev, "iommu_opaque", iommu);
+    qdev_prop_set_uint32(dev, "is_ledma", is_ledma);
     qdev_init_nofail(dev);
     s = sysbus_from_qdev(dev);
     sysbus_connect_irq(s, 0, parent_irq);
@@ -862,10 +863,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, 0);
 
     ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
-                             slavio_irq[16], iommu, &ledma_irq);
+                             slavio_irq[16], iommu, &ledma_irq, 1);
 
     if (graphic_depth != 8 && graphic_depth != 24) {
         fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
@@ -1524,10 +1525,11 @@ 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, 0);
 
+    /* should be lebuffer instead */
     ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[4],
-                             iounits[0], &ledma_irq);
+                             iounits[0], &ledma_irq, 0);
 
     if (graphic_depth != 8 && graphic_depth != 24) {
         fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
@@ -1707,10 +1709,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, 0);
 
     ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
-                             slavio_irq[3], iommu, &ledma_irq);
+                             slavio_irq[3], iommu, &ledma_irq, 1);
 
     if (graphic_depth != 8 && graphic_depth != 24) {
         fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] Re: [PATCH] sparc32: ledma extra registers
  2010-12-18 17:09 [Qemu-devel] [PATCH] sparc32: ledma extra registers Bob Breuer
@ 2010-12-18 18:53 ` Blue Swirl
  2010-12-18 20:26   ` Andreas Färber
  0 siblings, 1 reply; 10+ messages in thread
From: Blue Swirl @ 2010-12-18 18:53 UTC (permalink / raw)
  To: Bob Breuer; +Cc: qemu-devel

Thanks, applied.

On Sat, Dec 18, 2010 at 5:09 PM, Bob Breuer <breuerr@mc.net> wrote:
> ledma has 0x20 bytes of registers according to OBP, and at least Solaris9
> reads the 5th register which is beyond what we've mapped.  So let's setup
> a flag (inspired by a previous patch from Blue Swirl) to identify ledma
> from espdma, and map another 16 bytes of registers which return 0.
>
> Signed-off-by: Bob Breuer <breuerr@mc.net>
> ---
>  hw/sparc32_dma.c |   15 ++++++++++++++-
>  hw/sun4m.c       |   16 +++++++++-------
>  2 files changed, 23 insertions(+), 8 deletions(-)
>
> diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
> index e78f025..56be8c8 100644
> --- a/hw/sparc32_dma.c
> +++ b/hw/sparc32_dma.c
> @@ -44,6 +44,9 @@
>  /* We need the mask, because one instance of the device is not page
>    aligned (ledma, start address 0x0010) */
>  #define DMA_MASK (DMA_SIZE - 1)
> +/* ledma has more than 4 registers, Solaris reads the 5th one */
> +#define DMA_ETH_SIZE (8 * sizeof(uint32_t))
> +#define DMA_MAX_REG_OFFSET (2 * DMA_SIZE - 1)
>
>  #define DMA_VER 0xa0000000
>  #define DMA_INTR 1
> @@ -65,6 +68,7 @@ struct DMAState {
>     qemu_irq irq;
>     void *iommu;
>     qemu_irq gpio[2];
> +    uint32_t is_ledma;
>  };
>
>  enum {
> @@ -165,6 +169,9 @@ static uint32_t dma_mem_readl(void *opaque, target_phys_addr_t addr)
>     DMAState *s = opaque;
>     uint32_t saddr;
>
> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
> +        return 0; /* extra mystery register(s) */
> +    }
>     saddr = (addr & DMA_MASK) >> 2;
>     trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
>     return s->dmaregs[saddr];
> @@ -175,6 +182,9 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
>     DMAState *s = opaque;
>     uint32_t saddr;
>
> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
> +        return; /* extra mystery register(s) */
> +    }
>     saddr = (addr & DMA_MASK) >> 2;
>     trace_sparc32_dma_mem_writel(addr, s->dmaregs[saddr], val);
>     switch (saddr) {
> @@ -254,12 +264,14 @@ static int sparc32_dma_init1(SysBusDevice *dev)
>  {
>     DMAState *s = FROM_SYSBUS(DMAState, dev);
>     int dma_io_memory;
> +    int reg_size;
>
>     sysbus_init_irq(dev, &s->irq);
>
>     dma_io_memory = cpu_register_io_memory(dma_mem_read, dma_mem_write, s,
>                                            DEVICE_NATIVE_ENDIAN);
> -    sysbus_init_mmio(dev, DMA_SIZE, dma_io_memory);
> +    reg_size = s->is_ledma ? DMA_ETH_SIZE : DMA_SIZE;
> +    sysbus_init_mmio(dev, reg_size, dma_io_memory);
>
>     qdev_init_gpio_in(&dev->qdev, dma_set_irq, 1);
>     qdev_init_gpio_out(&dev->qdev, s->gpio, 2);
> @@ -275,6 +287,7 @@ static SysBusDeviceInfo sparc32_dma_info = {
>     .qdev.reset = dma_reset,
>     .qdev.props = (Property[]) {
>         DEFINE_PROP_PTR("iommu_opaque", DMAState, iommu),
> +        DEFINE_PROP_UINT32("is_ledma", DMAState, is_ledma, 0),
>         DEFINE_PROP_END_OF_LIST(),
>     }
>  };
> diff --git a/hw/sun4m.c b/hw/sun4m.c
> index 4795b3f..30e8a21 100644
> --- a/hw/sun4m.c
> +++ b/hw/sun4m.c
> @@ -378,13 +378,14 @@ 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, int is_ledma)
>  {
>     DeviceState *dev;
>     SysBusDevice *s;
>
>     dev = qdev_create(NULL, "sparc32_dma");
>     qdev_prop_set_ptr(dev, "iommu_opaque", iommu);
> +    qdev_prop_set_uint32(dev, "is_ledma", is_ledma);
>     qdev_init_nofail(dev);
>     s = sysbus_from_qdev(dev);
>     sysbus_connect_irq(s, 0, parent_irq);
> @@ -862,10 +863,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, 0);
>
>     ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
> -                             slavio_irq[16], iommu, &ledma_irq);
> +                             slavio_irq[16], iommu, &ledma_irq, 1);
>
>     if (graphic_depth != 8 && graphic_depth != 24) {
>         fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
> @@ -1524,10 +1525,11 @@ 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, 0);
>
> +    /* should be lebuffer instead */
>     ledma = sparc32_dma_init(hwdef->ledma_base, sbi_irq[4],
> -                             iounits[0], &ledma_irq);
> +                             iounits[0], &ledma_irq, 0);
>
>     if (graphic_depth != 8 && graphic_depth != 24) {
>         fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
> @@ -1707,10 +1709,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, 0);
>
>     ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
> -                             slavio_irq[3], iommu, &ledma_irq);
> +                             slavio_irq[3], iommu, &ledma_irq, 1);
>
>     if (graphic_depth != 8 && graphic_depth != 24) {
>         fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
>
>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] sparc32: ledma extra registers
  2010-12-18 18:53 ` [Qemu-devel] " Blue Swirl
@ 2010-12-18 20:26   ` Andreas Färber
  2010-12-19 19:37     ` Bob Breuer
  0 siblings, 1 reply; 10+ messages in thread
From: Andreas Färber @ 2010-12-18 20:26 UTC (permalink / raw)
  To: Blue Swirl, Bob Breuer; +Cc: QEMU Developers

Am 18.12.2010 um 19:53 schrieb Blue Swirl:

> On Sat, Dec 18, 2010 at 5:09 PM, Bob Breuer <breuerr@mc.net> wrote:
>> ledma has 0x20 bytes of registers according to OBP, and at least  
>> Solaris9
>> reads the 5th register which is beyond what we've mapped.  So let's  
>> setup
>> a flag (inspired by a previous patch from Blue Swirl) to identify  
>> ledma
>> from espdma, and map another 16 bytes of registers which return 0.
>>
>> Signed-off-by: Bob Breuer <breuerr@mc.net>

I'm not familar with that part of code but...

>> diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
>> index e78f025..56be8c8 100644
>> --- a/hw/sparc32_dma.c
>> +++ b/hw/sparc32_dma.c

>> @@ -165,6 +169,9 @@ static uint32_t dma_mem_readl(void *opaque,  
>> target_phys_addr_t addr)
>>     DMAState *s = opaque;
>>     uint32_t saddr;
>>
>> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
>> +        return 0; /* extra mystery register(s) */

Wouldn't it be a good idea to trace these "mystery" reads...

>> +    }
>>     saddr = (addr & DMA_MASK) >> 2;
>>     trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
>>     return s->dmaregs[saddr];
>> @@ -175,6 +182,9 @@ static void dma_mem_writel(void *opaque,  
>> target_phys_addr_t addr, uint32_t val)
>>     DMAState *s = opaque;
>>     uint32_t saddr;
>>
>> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
>> +        return; /* extra mystery register(s) */

...and writes? We return just before the tracepoints fire.

Andreas

>> +    }
>>     saddr = (addr & DMA_MASK) >> 2;
>>     trace_sparc32_dma_mem_writel(addr, s->dmaregs[saddr], val);
>>     switch (saddr) {

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] sparc32: ledma extra registers
  2010-12-18 20:26   ` Andreas Färber
@ 2010-12-19 19:37     ` Bob Breuer
  2010-12-19 20:00       ` [Qemu-devel] [PATCH] sparc32: ledma extra registers need tracing too Bob Breuer
  2010-12-20 10:22       ` [Qemu-devel] Re: [PATCH] sparc32: ledma extra registers Artyom Tarasenko
  0 siblings, 2 replies; 10+ messages in thread
From: Bob Breuer @ 2010-12-19 19:37 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Blue Swirl, QEMU Developers

Andreas Färber wrote:
> Am 18.12.2010 um 19:53 schrieb Blue Swirl:
>
>> On Sat, Dec 18, 2010 at 5:09 PM, Bob Breuer <breuerr@mc.net> wrote:
>>> ledma has 0x20 bytes of registers according to OBP, and at least
>>> Solaris9
>>> reads the 5th register which is beyond what we've mapped.  So let's
>>> setup
>>> a flag (inspired by a previous patch from Blue Swirl) to identify ledma
>>> from espdma, and map another 16 bytes of registers which return 0.
>>>
>>> Signed-off-by: Bob Breuer <breuerr@mc.net>
>
> I'm not familar with that part of code but...
>
>>> diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
>>> index e78f025..56be8c8 100644
>>> --- a/hw/sparc32_dma.c
>>> +++ b/hw/sparc32_dma.c
>
>>> @@ -165,6 +169,9 @@ static uint32_t dma_mem_readl(void *opaque,
>>> target_phys_addr_t addr)
>>>     DMAState *s = opaque;
>>>     uint32_t saddr;
>>>
>>> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
>>> +        return 0; /* extra mystery register(s) */
>
> Wouldn't it be a good idea to trace these "mystery" reads...
>
>>> +    }
>>>     saddr = (addr & DMA_MASK) >> 2;
>>>     trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
>>>     return s->dmaregs[saddr];
>>> @@ -175,6 +182,9 @@ static void dma_mem_writel(void *opaque,
>>> target_phys_addr_t addr, uint32_t val)
>>>     DMAState *s = opaque;
>>>     uint32_t saddr;
>>>
>>> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
>>> +        return; /* extra mystery register(s) */
>
> ...and writes? We return just before the tracepoints fire.
>

Ok, I'll put together a patch to add the trace calls just before the
returns.  How about I also call it undocumented instead of mystery. 
None of the BSD's or Linux know about or use anything beyond the 4
registers.

Blue, do you know of a mirror for the documents at
http://wikis.sun.com/display/FOSSdocs/Home ?  The pdfs there seem to
have gone missing, and maybe there might be something in the macio
documentation.

Bob

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH] sparc32: ledma extra registers need tracing too
  2010-12-19 19:37     ` Bob Breuer
@ 2010-12-19 20:00       ` Bob Breuer
  2010-12-20 17:55         ` [Qemu-devel] [PATCH v2] " Bob Breuer
  2010-12-20 10:22       ` [Qemu-devel] Re: [PATCH] sparc32: ledma extra registers Artyom Tarasenko
  1 sibling, 1 reply; 10+ messages in thread
From: Bob Breuer @ 2010-12-19 20:00 UTC (permalink / raw)
  To: QEMU Developers; +Cc: Blue Swirl, Andreas Färber

Also trace the extra registers, and call them undocumented instead.

Signed-off-by: Bob Breuer <breuerr@mc.net>

diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index 56be8c8..0325a55 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -170,7 +170,9 @@ static uint32_t dma_mem_readl(void *opaque, target_phys_addr_t addr)
     uint32_t saddr;
 
     if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
-        return 0; /* extra mystery register(s) */
+        /* extra undocumented register(s) */
+        trace_sparc32_dma_mem_readl(addr, 0);
+        return 0;
     }
     saddr = (addr & DMA_MASK) >> 2;
     trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
@@ -183,7 +185,9 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
     uint32_t saddr;
 
     if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
-        return; /* extra mystery register(s) */
+        /* extra undocumented register(s) */
+        trace_sparc32_dma_mem_writel(addr, 0, val);
+        return;
     }
     saddr = (addr & DMA_MASK) >> 2;
     trace_sparc32_dma_mem_writel(addr, s->dmaregs[saddr], val);

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] sparc32: ledma extra registers
  2010-12-19 19:37     ` Bob Breuer
  2010-12-19 20:00       ` [Qemu-devel] [PATCH] sparc32: ledma extra registers need tracing too Bob Breuer
@ 2010-12-20 10:22       ` Artyom Tarasenko
  2010-12-20 17:33         ` Bob Breuer
  1 sibling, 1 reply; 10+ messages in thread
From: Artyom Tarasenko @ 2010-12-20 10:22 UTC (permalink / raw)
  To: Bob Breuer; +Cc: Blue Swirl, Andreas Färber, QEMU Developers

On Sun, Dec 19, 2010 at 8:37 PM, Bob Breuer <breuerr@mc.net> wrote:
> Andreas Färber wrote:
>> Am 18.12.2010 um 19:53 schrieb Blue Swirl:
>>
>>> On Sat, Dec 18, 2010 at 5:09 PM, Bob Breuer <breuerr@mc.net> wrote:
>>>> ledma has 0x20 bytes of registers according to OBP, and at least
>>>> Solaris9
>>>> reads the 5th register which is beyond what we've mapped.  So let's
>>>> setup
>>>> a flag (inspired by a previous patch from Blue Swirl) to identify ledma
>>>> from espdma, and map another 16 bytes of registers which return 0.
>>>>
>>>> Signed-off-by: Bob Breuer <breuerr@mc.net>
>>
>> I'm not familar with that part of code but...
>>
>>>> diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
>>>> index e78f025..56be8c8 100644
>>>> --- a/hw/sparc32_dma.c
>>>> +++ b/hw/sparc32_dma.c
>>
>>>> @@ -165,6 +169,9 @@ static uint32_t dma_mem_readl(void *opaque,
>>>> target_phys_addr_t addr)
>>>>     DMAState *s = opaque;
>>>>     uint32_t saddr;
>>>>
>>>> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
>>>> +        return 0; /* extra mystery register(s) */
>>
>> Wouldn't it be a good idea to trace these "mystery" reads...
>>
>>>> +    }
>>>>     saddr = (addr & DMA_MASK) >> 2;
>>>>     trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
>>>>     return s->dmaregs[saddr];
>>>> @@ -175,6 +182,9 @@ static void dma_mem_writel(void *opaque,
>>>> target_phys_addr_t addr, uint32_t val)
>>>>     DMAState *s = opaque;
>>>>     uint32_t saddr;
>>>>
>>>> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
>>>> +        return; /* extra mystery register(s) */
>>
>> ...and writes? We return just before the tracepoints fire.
>>
>
> Ok, I'll put together a patch to add the trace calls just before the
> returns.  How about I also call it undocumented instead of mystery.
> None of the BSD's or Linux know about or use anything beyond the 4
> registers.

I'd use "aliased" instead of mystery.  On a real SS-5:

ok 78400020 20 spacel@ .
a4240050
ok 78400000 20 spacel@ .
a4240050
ok 78400024 20 spacel@ .
fc004000
ok 78400004 20 spacel@ .
fc004000

Addresses 0x7840002x are aliases for 0x7840000x. As well as
0x7840004x. And so on up to
ok 787fffe4 20 spacel@ .
fc004000
78800004 20 spacel@ .
0

Or a real SS-20 ef0400000 is aliased up to ef37fffe0

Fwiw I think it's a bug in the later Solaris versions:
http://tyom.blogspot.com/2010/10/bug-in-all-solaris-versions-after-57.html

On the bare metal it works because of address aliasing. If you want to
emulate the hw precisely, the Blue's generic aliasing patch can be
used here. The question is though do we want to do a generic aliasing
for all the SBUS devices, or just in the single case(es) where we know
is necessary.

On the other hand Solaris seems to be fine with a 0 stub too.

-- 
Regards,
Artyom Tarasenko

solaris/sparc under qemu blog: http://tyom.blogspot.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] sparc32: ledma extra registers
  2010-12-20 10:22       ` [Qemu-devel] Re: [PATCH] sparc32: ledma extra registers Artyom Tarasenko
@ 2010-12-20 17:33         ` Bob Breuer
  2010-12-21  9:28           ` Artyom Tarasenko
  0 siblings, 1 reply; 10+ messages in thread
From: Bob Breuer @ 2010-12-20 17:33 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: Blue Swirl, Andreas Färber, QEMU Developers

Artyom Tarasenko wrote:
> On Sun, Dec 19, 2010 at 8:37 PM, Bob Breuer <breuerr@mc.net> wrote:
>   
>> Andreas Färber wrote:
>>     
>>> Am 18.12.2010 um 19:53 schrieb Blue Swirl:
>>>
>>>       
>>>> On Sat, Dec 18, 2010 at 5:09 PM, Bob Breuer <breuerr@mc.net> wrote:
>>>>         
>>>>> ledma has 0x20 bytes of registers according to OBP, and at least
>>>>> Solaris9
>>>>> reads the 5th register which is beyond what we've mapped.  So let's
>>>>> setup
>>>>> a flag (inspired by a previous patch from Blue Swirl) to identify ledma
>>>>> from espdma, and map another 16 bytes of registers which return 0.
>>>>>
>>>>> Signed-off-by: Bob Breuer <breuerr@mc.net>
>>>>>           
>>> I'm not familar with that part of code but...
>>>
>>>       
>>>>> diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
>>>>> index e78f025..56be8c8 100644
>>>>> --- a/hw/sparc32_dma.c
>>>>> +++ b/hw/sparc32_dma.c
>>>>>           
>>>>> @@ -165,6 +169,9 @@ static uint32_t dma_mem_readl(void *opaque,
>>>>> target_phys_addr_t addr)
>>>>>     DMAState *s = opaque;
>>>>>     uint32_t saddr;
>>>>>
>>>>> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
>>>>> +        return 0; /* extra mystery register(s) */
>>>>>           
>>> Wouldn't it be a good idea to trace these "mystery" reads...
>>>
>>>       
>>>>> +    }
>>>>>     saddr = (addr & DMA_MASK) >> 2;
>>>>>     trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
>>>>>     return s->dmaregs[saddr];
>>>>> @@ -175,6 +182,9 @@ static void dma_mem_writel(void *opaque,
>>>>> target_phys_addr_t addr, uint32_t val)
>>>>>     DMAState *s = opaque;
>>>>>     uint32_t saddr;
>>>>>
>>>>> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
>>>>> +        return; /* extra mystery register(s) */
>>>>>           
>>> ...and writes? We return just before the tracepoints fire.
>>>
>>>       
>> Ok, I'll put together a patch to add the trace calls just before the
>> returns.  How about I also call it undocumented instead of mystery.
>> None of the BSD's or Linux know about or use anything beyond the 4
>> registers.
>>     
>
> I'd use "aliased" instead of mystery.  On a real SS-5:
>
> ok 78400020 20 spacel@ .
> a4240050
> ok 78400000 20 spacel@ .
> a4240050
> ok 78400024 20 spacel@ .
> fc004000
> ok 78400004 20 spacel@ .
> fc004000
>   
Verified that it also aliases on an SS-20.
> Addresses 0x7840002x are aliases for 0x7840000x. As well as
> 0x7840004x. And so on up to
> ok 787fffe4 20 spacel@ .
> fc004000
> 78800004 20 spacel@ .
> 0
>
> Or a real SS-20 ef0400000 is aliased up to ef37fffe0
>
> Fwiw I think it's a bug in the later Solaris versions:
> http://tyom.blogspot.com/2010/10/bug-in-all-solaris-versions-after-57.html
>
> On the bare metal it works because of address aliasing. If you want to
> emulate the hw precisely, the Blue's generic aliasing patch can be
> used here. The question is though do we want to do a generic aliasing
> for all the SBUS devices, or just in the single case(es) where we know
> is necessary.
>
> On the other hand Solaris seems to be fine with a 0 stub too.
>   
I'll send a patch to update the comments.  If it's accessing a wrong
register because of a bug, then it may not matter what value is returned.

Bob

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2] sparc32: ledma extra registers need tracing too
  2010-12-19 20:00       ` [Qemu-devel] [PATCH] sparc32: ledma extra registers need tracing too Bob Breuer
@ 2010-12-20 17:55         ` Bob Breuer
  2010-12-20 21:20           ` [Qemu-devel] " Blue Swirl
  0 siblings, 1 reply; 10+ messages in thread
From: Bob Breuer @ 2010-12-20 17:55 UTC (permalink / raw)
  To: QEMU Developers; +Cc: Blue Swirl, Andreas Färber, Artyom Tarasenko

Also trace the extra registers, and update the comments with new
info from Artyom Tarasenko.

Signed-off-by: Bob Breuer <breuerr@mc.net>
---
Since the extra registers are aliased, we could instead alias them at
a higher level.  Solaris9 boots to single-user with either option.

diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index 56be8c8..e75694b 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -44,7 +44,7 @@
 /* We need the mask, because one instance of the device is not page
    aligned (ledma, start address 0x0010) */
 #define DMA_MASK (DMA_SIZE - 1)
-/* ledma has more than 4 registers, Solaris reads the 5th one */
+/* OBP says 0x20 bytes for ledma, the extras are aliased to espdma */
 #define DMA_ETH_SIZE (8 * sizeof(uint32_t))
 #define DMA_MAX_REG_OFFSET (2 * DMA_SIZE - 1)
 
@@ -170,7 +170,10 @@ static uint32_t dma_mem_readl(void *opaque, target_phys_addr_t addr)
     uint32_t saddr;
 
     if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
-        return 0; /* extra mystery register(s) */
+        /* aliased to espdma, but we can't get there from here */
+        /* buggy driver if using undocumented behavior, just return 0 */
+        trace_sparc32_dma_mem_readl(addr, 0);
+        return 0;
     }
     saddr = (addr & DMA_MASK) >> 2;
     trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
@@ -183,7 +186,9 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
     uint32_t saddr;
 
     if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
-        return; /* extra mystery register(s) */
+        /* aliased to espdma, but we can't get there from here */
+        trace_sparc32_dma_mem_writel(addr, 0, val);
+        return;
     }
     saddr = (addr & DMA_MASK) >> 2;
     trace_sparc32_dma_mem_writel(addr, s->dmaregs[saddr], val);

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] Re: [PATCH v2] sparc32: ledma extra registers need tracing too
  2010-12-20 17:55         ` [Qemu-devel] [PATCH v2] " Bob Breuer
@ 2010-12-20 21:20           ` Blue Swirl
  0 siblings, 0 replies; 10+ messages in thread
From: Blue Swirl @ 2010-12-20 21:20 UTC (permalink / raw)
  To: Bob Breuer; +Cc: Andreas Färber, QEMU Developers, Artyom Tarasenko

Thanks, applied.

On Mon, Dec 20, 2010 at 5:55 PM, Bob Breuer <breuerr@mc.net> wrote:
> Also trace the extra registers, and update the comments with new
> info from Artyom Tarasenko.
>
> Signed-off-by: Bob Breuer <breuerr@mc.net>
> ---
> Since the extra registers are aliased, we could instead alias them at
> a higher level.  Solaris9 boots to single-user with either option.
>
> diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
> index 56be8c8..e75694b 100644
> --- a/hw/sparc32_dma.c
> +++ b/hw/sparc32_dma.c
> @@ -44,7 +44,7 @@
>  /* We need the mask, because one instance of the device is not page
>    aligned (ledma, start address 0x0010) */
>  #define DMA_MASK (DMA_SIZE - 1)
> -/* ledma has more than 4 registers, Solaris reads the 5th one */
> +/* OBP says 0x20 bytes for ledma, the extras are aliased to espdma */
>  #define DMA_ETH_SIZE (8 * sizeof(uint32_t))
>  #define DMA_MAX_REG_OFFSET (2 * DMA_SIZE - 1)
>
> @@ -170,7 +170,10 @@ static uint32_t dma_mem_readl(void *opaque, target_phys_addr_t addr)
>     uint32_t saddr;
>
>     if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
> -        return 0; /* extra mystery register(s) */
> +        /* aliased to espdma, but we can't get there from here */
> +        /* buggy driver if using undocumented behavior, just return 0 */
> +        trace_sparc32_dma_mem_readl(addr, 0);
> +        return 0;
>     }
>     saddr = (addr & DMA_MASK) >> 2;
>     trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
> @@ -183,7 +186,9 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
>     uint32_t saddr;
>
>     if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
> -        return; /* extra mystery register(s) */
> +        /* aliased to espdma, but we can't get there from here */
> +        trace_sparc32_dma_mem_writel(addr, 0, val);
> +        return;
>     }
>     saddr = (addr & DMA_MASK) >> 2;
>     trace_sparc32_dma_mem_writel(addr, s->dmaregs[saddr], val);
>
>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] sparc32: ledma extra registers
  2010-12-20 17:33         ` Bob Breuer
@ 2010-12-21  9:28           ` Artyom Tarasenko
  0 siblings, 0 replies; 10+ messages in thread
From: Artyom Tarasenko @ 2010-12-21  9:28 UTC (permalink / raw)
  To: Bob Breuer; +Cc: Blue Swirl, Andreas Färber, QEMU Developers

On Mon, Dec 20, 2010 at 6:33 PM, Bob Breuer <breuerr@mc.net> wrote:
> Artyom Tarasenko wrote:
>> On Sun, Dec 19, 2010 at 8:37 PM, Bob Breuer <breuerr@mc.net> wrote:
>>
>>> Andreas Färber wrote:
>>>
>>>> Am 18.12.2010 um 19:53 schrieb Blue Swirl:
>>>>
>>>>
>>>>> On Sat, Dec 18, 2010 at 5:09 PM, Bob Breuer <breuerr@mc.net> wrote:
>>>>>
>>>>>> ledma has 0x20 bytes of registers according to OBP, and at least
>>>>>> Solaris9
>>>>>> reads the 5th register which is beyond what we've mapped.  So let's
>>>>>> setup
>>>>>> a flag (inspired by a previous patch from Blue Swirl) to identify ledma
>>>>>> from espdma, and map another 16 bytes of registers which return 0.
>>>>>>
>>>>>> Signed-off-by: Bob Breuer <breuerr@mc.net>
>>>>>>
>>>> I'm not familar with that part of code but...
>>>>
>>>>
>>>>>> diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
>>>>>> index e78f025..56be8c8 100644
>>>>>> --- a/hw/sparc32_dma.c
>>>>>> +++ b/hw/sparc32_dma.c
>>>>>>
>>>>>> @@ -165,6 +169,9 @@ static uint32_t dma_mem_readl(void *opaque,
>>>>>> target_phys_addr_t addr)
>>>>>>     DMAState *s = opaque;
>>>>>>     uint32_t saddr;
>>>>>>
>>>>>> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
>>>>>> +        return 0; /* extra mystery register(s) */
>>>>>>
>>>> Wouldn't it be a good idea to trace these "mystery" reads...
>>>>
>>>>
>>>>>> +    }
>>>>>>     saddr = (addr & DMA_MASK) >> 2;
>>>>>>     trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
>>>>>>     return s->dmaregs[saddr];
>>>>>> @@ -175,6 +182,9 @@ static void dma_mem_writel(void *opaque,
>>>>>> target_phys_addr_t addr, uint32_t val)
>>>>>>     DMAState *s = opaque;
>>>>>>     uint32_t saddr;
>>>>>>
>>>>>> +    if (s->is_ledma && (addr > DMA_MAX_REG_OFFSET)) {
>>>>>> +        return; /* extra mystery register(s) */
>>>>>>
>>>> ...and writes? We return just before the tracepoints fire.
>>>>
>>>>
>>> Ok, I'll put together a patch to add the trace calls just before the
>>> returns.  How about I also call it undocumented instead of mystery.
>>> None of the BSD's or Linux know about or use anything beyond the 4
>>> registers.
>>>
>>
>> I'd use "aliased" instead of mystery.  On a real SS-5:
>>
>> ok 78400020 20 spacel@ .
>> a4240050
>> ok 78400000 20 spacel@ .
>> a4240050
>> ok 78400024 20 spacel@ .
>> fc004000
>> ok 78400004 20 spacel@ .
>> fc004000
>>
> Verified that it also aliases on an SS-20.
>> Addresses 0x7840002x are aliases for 0x7840000x. As well as
>> 0x7840004x. And so on up to
>> ok 787fffe4 20 spacel@ .
>> fc004000
>> 78800004 20 spacel@ .
>> 0
>>
>> Or a real SS-20 ef0400000 is aliased up to ef37fffe0
>>
>> Fwiw I think it's a bug in the later Solaris versions:
>> http://tyom.blogspot.com/2010/10/bug-in-all-solaris-versions-after-57.html
>>
>> On the bare metal it works because of address aliasing. If you want to
>> emulate the hw precisely, the Blue's generic aliasing patch can be
>> used here. The question is though do we want to do a generic aliasing
>> for all the SBUS devices, or just in the single case(es) where we know
>> is necessary.
>>
>> On the other hand Solaris seems to be fine with a 0 stub too.
>>
> I'll send a patch to update the comments.  If it's accessing a wrong
> register because of a bug, then it may not matter what value is returned.

I think the value is important, but the tests show that 0 is fine.


-- 
Regards,
Artyom Tarasenko

solaris/sparc under qemu blog: http://tyom.blogspot.com/

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-12-21  9:28 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-18 17:09 [Qemu-devel] [PATCH] sparc32: ledma extra registers Bob Breuer
2010-12-18 18:53 ` [Qemu-devel] " Blue Swirl
2010-12-18 20:26   ` Andreas Färber
2010-12-19 19:37     ` Bob Breuer
2010-12-19 20:00       ` [Qemu-devel] [PATCH] sparc32: ledma extra registers need tracing too Bob Breuer
2010-12-20 17:55         ` [Qemu-devel] [PATCH v2] " Bob Breuer
2010-12-20 21:20           ` [Qemu-devel] " Blue Swirl
2010-12-20 10:22       ` [Qemu-devel] Re: [PATCH] sparc32: ledma extra registers Artyom Tarasenko
2010-12-20 17:33         ` Bob Breuer
2010-12-21  9:28           ` Artyom Tarasenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.