Skip to content

Commit

Permalink
aspeed/sdmc: rework the locking register of the memory controller
Browse files Browse the repository at this point in the history
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@kaod.org>
  • Loading branch information
legoater authored and amboar committed Feb 9, 2018
1 parent 4962b99 commit 0529fa5
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 9 deletions.
28 changes: 19 additions & 9 deletions hw/misc/aspeed_sdmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
Expand All @@ -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:
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions include/hw/misc/aspeed_sdmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ typedef struct AspeedSDMCState {
uint32_t ram_bits;
uint64_t ram_size;

bool unlocked;
} AspeedSDMCState;

#endif /* ASPEED_SDMC_H */

0 comments on commit 0529fa5

Please sign in to comment.