On Tue, Oct 1, 2024 at 11:24 AM Peter Maydell <peter.mayd...@linaro.org>
wrote:

> On Mon, 30 Sept 2024 at 22:28, Strahinja Jankovic
> <strahinjapjanko...@gmail.com> wrote:
> >
> > Hi Peter,
> >
> > Thank you very much for the review and detailed comments.
> >
> > I will try to address all comments in the v2 of the patches, but I have
> some questions I added below.
> >
> > On Mon, Sep 30, 2024 at 4:45 PM Peter Maydell <peter.mayd...@linaro.org>
> wrote:
> >> > +static uint64_t allwinner_a10_spi_read(void *opaque, hwaddr offset,
> >> > +                                       unsigned size)
> >> > +{
> >> > +    uint32_t value = 0;
> >> > +    AWA10SPIState *s = opaque;
> >> > +    uint32_t index = offset >> 2;
> >>
> >> The MemoryRegionOps defines that size == 1 is permitted,
> >> but this calculation of index without any validation
> >> of offset means that if the guest writes a byte to
> >> offset 1 we will treat that identically to writing a byte
> >> to offset 0. This probably isn't what the hardware does.
> >
> > I checked once more the User manual, and it does not mention
> > unaligned access (example for RXDATA)
> >
> > In 8-bits SPI bus width, this register can be accessed in byte,
> > half-word or word unit by AHB. In byte accessing method,
> > if there are words in RXFIFO, the top word is returned and
> > the RXFIFO depth is decreased by 1. In half-word accessing
> > method, the two SPI bursts are returned and the RXFIFO
> > depth is decrease by 2. In word accessing method, the four
> > SPI bursts are returned and the RXFIFO depth is decreased
> > by 4.
> >
> > I chose not to cover the half-word and word access methods,
> > since neither Linux kernel nor U-Boot use it
> > (both use only byte access).
> >
> > I guess that I could add `.valid.unaligned = false` when
> > initializing `MemoryRegionOps`?
>
> This wouldn't help, because a 2-byte load at offset 2
> is not "unaligned" from the memory system's point of view.
> (Also, unaligned = false is the default.)
>
> Looking again at your code I see I misread it a bit:
> I thought it was doing a switch() on index, but it is on
> offset.
>
> Using a switch on offset makes it easy to handle the case
> of "bogus write to an offset that isn't the start of a
> register":
>
>    switch (offset) {
>    case SOME_REG_OFFSET:
>        /*
>         * handle it; if size 1/2/4 behave differently,
>         * then look at 'size' to do the right thing.
>         */
>        break;
>    /* etc */
>    default:
>        qemu_log_mask(LOG_GUEST_ERROR,
>                      "%s: bad offset 0x%x\n", __func__,
>                      (uint32_t)offset);
>        break;
>    }
>
> Then both the "offset that's not a defined register"
> and "offset that's not aligned to the start of a register"
> go into the default case, we log it as a guest error,
> and do nothing.
>

Great, thanks for the suggestion! I will include it in v2.

Best regards,
Strahinja



>
> thanks
> -- PMM
>

Reply via email to