[PATCH v2 3/9] hw/misc/iotkit-sysctl.c: add SSE-310 support
Simon Xu <[email protected]> Wed, 5 Aug 2026 10:29:59 -0500
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> Reviewed-by: Robert Elliott <[email protected]> Signed-off-by: Simon Xu <[email protected]> --- 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