[PATCH qemu 25/38] aspeed/sdmc: rework the locking register of the memory controller
Cédric Le Goater
clg at kaod.org
Sat Nov 19 01:22:05 AEDT 2016
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;
}
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 */
--
2.7.4
More information about the openbmc
mailing list