[PATCH qemu 25/38] aspeed/sdmc: rework the locking register of the memory controller

Andrew Jeffery andrew at aj.id.au
Mon Nov 28 12:55:55 AEDT 2016


On Fri, 2016-11-18 at 15:22 +0100, Cédric Le Goater wrote:
> The lock register is unlocked with a write of a special value and
> locked with a write of any other value. When unlocked, reads return
> one and when locked a zero.
> 
> > Signed-off-by: Cédric Le Goater <clg at kaod.org>
> ---
>  hw/misc/aspeed_sdmc.c         | 28 +++++++++++++++++++---------
>  include/hw/misc/aspeed_sdmc.h |  1 +
>  2 files changed, 20 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
> index 5f3ac0b6f608..867caa2d64dc 100644
> --- a/hw/misc/aspeed_sdmc.c
> +++ b/hw/misc/aspeed_sdmc.c
> @@ -83,17 +83,22 @@
>  static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
>  {
>      AspeedSDMCState *s = ASPEED_SDMC(opaque);
> +    uint64_t val = 0;
>  
>      addr >>= 2;
>  
> -    if (addr >= ARRAY_SIZE(s->regs)) {
> +    switch (addr) {
> +    case R_PROT:
> +        val = s->unlocked;
> +        break;
> +    default:
>          qemu_log_mask(LOG_GUEST_ERROR,
>                        "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
>                        __func__, addr);
> -        return 0;
> +        break;
>      }
>  
> -    return s->regs[addr];
> +    return val;

This suggests we only care about R_PROT - the change returns 0 for the
value of other registers. That doesn't seem right.

Andrew

>  }
>  
>  static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
> @@ -103,19 +108,18 @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
>  
>      addr >>= 2;
>  
> -    if (addr >= ARRAY_SIZE(s->regs)) {
> -        qemu_log_mask(LOG_GUEST_ERROR,
> -                      "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
> -                      __func__, addr);
> +    if (addr == R_PROT) {
> +        s->unlocked = (data == PROT_KEY_UNLOCK);
>          return;
>      }
>  
> -    if (addr != R_PROT && s->regs[R_PROT] != PROT_KEY_UNLOCK) {
> +    if (!s->unlocked) { /* TODO protect : MCR04 ∼ MCR7C */
>          qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
>          return;
>      }
>  
> -    if (addr == R_CONF) {
> +    switch (addr) {
> +    case R_CONF:
>          /* Make sure readonly bits are kept */
>          switch (s->silicon_rev) {
>          case AST2400_A0_SILICON_REV:
> @@ -128,6 +132,12 @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
>          default:
>              g_assert_not_reached();
>          }
> +        break;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
> +                      __func__, addr << 2);
> +        return;
>      }
>  
>      s->regs[addr] = data;
> diff --git a/include/hw/misc/aspeed_sdmc.h b/include/hw/misc/aspeed_sdmc.h
> index 551c8afdf4be..a4415d9efc2f 100644
> --- a/include/hw/misc/aspeed_sdmc.h
> +++ b/include/hw/misc/aspeed_sdmc.h
> @@ -28,6 +28,7 @@ typedef struct AspeedSDMCState {
>      uint32_t ram_bits;
>      uint64_t ram_size;
>  
> +    bool unlocked;
>  } AspeedSDMCState;
>  
>  #endif /* ASPEED_SDMC_H */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: This is a digitally signed message part
URL: <http://lists.ozlabs.org/pipermail/openbmc/attachments/20161128/32be6c9f/attachment.sig>


More information about the openbmc mailing list