hw/misc/iotkit-sysctl: Handle CPU_WAIT, NMI_ENABLE for SSE-300
In the SSE-300 the CPU_WAIT and NMI_ENABLE registers have moved offsets, so they are now where the SSE-200's WICCTRL and EWCTRL were. The SSE-300 does not have WICCTLR or EWCTRL at all, and the old offsets are reserved: Offset SSE-200 SSE-300 ----------------------------------- 0x118 CPUWAIT reserved 0x118 NMI_ENABLE reserved 0x120 WICCTRL CPUWAIT 0x124 EWCTRL NMI_ENABLE Handle this reshuffle, and the fact that SSE-300 has only one CPU and so only one active bit in CPUWAIT. 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-15-peter.maydell@linaro.org
This commit is contained in:
parent
31b0c6b176
commit
92ecf2d5ee
@ -172,7 +172,17 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
|
||||
}
|
||||
break;
|
||||
case A_CPUWAIT:
|
||||
r = s->cpuwait;
|
||||
switch (s->sse_version) {
|
||||
case ARMSSE_IOTKIT:
|
||||
case ARMSSE_SSE200:
|
||||
r = s->cpuwait;
|
||||
break;
|
||||
case ARMSSE_SSE300:
|
||||
/* In SSE300 this is reserved (for INITSVTOR2) */
|
||||
goto bad_offset;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
break;
|
||||
case A_NMI_ENABLE:
|
||||
switch (s->sse_version) {
|
||||
@ -183,12 +193,26 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
|
||||
case ARMSSE_SSE200:
|
||||
r = s->nmi_enable;
|
||||
break;
|
||||
case ARMSSE_SSE300:
|
||||
/* In SSE300 this is reserved (for INITSVTOR3) */
|
||||
goto bad_offset;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
break;
|
||||
case A_WICCTRL:
|
||||
r = s->wicctrl;
|
||||
switch (s->sse_version) {
|
||||
case ARMSSE_IOTKIT:
|
||||
case ARMSSE_SSE200:
|
||||
r = s->wicctrl;
|
||||
break;
|
||||
case ARMSSE_SSE300:
|
||||
/* In SSE300 this offset is CPUWAIT */
|
||||
r = s->cpuwait;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
break;
|
||||
case A_EWCTRL:
|
||||
switch (s->sse_version) {
|
||||
@ -197,6 +221,10 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
|
||||
case ARMSSE_SSE200:
|
||||
r = s->ewctrl;
|
||||
break;
|
||||
case ARMSSE_SSE300:
|
||||
/* In SSE300 this offset is is NMI_ENABLE */
|
||||
r = s->nmi_enable;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
@ -279,6 +307,21 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
|
||||
return r;
|
||||
}
|
||||
|
||||
static void cpuwait_write(IoTKitSysCtl *s, uint32_t value)
|
||||
{
|
||||
int num_cpus = (s->sse_version == ARMSSE_SSE300) ? 1 : 2;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_cpus; i++) {
|
||||
uint32_t mask = 1 << i;
|
||||
if ((s->cpuwait & mask) && !(value & mask)) {
|
||||
/* Powering up CPU 0 */
|
||||
arm_set_cpu_on_and_reset(i);
|
||||
}
|
||||
}
|
||||
s->cpuwait = value;
|
||||
}
|
||||
|
||||
static void iotkit_sysctl_write(void *opaque, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
@ -319,19 +362,32 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
|
||||
set_init_vtor(0, s->initsvtor0);
|
||||
break;
|
||||
case A_CPUWAIT:
|
||||
if ((s->cpuwait & 1) && !(value & 1)) {
|
||||
/* Powering up CPU 0 */
|
||||
arm_set_cpu_on_and_reset(0);
|
||||
switch (s->sse_version) {
|
||||
case ARMSSE_IOTKIT:
|
||||
case ARMSSE_SSE200:
|
||||
cpuwait_write(s, value);
|
||||
break;
|
||||
case ARMSSE_SSE300:
|
||||
/* In SSE300 this is reserved (for INITSVTOR2) */
|
||||
goto bad_offset;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
if ((s->cpuwait & 2) && !(value & 2)) {
|
||||
/* Powering up CPU 1 */
|
||||
arm_set_cpu_on_and_reset(1);
|
||||
}
|
||||
s->cpuwait = value;
|
||||
break;
|
||||
case A_WICCTRL:
|
||||
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
|
||||
s->wicctrl = value;
|
||||
switch (s->sse_version) {
|
||||
case ARMSSE_IOTKIT:
|
||||
case ARMSSE_SSE200:
|
||||
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
|
||||
s->wicctrl = value;
|
||||
break;
|
||||
case ARMSSE_SSE300:
|
||||
/* In SSE300 this offset is CPUWAIT */
|
||||
cpuwait_write(s, value);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
break;
|
||||
case A_SECDBGSET:
|
||||
/* write-1-to-set */
|
||||
@ -420,6 +476,11 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
|
||||
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
|
||||
s->ewctrl = value;
|
||||
break;
|
||||
case ARMSSE_SSE300:
|
||||
/* In SSE300 this offset is is NMI_ENABLE */
|
||||
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
|
||||
s->nmi_enable = value;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
@ -499,6 +560,9 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
|
||||
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
|
||||
s->nmi_enable = value;
|
||||
break;
|
||||
case ARMSSE_SSE300:
|
||||
/* In SSE300 this is reserved (for INITSVTOR3) */
|
||||
goto bad_offset;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user