@samitouri / QOSamiQemu / commits / 399ab98d0a

hw/misc/iotkit-sysctl.c: add SSE-310 support

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> Message-Id: <20260805153005.9989-4-simonxhy0404@gmail.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Simon Xu committed Aug 17, 2026 at 19:26 UTC 399ab98d0a37907ae2e2db095bf4d780a4a2747f
1 file changed +79 -7
hw/misc/iotkit-sysctl.c
+79 -7
@@ -51,6 +51,7 @@ REG32(CPUWAIT, 0x118)
51 REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
52 REG32(WICCTRL, 0x120)
53 REG32(EWCTRL, 0x124)
54 +REG32(PPUINTSTAT, 0x128)
55 REG32(PWRCTRL, 0x1fc)
56 FIELD(PWRCTRL, PPU_ACCESS_UNLOCK, 0, 1)
57 FIELD(PWRCTRL, PPU_ACCESS_FILTER, 1, 1)
@@ -87,6 +88,12 @@ static const int sse200_sysctl_id[] = {
88 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
89 };
90
91 +static const int sse310_sysctl_id[] = {
92 + 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
93 + 0x54, 0xb8, 0x4b, 0x00, /* PID0..PID3 */
94 + 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
95 +};
96 +
97 /*
98 * Set the initial secure vector table offset address for the core.
99 * This will take effect when the CPU next resets.
@@ -118,6 +125,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
125 goto bad_offset;
126 case ARMSSE_SSE200:
127 case ARMSSE_SSE300:
128 + case ARMSSE_SSE310:
129 r = s->scsecctrl;
130 break;
131 default:
@@ -130,6 +138,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
138 goto bad_offset;
139 case ARMSSE_SSE200:
140 case ARMSSE_SSE300:
141 + case ARMSSE_SSE310:
142 r = s->fclk_div;
143 break;
144 default:
@@ -142,6 +151,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
151 goto bad_offset;
152 case ARMSSE_SSE200:
153 case ARMSSE_SSE300:
154 + case ARMSSE_SSE310:
155 r = s->sysclk_div;
156 break;
157 default:
@@ -154,6 +164,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
164 goto bad_offset;
165 case ARMSSE_SSE200:
166 case ARMSSE_SSE300:
167 + case ARMSSE_SSE310:
168 r = s->clock_force;
169 break;
170 default:
@@ -180,6 +191,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
191 r = s->initsvtor1;
192 break;
193 case ARMSSE_SSE300:
194 + case ARMSSE_SSE310:
195 goto bad_offset;
196 default:
197 g_assert_not_reached();
@@ -192,6 +204,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
204 r = s->cpuwait;
205 break;
206 case ARMSSE_SSE300:
207 + case ARMSSE_SSE310:
208 /* In SSE300 this is reserved (for INITSVTOR2) */
209 goto bad_offset;
210 default:
@@ -208,6 +221,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
221 r = s->nmi_enable;
222 break;
223 case ARMSSE_SSE300:
224 + case ARMSSE_SSE310:
225 /* In SSE300 this is reserved (for INITSVTOR3) */
226 goto bad_offset;
227 default:
@@ -221,7 +235,8 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
235 r = s->wicctrl;
236 break;
237 case ARMSSE_SSE300:
224 - /* In SSE300 this offset is CPUWAIT */
238 + case ARMSSE_SSE310:
239 + /* In SSE300 and SSE310 this offset is CPUWAIT */
240 r = s->cpuwait;
241 break;
242 default:
@@ -236,19 +251,36 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
251 r = s->ewctrl;
252 break;
253 case ARMSSE_SSE300:
239 - /* In SSE300 this offset is NMI_ENABLE */
254 + case ARMSSE_SSE310:
255 + /* In SSE300 and SSE310 this offset is NMI_ENABLE */
256 r = s->nmi_enable;
257 break;
258 default:
259 g_assert_not_reached();
260 }
261 break;
262 + case A_PPUINTSTAT:
263 + switch (s->sse_version) {
264 + case ARMSSE_IOTKIT:
265 + case ARMSSE_SSE200:
266 + case ARMSSE_SSE300:
267 + goto bad_offset;
268 + case ARMSSE_SSE310:
269 + qemu_log_mask(LOG_UNIMP,
270 + "IoTKit SysCtl PPUINTSTAT unimplemented\n");
271 + r = 0;
272 + break;
273 + default:
274 + g_assert_not_reached();
275 + }
276 + break;
277 case A_PWRCTRL:
278 switch (s->sse_version) {
279 case ARMSSE_IOTKIT:
280 case ARMSSE_SSE200:
281 goto bad_offset;
282 case ARMSSE_SSE300:
283 + case ARMSSE_SSE310:
284 r = s->pwrctrl;
285 break;
286 default:
@@ -261,6 +293,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
293 goto bad_offset;
294 case ARMSSE_SSE200:
295 case ARMSSE_SSE300:
296 + case ARMSSE_SSE310:
297 r = s->pdcm_pd_sys_sense;
298 break;
299 default:
@@ -273,6 +306,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
306 case ARMSSE_SSE200:
307 goto bad_offset;
308 case ARMSSE_SSE300:
309 + case ARMSSE_SSE310:
310 r = s->pdcm_pd_cpu0_sense;
311 break;
312 default:
@@ -287,6 +321,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
321 r = s->pdcm_pd_sram0_sense;
322 break;
323 case ARMSSE_SSE300:
324 + case ARMSSE_SSE310:
325 goto bad_offset;
326 default:
327 g_assert_not_reached();
@@ -300,6 +335,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
335 r = s->pdcm_pd_sram1_sense;
336 break;
337 case ARMSSE_SSE300:
338 + case ARMSSE_SSE310:
339 goto bad_offset;
340 default:
341 g_assert_not_reached();
@@ -313,6 +349,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
349 r = s->pdcm_pd_sram2_sense;
350 break;
351 case ARMSSE_SSE300:
352 + case ARMSSE_SSE310:
353 r = s->pdcm_pd_vmr0_sense;
354 break;
355 default:
@@ -327,6 +364,7 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
364 r = s->pdcm_pd_sram3_sense;
365 break;
366 case ARMSSE_SSE300:
367 + case ARMSSE_SSE310:
368 r = s->pdcm_pd_vmr1_sense;
369 break;
370 default:
@@ -342,6 +380,9 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
380 case ARMSSE_SSE300:
381 r = sse200_sysctl_id[(offset - A_PID4) / 4];
382 break;
383 + case ARMSSE_SSE310:
384 + r = sse310_sysctl_id[(offset - A_PID4) / 4];
385 + break;
386 default:
387 g_assert_not_reached();
388 }
@@ -367,7 +408,8 @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
408
409 static void cpuwait_write(IoTKitSysCtl *s, uint32_t value)
410 {
370 - int num_cpus = (s->sse_version == ARMSSE_SSE300) ? 1 : 2;
411 + int num_cpus = (s->sse_version == ARMSSE_SSE300 ||
412 + s->sse_version == ARMSSE_SSE310) ? 1 : 2;
413 int i;
414
415 for (i = 0; i < num_cpus; i++) {
@@ -418,7 +460,8 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
460 case A_INITSVTOR0:
461 switch (s->sse_version) {
462 case ARMSSE_SSE300:
421 - /* SSE300 has a LOCK bit which prevents further writes when set */
463 + case ARMSSE_SSE310:
464 + /* SSE300, SSE310 have a LOCK bit which prevents further writes */
465 if (s->initsvtor0 & R_INITSVTOR0_LOCK_MASK) {
466 qemu_log_mask(LOG_GUEST_ERROR,
467 "IoTKit INITSVTOR0 write when register locked\n");
@@ -443,6 +486,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
486 cpuwait_write(s, value);
487 break;
488 case ARMSSE_SSE300:
489 + case ARMSSE_SSE310:
490 /* In SSE300 this is reserved (for INITSVTOR2) */
491 goto bad_offset;
492 default:
@@ -457,7 +501,8 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
501 s->wicctrl = value;
502 break;
503 case ARMSSE_SSE300:
460 - /* In SSE300 this offset is CPUWAIT */
504 + case ARMSSE_SSE310:
505 + /* In SSE300 and SSE310 this offset is CPUWAIT */
506 cpuwait_write(s, value);
507 break;
508 default:
@@ -485,6 +530,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
530 goto bad_offset;
531 case ARMSSE_SSE200:
532 case ARMSSE_SSE300:
533 + case ARMSSE_SSE310:
534 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
535 s->scsecctrl = value;
536 break;
@@ -498,6 +544,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
544 goto bad_offset;
545 case ARMSSE_SSE200:
546 case ARMSSE_SSE300:
547 + case ARMSSE_SSE310:
548 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
549 s->fclk_div = value;
550 break;
@@ -511,6 +558,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
558 goto bad_offset;
559 case ARMSSE_SSE200:
560 case ARMSSE_SSE300:
561 + case ARMSSE_SSE310:
562 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
563 s->sysclk_div = value;
564 break;
@@ -524,6 +572,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
572 goto bad_offset;
573 case ARMSSE_SSE200:
574 case ARMSSE_SSE300:
575 + case ARMSSE_SSE310:
576 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
577 s->clock_force = value;
578 break;
@@ -540,6 +589,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
589 set_init_vtor(1, s->initsvtor1);
590 break;
591 case ARMSSE_SSE300:
592 + case ARMSSE_SSE310:
593 goto bad_offset;
594 default:
595 g_assert_not_reached();
@@ -554,7 +604,8 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
604 s->ewctrl = value;
605 break;
606 case ARMSSE_SSE300:
557 - /* In SSE300 this offset is NMI_ENABLE */
607 + case ARMSSE_SSE310:
608 + /* In SSE300 and SSE310 this offset is NMI_ENABLE */
609 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
610 s->nmi_enable = value;
611 break;
@@ -562,12 +613,25 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
613 g_assert_not_reached();
614 }
615 break;
616 + case A_PPUINTSTAT:
617 + switch (s->sse_version) {
618 + case ARMSSE_IOTKIT:
619 + case ARMSSE_SSE200:
620 + case ARMSSE_SSE300:
621 + goto bad_offset;
622 + case ARMSSE_SSE310:
623 + goto ro_offset;
624 + default:
625 + g_assert_not_reached();
626 + }
627 + break;
628 case A_PWRCTRL:
629 switch (s->sse_version) {
630 case ARMSSE_IOTKIT:
631 case ARMSSE_SSE200:
632 goto bad_offset;
633 case ARMSSE_SSE300:
634 + case ARMSSE_SSE310:
635 if (!(s->pwrctrl & R_PWRCTRL_PPU_ACCESS_UNLOCK_MASK)) {
636 qemu_log_mask(LOG_GUEST_ERROR,
637 "IoTKit PWRCTRL write when register locked\n");
@@ -585,6 +649,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
649 goto bad_offset;
650 case ARMSSE_SSE200:
651 case ARMSSE_SSE300:
652 + case ARMSSE_SSE310:
653 qemu_log_mask(LOG_UNIMP,
654 "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
655 s->pdcm_pd_sys_sense = value;
@@ -599,6 +664,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
664 case ARMSSE_SSE200:
665 goto bad_offset;
666 case ARMSSE_SSE300:
667 + case ARMSSE_SSE310:
668 qemu_log_mask(LOG_UNIMP,
669 "IoTKit SysCtl PDCM_PD_CPU0_SENSE unimplemented\n");
670 s->pdcm_pd_cpu0_sense = value;
@@ -617,6 +683,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
683 s->pdcm_pd_sram0_sense = value;
684 break;
685 case ARMSSE_SSE300:
686 + case ARMSSE_SSE310:
687 goto bad_offset;
688 default:
689 g_assert_not_reached();
@@ -632,6 +699,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
699 s->pdcm_pd_sram1_sense = value;
700 break;
701 case ARMSSE_SSE300:
702 + case ARMSSE_SSE310:
703 goto bad_offset;
704 default:
705 g_assert_not_reached();
@@ -647,6 +715,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
715 s->pdcm_pd_sram2_sense = value;
716 break;
717 case ARMSSE_SSE300:
718 + case ARMSSE_SSE310:
719 qemu_log_mask(LOG_UNIMP,
720 "IoTKit SysCtl PDCM_PD_VMR0_SENSE unimplemented\n");
721 s->pdcm_pd_vmr0_sense = value;
@@ -665,6 +734,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
734 s->pdcm_pd_sram3_sense = value;
735 break;
736 case ARMSSE_SSE300:
737 + case ARMSSE_SSE310:
738 qemu_log_mask(LOG_UNIMP,
739 "IoTKit SysCtl PDCM_PD_VMR1_SENSE unimplemented\n");
740 s->pdcm_pd_vmr1_sense = value;
@@ -683,6 +753,7 @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
753 s->nmi_enable = value;
754 break;
755 case ARMSSE_SSE300:
756 + case ARMSSE_SSE310:
757 /* In SSE300 this is reserved (for INITSVTOR3) */
758 goto bad_offset;
759 default:
@@ -769,7 +840,8 @@ static bool sse300_needed(void *opaque)
840 {
841 IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
842
772 - return s->sse_version == ARMSSE_SSE300;
843 + return s->sse_version == ARMSSE_SSE300 ||
844 + s->sse_version == ARMSSE_SSE310;
845 }
846
847 static const VMStateDescription iotkit_sysctl_sse300_vmstate = {