summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Maydell2021-02-19 15:45:48 +0100
committerPeter Maydell2021-03-08 18:20:02 +0100
commit246dbeb76319fdaa7030403ea0273617331f6a44 (patch)
tree52a9d7b8c2f174940d4327f57725476628affed9
parenthw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300 (diff)
downloadqemu-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.c27
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();
}