From: Simon Xu <simonxhy0404@gmail.com>
To: qemu-devel@nongnu.org
Cc: qemu-arm@nongnu.org, Owen Giles <owen.giles@hpe.com>,
Peter Maydell <peter.maydell@linaro.org>,
Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>,
Robert Elliott <elliott@hpe.com>,
Simon Xu <simonxhy0404@gmail.com>
Subject: [PATCH v2 3/9] hw/misc/iotkit-sysctl.c: add SSE-310 support
Date: Wed, 5 Aug 2026 10:29:59 -0500 [thread overview]
Message-ID: <20260805153005.9989-4-simonxhy0404@gmail.com> (raw)
In-Reply-To: <20260805153005.9989-1-simonxhy0404@gmail.com>
Add SSE-310 case statements for reads and writes.
Add new SSE-310 PIDR and CLIDR values.
Add new SSE-310 PPUINTSTAT register as RAZ with LOG_UMIMP on reads and
RO on writes.
Reviewed-by: Owen Giles <owen.giles@hpe.com>
Reviewed-by: Robert Elliott <elliott@hpe.com>
Signed-off-by: Simon Xu <simonxhy0404@gmail.com>
---
v1 -> v2
Add PPUINTSTAT register
Make sure comments don't separate case statements
---
hw/misc/iotkit-sysctl.c | 89 ++++++++++++++++++++++++++++++---
include/hw/misc/iotkit-sysctl.h | 1 +
2 files changed, 82 insertions(+), 8 deletions(-)
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
index dff89c677f..bdf59b5f85 100644
--- a/hw/misc/iotkit-sysctl.c
+++ b/hw/misc/iotkit-sysctl.c
@@ -51,6 +51,7 @@ REG32(CPUWAIT, 0x118)
REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
REG32(WICCTRL, 0x120)
REG32(EWCTRL, 0x124)
+REG32(PPUINTSTAT, 0x128)
REG32(PWRCTRL, 0x1fc)
FIELD(PWRCTRL, PPU_ACCESS_UNLOCK, 0, 1)
FIELD(PWRCTRL, PPU_ACCESS_FILTER, 1, 1)
@@ -87,6 +88,12 @@ static const int sse200_sysctl_id[] = {
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
};
+static const int sse310_sysctl_id[] = {
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+ 0x54, 0xb8, 0x4b, 0x00, /* PID0..PID3 */
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
/*
* Set the initial secure vector table offset address for the core.
* This will take effect when the CPU next resets.
@@ -118,6 +125,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
r = s->scsecctrl;
break;
default:
@@ -130,6 +138,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
r = s->fclk_div;
break;
default:
@@ -142,6 +151,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
r = s->sysclk_div;
break;
default:
@@ -154,6 +164,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
r = s->clock_force;
break;
default:
@@ -180,6 +191,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
r = s->initsvtor1;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
goto bad_offset;
default:
g_assert_not_reached();
@@ -192,6 +204,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
r = s->cpuwait;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
/* In SSE300 this is reserved (for INITSVTOR2) */
goto bad_offset;
default:
@@ -208,6 +221,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
r = s->nmi_enable;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
/* In SSE300 this is reserved (for INITSVTOR3) */
goto bad_offset;
default:
@@ -221,7 +235,8 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
r = s->wicctrl;
break;
case ARMSSE_SSE300:
- /* In SSE300 this offset is CPUWAIT */
+ case ARMSSE_SSE310:
+ /* In SSE300 and SSE310 this offset is CPUWAIT */
r = s->cpuwait;
break;
default:
@@ -236,19 +251,36 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
r = s->ewctrl;
break;
case ARMSSE_SSE300:
- /* In SSE300 this offset is NMI_ENABLE */
+ case ARMSSE_SSE310:
+ /* In SSE300 and SSE310 this offset is NMI_ENABLE */
r = s->nmi_enable;
break;
default:
g_assert_not_reached();
}
break;
+ case A_PPUINTSTAT:
+ switch (s->sse_version) {
+ case ARMSSE_IOTKIT:
+ case ARMSSE_SSE200:
+ case ARMSSE_SSE300:
+ goto bad_offset;
+ case ARMSSE_SSE310:
+ qemu_log_mask(LOG_UNIMP,
+ "IoTKit SysCtl PPUINTSTAT unimplemented\n");
+ r = s->ppuintstat;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ break;
case A_PWRCTRL:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
case ARMSSE_SSE200:
goto bad_offset;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
r = s->pwrctrl;
break;
default:
@@ -261,6 +293,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
r = s->pdcm_pd_sys_sense;
break;
default:
@@ -273,7 +306,8 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
case ARMSSE_SSE200:
goto bad_offset;
case ARMSSE_SSE300:
- r = s->pdcm_pd_cpu0_sense;
+ case ARMSSE_SSE310:
+ r = s->pdcm_pd_cpu0_sense;
break;
default:
g_assert_not_reached();
@@ -287,6 +321,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
r = s->pdcm_pd_sram0_sense;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
goto bad_offset;
default:
g_assert_not_reached();
@@ -300,6 +335,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
r = s->pdcm_pd_sram1_sense;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
goto bad_offset;
default:
g_assert_not_reached();
@@ -313,6 +349,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
r = s->pdcm_pd_sram2_sense;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
r = s->pdcm_pd_vmr0_sense;
break;
default:
@@ -327,6 +364,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
r = s->pdcm_pd_sram3_sense;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
r = s->pdcm_pd_vmr1_sense;
break;
default:
@@ -342,6 +380,9 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
case ARMSSE_SSE300:
r = sse200_sysctl_id[(offset - A_PID4) / 4];
break;
+ case ARMSSE_SSE310:
+ r = sse310_sysctl_id[(offset - A_PID4) / 4];
+ break;
default:
g_assert_not_reached();
}
@@ -367,7 +408,8 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
static void cpuwait_write(IoTKitSysCtl *s, uint32_t value)
{
- int num_cpus = (s->sse_version == ARMSSE_SSE300) ? 1 : 2;
+ int num_cpus = (s->sse_version == ARMSSE_SSE300 ||
+ s->sse_version == ARMSSE_SSE310) ? 1 : 2;
int i;
for (i = 0; i < num_cpus; i++) {
@@ -418,7 +460,8 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
case A_INITSVTOR0:
switch (s->sse_version) {
case ARMSSE_SSE300:
- /* SSE300 has a LOCK bit which prevents further writes when set */
+ case ARMSSE_SSE310:
+ /* SSE300 and SSE310 have a LOCK bit which prevents further writes */
if (s->initsvtor0 & R_INITSVTOR0_LOCK_MASK) {
qemu_log_mask(LOG_GUEST_ERROR,
"IoTKit INITSVTOR0 write when register locked\n");
@@ -443,6 +486,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
cpuwait_write(s, value);
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
/* In SSE300 this is reserved (for INITSVTOR2) */
goto bad_offset;
default:
@@ -457,7 +501,8 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
s->wicctrl = value;
break;
case ARMSSE_SSE300:
- /* In SSE300 this offset is CPUWAIT */
+ case ARMSSE_SSE310:
+ /* In SSE300 and SSE310 this offset is CPUWAIT */
cpuwait_write(s, value);
break;
default:
@@ -485,6 +530,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
s->scsecctrl = value;
break;
@@ -498,6 +544,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
s->fclk_div = value;
break;
@@ -511,6 +558,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
s->sysclk_div = value;
break;
@@ -524,6 +572,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
s->clock_force = value;
break;
@@ -540,6 +589,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
set_init_vtor(1, s->initsvtor1);
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
goto bad_offset;
default:
g_assert_not_reached();
@@ -554,7 +604,8 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
s->ewctrl = value;
break;
case ARMSSE_SSE300:
- /* In SSE300 this offset is NMI_ENABLE */
+ case ARMSSE_SSE310:
+ /* In SSE300 and SSE310 this offset is NMI_ENABLE */
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
s->nmi_enable = value;
break;
@@ -562,12 +613,25 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
g_assert_not_reached();
}
break;
+ case A_PPUINTSTAT:
+ switch (s->sse_version) {
+ case ARMSSE_IOTKIT:
+ case ARMSSE_SSE200:
+ case ARMSSE_SSE300:
+ goto bad_offset;
+ case ARMSSE_SSE310:
+ goto ro_offset;
+ default:
+ g_assert_not_reached();
+ }
+ break;
case A_PWRCTRL:
switch (s->sse_version) {
case ARMSSE_IOTKIT:
case ARMSSE_SSE200:
goto bad_offset;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
if (!(s->pwrctrl & R_PWRCTRL_PPU_ACCESS_UNLOCK_MASK)) {
qemu_log_mask(LOG_GUEST_ERROR,
"IoTKit PWRCTRL write when register locked\n");
@@ -585,6 +649,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
goto bad_offset;
case ARMSSE_SSE200:
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
s->pdcm_pd_sys_sense = value;
@@ -599,6 +664,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
case ARMSSE_SSE200:
goto bad_offset;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_CPU0_SENSE unimplemented\n");
s->pdcm_pd_cpu0_sense = value;
@@ -617,6 +683,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
s->pdcm_pd_sram0_sense = value;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
goto bad_offset;
default:
g_assert_not_reached();
@@ -632,6 +699,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
s->pdcm_pd_sram1_sense = value;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
goto bad_offset;
default:
g_assert_not_reached();
@@ -647,6 +715,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
s->pdcm_pd_sram2_sense = value;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_VMR0_SENSE unimplemented\n");
s->pdcm_pd_vmr0_sense = value;
@@ -665,6 +734,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
s->pdcm_pd_sram3_sense = value;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
qemu_log_mask(LOG_UNIMP,
"IoTKit SysCtl PDCM_PD_VMR1_SENSE unimplemented\n");
s->pdcm_pd_vmr1_sense = value;
@@ -683,6 +753,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
s->nmi_enable = value;
break;
case ARMSSE_SSE300:
+ case ARMSSE_SSE310:
/* In SSE300 this is reserved (for INITSVTOR3) */
goto bad_offset;
default:
@@ -734,6 +805,7 @@ static void iotkit_sysctl_reset(DeviceState *dev)
s->clock_force = 0;
s->nmi_enable = 0;
s->ewctrl = 0;
+ s->ppuintstat = 0;
s->pwrctrl = 0x3;
s->pdcm_pd_sys_sense = 0x7f;
s->pdcm_pd_sram0_sense = 0;
@@ -769,7 +841,8 @@ static bool sse300_needed(void *opaque)
{
IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
- return s->sse_version == ARMSSE_SSE300;
+ return s->sse_version == ARMSSE_SSE300 ||
+ s->sse_version == ARMSSE_SSE310;
}
static const VMStateDescription iotkit_sysctl_sse300_vmstate = {
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
index ce72258a84..8e1cf0012d 100644
--- a/include/hw/misc/iotkit-sysctl.h
+++ b/include/hw/misc/iotkit-sysctl.h
@@ -53,6 +53,7 @@ struct IoTKitSysCtl {
uint32_t initsvtor1;
uint32_t nmi_enable;
uint32_t ewctrl;
+ uint32_t ppuintstat;
uint32_t pwrctrl;
uint32_t pdcm_pd_sys_sense;
uint32_t pdcm_pd_sram0_sense;
--
2.53.0
next prev parent reply other threads:[~2026-08-05 15:30 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-05 15:29 [PATCH v2 0/9] arm: add Cortex-M85, SSE-310, and mps3-an555 Simon Xu
2026-08-05 15:29 ` [PATCH v2 1/9] target/arm/tcg/cpu-v7m.c: add cortex-m85 model Simon Xu
2026-08-05 15:29 ` [PATCH v2 2/9] hw/arm/armsse: add Arm Corstone SSE-310 Simon Xu
2026-08-17 15:23 ` Peter Maydell
2026-08-05 15:29 ` Simon Xu [this message]
2026-08-17 15:30 ` [PATCH v2 3/9] hw/misc/iotkit-sysctl.c: add SSE-310 support Peter Maydell
2026-08-05 15:30 ` [PATCH v2 4/9] hw/misc/iotkit-secctl.c: fix AHB secure read Simon Xu
2026-08-17 15:33 ` Peter Maydell
2026-08-05 15:30 ` [PATCH v2 5/9] hw/misc/iotkit-secctl.c: add SSE-310 support Simon Xu
2026-08-17 15:34 ` Peter Maydell
2026-08-05 15:30 ` [PATCH v2 6/9] hw/misc/iotkit-secctl.c: use GNU C case ranges Simon Xu
2026-08-17 15:38 ` Peter Maydell
2026-08-05 15:30 ` [PATCH v2 7/9] hw/misc/iotkit-sysinfo.c: add SSE-310 support Simon Xu
2026-08-17 15:38 ` Peter Maydell
2026-08-05 15:30 ` [PATCH v2 8/9] hw/arm/mps2-tz.c add Arm mps3-an555 board Simon Xu
2026-08-17 15:50 ` Peter Maydell
2026-08-05 15:30 ` [PATCH v2 9/9] hw/misc/mps2-fpgaio.c: add GPIOALT2 register Simon Xu
2026-08-17 15:49 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260805153005.9989-4-simonxhy0404@gmail.com \
--to=simonxhy0404@gmail.com \
--cc=elliott@hpe.com \
--cc=owen.giles@hpe.com \
--cc=peter.maydell@linaro.org \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox