diff mbox series

[v3,09/14] dp8393x: Use long-word-aligned RRA pointers in 32-bit mode

Message ID b971aa27c59c56f5c7c6bfaf26080fd97bb5cb9f.1579474761.git.fthain@telegraphics.com.au
State New
Headers show
Series Fixes for DP8393X SONIC device emulation | expand

Commit Message

Finn Thain Jan. 19, 2020, 10:59 p.m. UTC
Section 3.4.1 of the datasheet says,

    The alignment of the RRA is confined to either word or long word
    boundaries, depending upon the data width mode. In 16-bit mode,
    the RRA must be aligned to a word boundary (A0 is always zero)
    and in 32-bit mode, the RRA is aligned to a long word boundary
    (A0 and A1 are always zero).

This constraint has been implemented for 16-bit mode; implement it
for 32-bit mode too.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Tested-by: Laurent Vivier <laurent@vivier.eu>
---
 hw/net/dp8393x.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

Comments

Philippe Mathieu-Daudé Jan. 28, 2020, 11:13 a.m. UTC | #1
On 1/19/20 11:59 PM, Finn Thain wrote:
> Section 3.4.1 of the datasheet says,
> 
>      The alignment of the RRA is confined to either word or long word
>      boundaries, depending upon the data width mode. In 16-bit mode,
>      the RRA must be aligned to a word boundary (A0 is always zero)
>      and in 32-bit mode, the RRA is aligned to a long word boundary
>      (A0 and A1 are always zero).
> 
> This constraint has been implemented for 16-bit mode; implement it
> for 32-bit mode too.
> 
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> Tested-by: Laurent Vivier <laurent@vivier.eu>
> ---
>   hw/net/dp8393x.c | 8 ++++++--
>   1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> index 947ceef37c..b052e2c854 100644
> --- a/hw/net/dp8393x.c
> +++ b/hw/net/dp8393x.c
> @@ -663,12 +663,16 @@ static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data,
>                   qemu_flush_queued_packets(qemu_get_queue(s->nic));
>               }
>               break;
> -        /* Ignore least significant bit */
> +        /* The guest is required to store aligned pointers here */
>           case SONIC_RSA:
>           case SONIC_REA:
>           case SONIC_RRP:
>           case SONIC_RWP:
> -            s->regs[reg] = val & 0xfffe;
> +            if (s->regs[SONIC_DCR] & SONIC_DCR_DW) {
> +                s->regs[reg] = val & 0xfffc;
> +            } else {
> +                s->regs[reg] = val & 0xfffe;
> +            }
>               break;
>           /* Invert written value for some registers */
>           case SONIC_CRCT:
> 

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
diff mbox series

Patch

diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 947ceef37c..b052e2c854 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -663,12 +663,16 @@  static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data,
                 qemu_flush_queued_packets(qemu_get_queue(s->nic));
             }
             break;
-        /* Ignore least significant bit */
+        /* The guest is required to store aligned pointers here */
         case SONIC_RSA:
         case SONIC_REA:
         case SONIC_RRP:
         case SONIC_RWP:
-            s->regs[reg] = val & 0xfffe;
+            if (s->regs[SONIC_DCR] & SONIC_DCR_DW) {
+                s->regs[reg] = val & 0xfffc;
+            } else {
+                s->regs[reg] = val & 0xfffe;
+            }
             break;
         /* Invert written value for some registers */
         case SONIC_CRCT: