diff options
author | Peter Maydell | 2021-02-19 15:45:48 +0100 |
---|---|---|
committer | Peter Maydell | 2021-03-08 18:20:02 +0100 |
commit | 246dbeb76319fdaa7030403ea0273617331f6a44 (patch) | |
tree | 52a9d7b8c2f174940d4327f57725476628affed9 | |
parent | hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300 (diff) | |
download | qemu-246dbeb76319fdaa7030403ea0273617331f6a44.tar.gz qemu-246dbeb76319fdaa7030403ea0273617331f6a44.tar.xz qemu-246dbeb76319fdaa7030403ea0273617331f6a44.zip |
hw/misc/iotkit-sysctl: Handle INITSVTOR* for SSE-300
The SSE-300 has only one CPU and so no INITSVTOR1. It does
have INITSVTOR0, but unlike the SSE-200 this register now
has a LOCK bit which can be set to 1 to prevent any further
writes to the register. Implement these differences.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210219144617.4782-16-peter.maydell@linaro.org
-rw-r--r-- | hw/misc/iotkit-sysctl.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c index 54004bebcb..511ede089c 100644 --- a/hw/misc/iotkit-sysctl.c +++ b/hw/misc/iotkit-sysctl.c @@ -45,6 +45,8 @@ REG32(SWRESET, 0x108) FIELD(SWRESET, SWRESETREQ, 9, 1) REG32(GRETREG, 0x10c) REG32(INITSVTOR0, 0x110) + FIELD(INITSVTOR0, LOCK, 0, 1) + FIELD(INITSVTOR0, VTOR, 7, 25) REG32(INITSVTOR1, 0x114) REG32(CPUWAIT, 0x118) REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */ @@ -167,6 +169,8 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset, case ARMSSE_SSE200: r = s->initsvtor1; break; + case ARMSSE_SSE300: + goto bad_offset; default: g_assert_not_reached(); } @@ -358,8 +362,25 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset, s->gretreg = value; break; case A_INITSVTOR0: - s->initsvtor0 = value; - set_init_vtor(0, s->initsvtor0); + switch (s->sse_version) { + case ARMSSE_SSE300: + /* SSE300 has a LOCK bit which prevents further writes when set */ + if (s->initsvtor0 & R_INITSVTOR0_LOCK_MASK) { + qemu_log_mask(LOG_GUEST_ERROR, + "IoTKit INITSVTOR0 write when register locked\n"); + break; + } + s->initsvtor0 = value; + set_init_vtor(0, s->initsvtor0 & R_INITSVTOR0_VTOR_MASK); + break; + case ARMSSE_IOTKIT: + case ARMSSE_SSE200: + s->initsvtor0 = value; + set_init_vtor(0, s->initsvtor0); + break; + default: + g_assert_not_reached(); + } break; case A_CPUWAIT: switch (s->sse_version) { @@ -464,6 +485,8 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset, s->initsvtor1 = value; set_init_vtor(1, s->initsvtor1); break; + case ARMSSE_SSE300: + goto bad_offset; default: g_assert_not_reached(); } |