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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.