Message ID | b971aa27c59c56f5c7c6bfaf26080fd97bb5cb9f.1579474761.git.fthain@telegraphics.com.au |
---|---|
State | New |
Headers | show |
Series | Fixes for DP8393X SONIC device emulation | expand |
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 --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: