xref: /qemu/hw/misc/iotkit-sysctl.c (revision 06b40d250ecfa1633209c2e431a7a38acfd03a98)
175750e4dSPeter Maydell /*
275750e4dSPeter Maydell  * ARM IoTKit system control element
375750e4dSPeter Maydell  *
475750e4dSPeter Maydell  * Copyright (c) 2018 Linaro Limited
575750e4dSPeter Maydell  * Written by Peter Maydell
675750e4dSPeter Maydell  *
775750e4dSPeter Maydell  *  This program is free software; you can redistribute it and/or modify
875750e4dSPeter Maydell  *  it under the terms of the GNU General Public License version 2 or
975750e4dSPeter Maydell  *  (at your option) any later version.
1075750e4dSPeter Maydell  */
1175750e4dSPeter Maydell 
1275750e4dSPeter Maydell /*
1375750e4dSPeter Maydell  * This is a model of the "system control element" which is part of the
1475750e4dSPeter Maydell  * Arm IoTKit and documented in
1550b52b18SPeter Maydell  * https://developer.arm.com/documentation/ecm0601256/latest
1675750e4dSPeter Maydell  * Specifically, it implements the "system control register" blocks.
1775750e4dSPeter Maydell  */
1875750e4dSPeter Maydell 
1975750e4dSPeter Maydell #include "qemu/osdep.h"
2004836414SPeter Maydell #include "qemu/bitops.h"
2175750e4dSPeter Maydell #include "qemu/log.h"
220b8fa32fSMarkus Armbruster #include "qemu/module.h"
2332cad1ffSPhilippe Mathieu-Daudé #include "system/runstate.h"
2475750e4dSPeter Maydell #include "trace.h"
2575750e4dSPeter Maydell #include "qapi/error.h"
2675750e4dSPeter Maydell #include "hw/sysbus.h"
27d6454270SMarkus Armbruster #include "migration/vmstate.h"
2875750e4dSPeter Maydell #include "hw/registerfields.h"
2975750e4dSPeter Maydell #include "hw/misc/iotkit-sysctl.h"
30a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
31419a7f80SPeter Maydell #include "hw/arm/armsse-version.h"
320f862986SPeter Maydell #include "target/arm/arm-powerctl.h"
3375750e4dSPeter Maydell 
3475750e4dSPeter Maydell REG32(SECDBGSTAT, 0x0)
3575750e4dSPeter Maydell REG32(SECDBGSET, 0x4)
3675750e4dSPeter Maydell REG32(SECDBGCLR, 0x8)
3704836414SPeter Maydell REG32(SCSECCTRL, 0xc)
3804836414SPeter Maydell REG32(FCLK_DIV, 0x10)
3904836414SPeter Maydell REG32(SYSCLK_DIV, 0x14)
4004836414SPeter Maydell REG32(CLOCK_FORCE, 0x18)
4175750e4dSPeter Maydell REG32(RESET_SYNDROME, 0x100)
4275750e4dSPeter Maydell REG32(RESET_MASK, 0x104)
4375750e4dSPeter Maydell REG32(SWRESET, 0x108)
4475750e4dSPeter Maydell     FIELD(SWRESET, SWRESETREQ, 9, 1)
4575750e4dSPeter Maydell REG32(GRETREG, 0x10c)
46394e10d2SPeter Maydell REG32(INITSVTOR0, 0x110)
47246dbeb7SPeter Maydell     FIELD(INITSVTOR0, LOCK, 0, 1)
48246dbeb7SPeter Maydell     FIELD(INITSVTOR0, VTOR, 7, 25)
4904836414SPeter Maydell REG32(INITSVTOR1, 0x114)
5075750e4dSPeter Maydell REG32(CPUWAIT, 0x118)
5104836414SPeter Maydell REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
5275750e4dSPeter Maydell REG32(WICCTRL, 0x120)
5304836414SPeter Maydell REG32(EWCTRL, 0x124)
542672a6caSPeter Maydell REG32(PWRCTRL, 0x1fc)
552672a6caSPeter Maydell     FIELD(PWRCTRL, PPU_ACCESS_UNLOCK, 0, 1)
562672a6caSPeter Maydell     FIELD(PWRCTRL, PPU_ACCESS_FILTER, 1, 1)
5704836414SPeter Maydell REG32(PDCM_PD_SYS_SENSE, 0x200)
58c5ffe6c8SPeter Maydell REG32(PDCM_PD_CPU0_SENSE, 0x204)
5904836414SPeter Maydell REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
6004836414SPeter Maydell REG32(PDCM_PD_SRAM1_SENSE, 0x210)
61c5ffe6c8SPeter Maydell REG32(PDCM_PD_SRAM2_SENSE, 0x214) /* PDCM_PD_VMR0_SENSE on SSE300 */
62c5ffe6c8SPeter Maydell REG32(PDCM_PD_SRAM3_SENSE, 0x218) /* PDCM_PD_VMR1_SENSE on SSE300 */
6375750e4dSPeter Maydell REG32(PID4, 0xfd0)
6475750e4dSPeter Maydell REG32(PID5, 0xfd4)
6575750e4dSPeter Maydell REG32(PID6, 0xfd8)
6675750e4dSPeter Maydell REG32(PID7, 0xfdc)
6775750e4dSPeter Maydell REG32(PID0, 0xfe0)
6875750e4dSPeter Maydell REG32(PID1, 0xfe4)
6975750e4dSPeter Maydell REG32(PID2, 0xfe8)
7075750e4dSPeter Maydell REG32(PID3, 0xfec)
7175750e4dSPeter Maydell REG32(CID0, 0xff0)
7275750e4dSPeter Maydell REG32(CID1, 0xff4)
7375750e4dSPeter Maydell REG32(CID2, 0xff8)
7475750e4dSPeter Maydell REG32(CID3, 0xffc)
7575750e4dSPeter Maydell 
7675750e4dSPeter Maydell /* PID/CID values */
776069bbc9SPeter Maydell static const int iotkit_sysctl_id[] = {
7875750e4dSPeter Maydell     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
7975750e4dSPeter Maydell     0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
8075750e4dSPeter Maydell     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
8175750e4dSPeter Maydell };
8275750e4dSPeter Maydell 
836069bbc9SPeter Maydell /* Also used by the SSE300 */
846069bbc9SPeter Maydell static const int sse200_sysctl_id[] = {
856069bbc9SPeter Maydell     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
866069bbc9SPeter Maydell     0x54, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
876069bbc9SPeter Maydell     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
886069bbc9SPeter Maydell };
896069bbc9SPeter Maydell 
900f862986SPeter Maydell /*
910f862986SPeter Maydell  * Set the initial secure vector table offset address for the core.
920f862986SPeter Maydell  * This will take effect when the CPU next resets.
930f862986SPeter Maydell  */
set_init_vtor(uint64_t cpuid,uint32_t vtor)940f862986SPeter Maydell static void set_init_vtor(uint64_t cpuid, uint32_t vtor)
950f862986SPeter Maydell {
960f862986SPeter Maydell     Object *cpuobj = OBJECT(arm_get_cpu_by_id(cpuid));
970f862986SPeter Maydell 
980f862986SPeter Maydell     if (cpuobj) {
99efba1595SDaniel P. Berrangé         if (object_property_find(cpuobj, "init-svtor")) {
1005325cc34SMarkus Armbruster             object_property_set_uint(cpuobj, "init-svtor", vtor, &error_abort);
1010f862986SPeter Maydell         }
1020f862986SPeter Maydell     }
1030f862986SPeter Maydell }
1040f862986SPeter Maydell 
iotkit_sysctl_read(void * opaque,hwaddr offset,unsigned size)10575750e4dSPeter Maydell static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
10675750e4dSPeter Maydell                                     unsigned size)
10775750e4dSPeter Maydell {
10875750e4dSPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
10975750e4dSPeter Maydell     uint64_t r;
11075750e4dSPeter Maydell 
11175750e4dSPeter Maydell     switch (offset) {
11275750e4dSPeter Maydell     case A_SECDBGSTAT:
11375750e4dSPeter Maydell         r = s->secure_debug;
11475750e4dSPeter Maydell         break;
11504836414SPeter Maydell     case A_SCSECCTRL:
1161cbd6fe4SPeter Maydell         switch (s->sse_version) {
1171cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
11804836414SPeter Maydell             goto bad_offset;
1191cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
12031b0c6b1SPeter Maydell         case ARMSSE_SSE300:
12104836414SPeter Maydell             r = s->scsecctrl;
12204836414SPeter Maydell             break;
1231cbd6fe4SPeter Maydell         default:
1241cbd6fe4SPeter Maydell             g_assert_not_reached();
12504836414SPeter Maydell         }
1261cbd6fe4SPeter Maydell         break;
1271cbd6fe4SPeter Maydell     case A_FCLK_DIV:
1281cbd6fe4SPeter Maydell         switch (s->sse_version) {
1291cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
1301cbd6fe4SPeter Maydell             goto bad_offset;
1311cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
13231b0c6b1SPeter Maydell         case ARMSSE_SSE300:
13304836414SPeter Maydell             r = s->fclk_div;
13404836414SPeter Maydell             break;
1351cbd6fe4SPeter Maydell         default:
1361cbd6fe4SPeter Maydell             g_assert_not_reached();
13704836414SPeter Maydell         }
1381cbd6fe4SPeter Maydell         break;
1391cbd6fe4SPeter Maydell     case A_SYSCLK_DIV:
1401cbd6fe4SPeter Maydell         switch (s->sse_version) {
1411cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
1421cbd6fe4SPeter Maydell             goto bad_offset;
1431cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
14431b0c6b1SPeter Maydell         case ARMSSE_SSE300:
14504836414SPeter Maydell             r = s->sysclk_div;
14604836414SPeter Maydell             break;
1471cbd6fe4SPeter Maydell         default:
1481cbd6fe4SPeter Maydell             g_assert_not_reached();
14904836414SPeter Maydell         }
1501cbd6fe4SPeter Maydell         break;
1511cbd6fe4SPeter Maydell     case A_CLOCK_FORCE:
1521cbd6fe4SPeter Maydell         switch (s->sse_version) {
1531cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
1541cbd6fe4SPeter Maydell             goto bad_offset;
1551cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
15631b0c6b1SPeter Maydell         case ARMSSE_SSE300:
15704836414SPeter Maydell             r = s->clock_force;
15804836414SPeter Maydell             break;
1591cbd6fe4SPeter Maydell         default:
1601cbd6fe4SPeter Maydell             g_assert_not_reached();
1611cbd6fe4SPeter Maydell         }
1621cbd6fe4SPeter Maydell         break;
16375750e4dSPeter Maydell     case A_RESET_SYNDROME:
16475750e4dSPeter Maydell         r = s->reset_syndrome;
16575750e4dSPeter Maydell         break;
16675750e4dSPeter Maydell     case A_RESET_MASK:
16775750e4dSPeter Maydell         r = s->reset_mask;
16875750e4dSPeter Maydell         break;
16975750e4dSPeter Maydell     case A_GRETREG:
17075750e4dSPeter Maydell         r = s->gretreg;
17175750e4dSPeter Maydell         break;
172394e10d2SPeter Maydell     case A_INITSVTOR0:
173394e10d2SPeter Maydell         r = s->initsvtor0;
17475750e4dSPeter Maydell         break;
17504836414SPeter Maydell     case A_INITSVTOR1:
1761cbd6fe4SPeter Maydell         switch (s->sse_version) {
1771cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
17804836414SPeter Maydell             goto bad_offset;
1791cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
18004836414SPeter Maydell             r = s->initsvtor1;
18104836414SPeter Maydell             break;
182246dbeb7SPeter Maydell         case ARMSSE_SSE300:
183246dbeb7SPeter Maydell             goto bad_offset;
1841cbd6fe4SPeter Maydell         default:
1851cbd6fe4SPeter Maydell             g_assert_not_reached();
1861cbd6fe4SPeter Maydell         }
1871cbd6fe4SPeter Maydell         break;
18875750e4dSPeter Maydell     case A_CPUWAIT:
18992ecf2d5SPeter Maydell         switch (s->sse_version) {
19092ecf2d5SPeter Maydell         case ARMSSE_IOTKIT:
19192ecf2d5SPeter Maydell         case ARMSSE_SSE200:
19275750e4dSPeter Maydell             r = s->cpuwait;
19375750e4dSPeter Maydell             break;
19492ecf2d5SPeter Maydell         case ARMSSE_SSE300:
19592ecf2d5SPeter Maydell             /* In SSE300 this is reserved (for INITSVTOR2) */
19692ecf2d5SPeter Maydell             goto bad_offset;
19792ecf2d5SPeter Maydell         default:
19892ecf2d5SPeter Maydell             g_assert_not_reached();
19992ecf2d5SPeter Maydell         }
20092ecf2d5SPeter Maydell         break;
20104836414SPeter Maydell     case A_NMI_ENABLE:
2021cbd6fe4SPeter Maydell         switch (s->sse_version) {
2031cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
2041cbd6fe4SPeter Maydell             /* In IoTKit this is named BUSWAIT but marked reserved, R/O, zero */
20575750e4dSPeter Maydell             r = 0;
20675750e4dSPeter Maydell             break;
2071cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
20804836414SPeter Maydell             r = s->nmi_enable;
20904836414SPeter Maydell             break;
21092ecf2d5SPeter Maydell         case ARMSSE_SSE300:
21192ecf2d5SPeter Maydell             /* In SSE300 this is reserved (for INITSVTOR3) */
21292ecf2d5SPeter Maydell             goto bad_offset;
2131cbd6fe4SPeter Maydell         default:
2141cbd6fe4SPeter Maydell             g_assert_not_reached();
2151cbd6fe4SPeter Maydell         }
2161cbd6fe4SPeter Maydell         break;
21775750e4dSPeter Maydell     case A_WICCTRL:
21892ecf2d5SPeter Maydell         switch (s->sse_version) {
21992ecf2d5SPeter Maydell         case ARMSSE_IOTKIT:
22092ecf2d5SPeter Maydell         case ARMSSE_SSE200:
22175750e4dSPeter Maydell             r = s->wicctrl;
22275750e4dSPeter Maydell             break;
22392ecf2d5SPeter Maydell         case ARMSSE_SSE300:
22492ecf2d5SPeter Maydell             /* In SSE300 this offset is CPUWAIT */
22592ecf2d5SPeter Maydell             r = s->cpuwait;
22692ecf2d5SPeter Maydell             break;
22792ecf2d5SPeter Maydell         default:
22892ecf2d5SPeter Maydell             g_assert_not_reached();
22992ecf2d5SPeter Maydell         }
23092ecf2d5SPeter Maydell         break;
23104836414SPeter Maydell     case A_EWCTRL:
2321cbd6fe4SPeter Maydell         switch (s->sse_version) {
2331cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
23404836414SPeter Maydell             goto bad_offset;
2351cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
23604836414SPeter Maydell             r = s->ewctrl;
23704836414SPeter Maydell             break;
23892ecf2d5SPeter Maydell         case ARMSSE_SSE300:
2397a21bee2SDaniel P. Berrangé             /* In SSE300 this offset is NMI_ENABLE */
24092ecf2d5SPeter Maydell             r = s->nmi_enable;
24192ecf2d5SPeter Maydell             break;
2421cbd6fe4SPeter Maydell         default:
2431cbd6fe4SPeter Maydell             g_assert_not_reached();
24404836414SPeter Maydell         }
2451cbd6fe4SPeter Maydell         break;
2462672a6caSPeter Maydell     case A_PWRCTRL:
2472672a6caSPeter Maydell         switch (s->sse_version) {
2482672a6caSPeter Maydell         case ARMSSE_IOTKIT:
2492672a6caSPeter Maydell         case ARMSSE_SSE200:
2502672a6caSPeter Maydell             goto bad_offset;
2512672a6caSPeter Maydell         case ARMSSE_SSE300:
2522672a6caSPeter Maydell             r = s->pwrctrl;
2532672a6caSPeter Maydell             break;
2542672a6caSPeter Maydell         default:
2552672a6caSPeter Maydell             g_assert_not_reached();
2562672a6caSPeter Maydell         }
2572672a6caSPeter Maydell         break;
2581cbd6fe4SPeter Maydell     case A_PDCM_PD_SYS_SENSE:
2591cbd6fe4SPeter Maydell         switch (s->sse_version) {
2601cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
2611cbd6fe4SPeter Maydell             goto bad_offset;
2621cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
26331b0c6b1SPeter Maydell         case ARMSSE_SSE300:
26404836414SPeter Maydell             r = s->pdcm_pd_sys_sense;
26504836414SPeter Maydell             break;
2661cbd6fe4SPeter Maydell         default:
2671cbd6fe4SPeter Maydell             g_assert_not_reached();
26804836414SPeter Maydell         }
2691cbd6fe4SPeter Maydell         break;
270c5ffe6c8SPeter Maydell     case A_PDCM_PD_CPU0_SENSE:
271c5ffe6c8SPeter Maydell         switch (s->sse_version) {
272c5ffe6c8SPeter Maydell         case ARMSSE_IOTKIT:
273c5ffe6c8SPeter Maydell         case ARMSSE_SSE200:
274c5ffe6c8SPeter Maydell             goto bad_offset;
275c5ffe6c8SPeter Maydell         case ARMSSE_SSE300:
276c5ffe6c8SPeter Maydell             r = s->pdcm_pd_cpu0_sense;
277c5ffe6c8SPeter Maydell             break;
278c5ffe6c8SPeter Maydell         default:
279c5ffe6c8SPeter Maydell             g_assert_not_reached();
280c5ffe6c8SPeter Maydell         }
281c5ffe6c8SPeter Maydell         break;
2821cbd6fe4SPeter Maydell     case A_PDCM_PD_SRAM0_SENSE:
2831cbd6fe4SPeter Maydell         switch (s->sse_version) {
2841cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
2851cbd6fe4SPeter Maydell             goto bad_offset;
2861cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
28704836414SPeter Maydell             r = s->pdcm_pd_sram0_sense;
28804836414SPeter Maydell             break;
289c5ffe6c8SPeter Maydell         case ARMSSE_SSE300:
290c5ffe6c8SPeter Maydell             goto bad_offset;
2911cbd6fe4SPeter Maydell         default:
2921cbd6fe4SPeter Maydell             g_assert_not_reached();
29304836414SPeter Maydell         }
2941cbd6fe4SPeter Maydell         break;
2951cbd6fe4SPeter Maydell     case A_PDCM_PD_SRAM1_SENSE:
2961cbd6fe4SPeter Maydell         switch (s->sse_version) {
2971cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
2981cbd6fe4SPeter Maydell             goto bad_offset;
2991cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
30004836414SPeter Maydell             r = s->pdcm_pd_sram1_sense;
30104836414SPeter Maydell             break;
302c5ffe6c8SPeter Maydell         case ARMSSE_SSE300:
303c5ffe6c8SPeter Maydell             goto bad_offset;
3041cbd6fe4SPeter Maydell         default:
3051cbd6fe4SPeter Maydell             g_assert_not_reached();
30604836414SPeter Maydell         }
3071cbd6fe4SPeter Maydell         break;
3081cbd6fe4SPeter Maydell     case A_PDCM_PD_SRAM2_SENSE:
3091cbd6fe4SPeter Maydell         switch (s->sse_version) {
3101cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
3111cbd6fe4SPeter Maydell             goto bad_offset;
3121cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
31304836414SPeter Maydell             r = s->pdcm_pd_sram2_sense;
31404836414SPeter Maydell             break;
315c5ffe6c8SPeter Maydell         case ARMSSE_SSE300:
316c5ffe6c8SPeter Maydell             r = s->pdcm_pd_vmr0_sense;
317c5ffe6c8SPeter Maydell             break;
3181cbd6fe4SPeter Maydell         default:
3191cbd6fe4SPeter Maydell             g_assert_not_reached();
32004836414SPeter Maydell         }
3211cbd6fe4SPeter Maydell         break;
3221cbd6fe4SPeter Maydell     case A_PDCM_PD_SRAM3_SENSE:
3231cbd6fe4SPeter Maydell         switch (s->sse_version) {
3241cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
3251cbd6fe4SPeter Maydell             goto bad_offset;
3261cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
32704836414SPeter Maydell             r = s->pdcm_pd_sram3_sense;
32804836414SPeter Maydell             break;
329c5ffe6c8SPeter Maydell         case ARMSSE_SSE300:
330c5ffe6c8SPeter Maydell             r = s->pdcm_pd_vmr1_sense;
331c5ffe6c8SPeter Maydell             break;
3321cbd6fe4SPeter Maydell         default:
3331cbd6fe4SPeter Maydell             g_assert_not_reached();
3341cbd6fe4SPeter Maydell         }
3351cbd6fe4SPeter Maydell         break;
33675750e4dSPeter Maydell     case A_PID4 ... A_CID3:
3376069bbc9SPeter Maydell         switch (s->sse_version) {
3386069bbc9SPeter Maydell         case ARMSSE_IOTKIT:
3396069bbc9SPeter Maydell             r = iotkit_sysctl_id[(offset - A_PID4) / 4];
3406069bbc9SPeter Maydell             break;
3416069bbc9SPeter Maydell         case ARMSSE_SSE200:
3426069bbc9SPeter Maydell         case ARMSSE_SSE300:
3436069bbc9SPeter Maydell             r = sse200_sysctl_id[(offset - A_PID4) / 4];
3446069bbc9SPeter Maydell             break;
3456069bbc9SPeter Maydell         default:
3466069bbc9SPeter Maydell             g_assert_not_reached();
3476069bbc9SPeter Maydell         }
34875750e4dSPeter Maydell         break;
34975750e4dSPeter Maydell     case A_SECDBGSET:
35075750e4dSPeter Maydell     case A_SECDBGCLR:
35175750e4dSPeter Maydell     case A_SWRESET:
35275750e4dSPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
35375750e4dSPeter Maydell                       "IoTKit SysCtl read: read of WO offset %x\n",
35475750e4dSPeter Maydell                       (int)offset);
35575750e4dSPeter Maydell         r = 0;
35675750e4dSPeter Maydell         break;
35775750e4dSPeter Maydell     default:
35804836414SPeter Maydell     bad_offset:
35975750e4dSPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
36075750e4dSPeter Maydell                       "IoTKit SysCtl read: bad offset %x\n", (int)offset);
36175750e4dSPeter Maydell         r = 0;
36275750e4dSPeter Maydell         break;
36375750e4dSPeter Maydell     }
36475750e4dSPeter Maydell     trace_iotkit_sysctl_read(offset, r, size);
36575750e4dSPeter Maydell     return r;
36675750e4dSPeter Maydell }
36775750e4dSPeter Maydell 
cpuwait_write(IoTKitSysCtl * s,uint32_t value)36892ecf2d5SPeter Maydell static void cpuwait_write(IoTKitSysCtl *s, uint32_t value)
36992ecf2d5SPeter Maydell {
37092ecf2d5SPeter Maydell     int num_cpus = (s->sse_version == ARMSSE_SSE300) ? 1 : 2;
37192ecf2d5SPeter Maydell     int i;
37292ecf2d5SPeter Maydell 
37392ecf2d5SPeter Maydell     for (i = 0; i < num_cpus; i++) {
37492ecf2d5SPeter Maydell         uint32_t mask = 1 << i;
37592ecf2d5SPeter Maydell         if ((s->cpuwait & mask) && !(value & mask)) {
37692ecf2d5SPeter Maydell             /* Powering up CPU 0 */
37792ecf2d5SPeter Maydell             arm_set_cpu_on_and_reset(i);
37892ecf2d5SPeter Maydell         }
37992ecf2d5SPeter Maydell     }
38092ecf2d5SPeter Maydell     s->cpuwait = value;
38192ecf2d5SPeter Maydell }
38292ecf2d5SPeter Maydell 
iotkit_sysctl_write(void * opaque,hwaddr offset,uint64_t value,unsigned size)38375750e4dSPeter Maydell static void iotkit_sysctl_write(void *opaque, hwaddr offset,
38475750e4dSPeter Maydell                                  uint64_t value, unsigned size)
38575750e4dSPeter Maydell {
38675750e4dSPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
38775750e4dSPeter Maydell 
38875750e4dSPeter Maydell     trace_iotkit_sysctl_write(offset, value, size);
38975750e4dSPeter Maydell 
39075750e4dSPeter Maydell     /*
39175750e4dSPeter Maydell      * Most of the state here has to do with control of reset and
39275750e4dSPeter Maydell      * similar kinds of power up -- for instance the guest can ask
39375750e4dSPeter Maydell      * what the reason for the last reset was, or forbid reset for
39475750e4dSPeter Maydell      * some causes (like the non-secure watchdog). Most of this is
39575750e4dSPeter Maydell      * not relevant to QEMU, which doesn't really model anything other
39675750e4dSPeter Maydell      * than a full power-on reset.
39775750e4dSPeter Maydell      * We just model the registers as reads-as-written.
39875750e4dSPeter Maydell      */
39975750e4dSPeter Maydell 
40075750e4dSPeter Maydell     switch (offset) {
40175750e4dSPeter Maydell     case A_RESET_SYNDROME:
40275750e4dSPeter Maydell         qemu_log_mask(LOG_UNIMP,
40375750e4dSPeter Maydell                       "IoTKit SysCtl RESET_SYNDROME unimplemented\n");
40475750e4dSPeter Maydell         s->reset_syndrome = value;
40575750e4dSPeter Maydell         break;
40675750e4dSPeter Maydell     case A_RESET_MASK:
40775750e4dSPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n");
40875750e4dSPeter Maydell         s->reset_mask = value;
40975750e4dSPeter Maydell         break;
41075750e4dSPeter Maydell     case A_GRETREG:
41175750e4dSPeter Maydell         /*
41275750e4dSPeter Maydell          * General retention register, which is only reset by a power-on
41375750e4dSPeter Maydell          * reset. Technically this implementation is complete, since
41475750e4dSPeter Maydell          * QEMU only supports power-on resets...
41575750e4dSPeter Maydell          */
41675750e4dSPeter Maydell         s->gretreg = value;
41775750e4dSPeter Maydell         break;
418394e10d2SPeter Maydell     case A_INITSVTOR0:
419246dbeb7SPeter Maydell         switch (s->sse_version) {
420246dbeb7SPeter Maydell         case ARMSSE_SSE300:
421246dbeb7SPeter Maydell             /* SSE300 has a LOCK bit which prevents further writes when set */
422246dbeb7SPeter Maydell             if (s->initsvtor0 & R_INITSVTOR0_LOCK_MASK) {
423246dbeb7SPeter Maydell                 qemu_log_mask(LOG_GUEST_ERROR,
424246dbeb7SPeter Maydell                               "IoTKit INITSVTOR0 write when register locked\n");
425246dbeb7SPeter Maydell                 break;
426246dbeb7SPeter Maydell             }
427246dbeb7SPeter Maydell             s->initsvtor0 = value;
428246dbeb7SPeter Maydell             set_init_vtor(0, s->initsvtor0 & R_INITSVTOR0_VTOR_MASK);
429246dbeb7SPeter Maydell             break;
430246dbeb7SPeter Maydell         case ARMSSE_IOTKIT:
431246dbeb7SPeter Maydell         case ARMSSE_SSE200:
432394e10d2SPeter Maydell             s->initsvtor0 = value;
4330f862986SPeter Maydell             set_init_vtor(0, s->initsvtor0);
43475750e4dSPeter Maydell             break;
435246dbeb7SPeter Maydell         default:
436246dbeb7SPeter Maydell             g_assert_not_reached();
437246dbeb7SPeter Maydell         }
438246dbeb7SPeter Maydell         break;
43975750e4dSPeter Maydell     case A_CPUWAIT:
44092ecf2d5SPeter Maydell         switch (s->sse_version) {
44192ecf2d5SPeter Maydell         case ARMSSE_IOTKIT:
44292ecf2d5SPeter Maydell         case ARMSSE_SSE200:
44392ecf2d5SPeter Maydell             cpuwait_write(s, value);
44492ecf2d5SPeter Maydell             break;
44592ecf2d5SPeter Maydell         case ARMSSE_SSE300:
44692ecf2d5SPeter Maydell             /* In SSE300 this is reserved (for INITSVTOR2) */
44792ecf2d5SPeter Maydell             goto bad_offset;
44892ecf2d5SPeter Maydell         default:
44992ecf2d5SPeter Maydell             g_assert_not_reached();
4500f862986SPeter Maydell         }
45175750e4dSPeter Maydell         break;
45275750e4dSPeter Maydell     case A_WICCTRL:
45392ecf2d5SPeter Maydell         switch (s->sse_version) {
45492ecf2d5SPeter Maydell         case ARMSSE_IOTKIT:
45592ecf2d5SPeter Maydell         case ARMSSE_SSE200:
45675750e4dSPeter Maydell             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
45775750e4dSPeter Maydell             s->wicctrl = value;
45875750e4dSPeter Maydell             break;
45992ecf2d5SPeter Maydell         case ARMSSE_SSE300:
46092ecf2d5SPeter Maydell             /* In SSE300 this offset is CPUWAIT */
46192ecf2d5SPeter Maydell             cpuwait_write(s, value);
46292ecf2d5SPeter Maydell             break;
46392ecf2d5SPeter Maydell         default:
46492ecf2d5SPeter Maydell             g_assert_not_reached();
46592ecf2d5SPeter Maydell         }
46692ecf2d5SPeter Maydell         break;
46775750e4dSPeter Maydell     case A_SECDBGSET:
46875750e4dSPeter Maydell         /* write-1-to-set */
46975750e4dSPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n");
47075750e4dSPeter Maydell         s->secure_debug |= value;
47175750e4dSPeter Maydell         break;
47275750e4dSPeter Maydell     case A_SECDBGCLR:
47375750e4dSPeter Maydell         /* write-1-to-clear */
47475750e4dSPeter Maydell         s->secure_debug &= ~value;
47575750e4dSPeter Maydell         break;
47675750e4dSPeter Maydell     case A_SWRESET:
47775750e4dSPeter Maydell         /* One w/o bit to request a reset; all other bits reserved */
47875750e4dSPeter Maydell         if (value & R_SWRESET_SWRESETREQ_MASK) {
47975750e4dSPeter Maydell             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
48075750e4dSPeter Maydell         }
48175750e4dSPeter Maydell         break;
48204836414SPeter Maydell     case A_SCSECCTRL:
4831cbd6fe4SPeter Maydell         switch (s->sse_version) {
4841cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
48504836414SPeter Maydell             goto bad_offset;
4861cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
48731b0c6b1SPeter Maydell         case ARMSSE_SSE300:
48804836414SPeter Maydell             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
48904836414SPeter Maydell             s->scsecctrl = value;
49004836414SPeter Maydell             break;
4911cbd6fe4SPeter Maydell         default:
4921cbd6fe4SPeter Maydell             g_assert_not_reached();
49304836414SPeter Maydell         }
4941cbd6fe4SPeter Maydell         break;
4951cbd6fe4SPeter Maydell     case A_FCLK_DIV:
4961cbd6fe4SPeter Maydell         switch (s->sse_version) {
4971cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
4981cbd6fe4SPeter Maydell             goto bad_offset;
4991cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
50031b0c6b1SPeter Maydell         case ARMSSE_SSE300:
50104836414SPeter Maydell             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
50204836414SPeter Maydell             s->fclk_div = value;
50304836414SPeter Maydell             break;
5041cbd6fe4SPeter Maydell         default:
5051cbd6fe4SPeter Maydell             g_assert_not_reached();
50604836414SPeter Maydell         }
5071cbd6fe4SPeter Maydell         break;
5081cbd6fe4SPeter Maydell     case A_SYSCLK_DIV:
5091cbd6fe4SPeter Maydell         switch (s->sse_version) {
5101cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
5111cbd6fe4SPeter Maydell             goto bad_offset;
5121cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
51331b0c6b1SPeter Maydell         case ARMSSE_SSE300:
51404836414SPeter Maydell             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
51504836414SPeter Maydell             s->sysclk_div = value;
51604836414SPeter Maydell             break;
5171cbd6fe4SPeter Maydell         default:
5181cbd6fe4SPeter Maydell             g_assert_not_reached();
51904836414SPeter Maydell         }
5201cbd6fe4SPeter Maydell         break;
5211cbd6fe4SPeter Maydell     case A_CLOCK_FORCE:
5221cbd6fe4SPeter Maydell         switch (s->sse_version) {
5231cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
5241cbd6fe4SPeter Maydell             goto bad_offset;
5251cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
52631b0c6b1SPeter Maydell         case ARMSSE_SSE300:
52704836414SPeter Maydell             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
52804836414SPeter Maydell             s->clock_force = value;
52904836414SPeter Maydell             break;
5301cbd6fe4SPeter Maydell         default:
5311cbd6fe4SPeter Maydell             g_assert_not_reached();
53204836414SPeter Maydell         }
5331cbd6fe4SPeter Maydell         break;
5341cbd6fe4SPeter Maydell     case A_INITSVTOR1:
5351cbd6fe4SPeter Maydell         switch (s->sse_version) {
5361cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
5371cbd6fe4SPeter Maydell             goto bad_offset;
5381cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
53904836414SPeter Maydell             s->initsvtor1 = value;
5400f862986SPeter Maydell             set_init_vtor(1, s->initsvtor1);
54104836414SPeter Maydell             break;
542246dbeb7SPeter Maydell         case ARMSSE_SSE300:
543246dbeb7SPeter Maydell             goto bad_offset;
5441cbd6fe4SPeter Maydell         default:
5451cbd6fe4SPeter Maydell             g_assert_not_reached();
54604836414SPeter Maydell         }
5471cbd6fe4SPeter Maydell         break;
5481cbd6fe4SPeter Maydell     case A_EWCTRL:
5491cbd6fe4SPeter Maydell         switch (s->sse_version) {
5501cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
5511cbd6fe4SPeter Maydell             goto bad_offset;
5521cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
55304836414SPeter Maydell             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
55404836414SPeter Maydell             s->ewctrl = value;
55504836414SPeter Maydell             break;
55692ecf2d5SPeter Maydell         case ARMSSE_SSE300:
5577a21bee2SDaniel P. Berrangé             /* In SSE300 this offset is NMI_ENABLE */
55892ecf2d5SPeter Maydell             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
55992ecf2d5SPeter Maydell             s->nmi_enable = value;
56092ecf2d5SPeter Maydell             break;
5611cbd6fe4SPeter Maydell         default:
5621cbd6fe4SPeter Maydell             g_assert_not_reached();
56304836414SPeter Maydell         }
5641cbd6fe4SPeter Maydell         break;
5652672a6caSPeter Maydell     case A_PWRCTRL:
5662672a6caSPeter Maydell         switch (s->sse_version) {
5672672a6caSPeter Maydell         case ARMSSE_IOTKIT:
5682672a6caSPeter Maydell         case ARMSSE_SSE200:
5692672a6caSPeter Maydell             goto bad_offset;
5702672a6caSPeter Maydell         case ARMSSE_SSE300:
5712672a6caSPeter Maydell             if (!(s->pwrctrl & R_PWRCTRL_PPU_ACCESS_UNLOCK_MASK)) {
5722672a6caSPeter Maydell                 qemu_log_mask(LOG_GUEST_ERROR,
5732672a6caSPeter Maydell                               "IoTKit PWRCTRL write when register locked\n");
5742672a6caSPeter Maydell                 break;
5752672a6caSPeter Maydell             }
5762672a6caSPeter Maydell             s->pwrctrl = value;
5772672a6caSPeter Maydell             break;
5782672a6caSPeter Maydell         default:
5792672a6caSPeter Maydell             g_assert_not_reached();
5802672a6caSPeter Maydell         }
5812672a6caSPeter Maydell         break;
5821cbd6fe4SPeter Maydell     case A_PDCM_PD_SYS_SENSE:
5831cbd6fe4SPeter Maydell         switch (s->sse_version) {
5841cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
5851cbd6fe4SPeter Maydell             goto bad_offset;
5861cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
58731b0c6b1SPeter Maydell         case ARMSSE_SSE300:
58804836414SPeter Maydell             qemu_log_mask(LOG_UNIMP,
58904836414SPeter Maydell                           "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
59004836414SPeter Maydell             s->pdcm_pd_sys_sense = value;
59104836414SPeter Maydell             break;
5921cbd6fe4SPeter Maydell         default:
5931cbd6fe4SPeter Maydell             g_assert_not_reached();
59404836414SPeter Maydell         }
5951cbd6fe4SPeter Maydell         break;
596c5ffe6c8SPeter Maydell     case A_PDCM_PD_CPU0_SENSE:
597c5ffe6c8SPeter Maydell         switch (s->sse_version) {
598c5ffe6c8SPeter Maydell         case ARMSSE_IOTKIT:
599c5ffe6c8SPeter Maydell         case ARMSSE_SSE200:
600c5ffe6c8SPeter Maydell             goto bad_offset;
601c5ffe6c8SPeter Maydell         case ARMSSE_SSE300:
602c5ffe6c8SPeter Maydell             qemu_log_mask(LOG_UNIMP,
603c5ffe6c8SPeter Maydell                           "IoTKit SysCtl PDCM_PD_CPU0_SENSE unimplemented\n");
604c5ffe6c8SPeter Maydell             s->pdcm_pd_cpu0_sense = value;
605c5ffe6c8SPeter Maydell             break;
606c5ffe6c8SPeter Maydell         default:
607c5ffe6c8SPeter Maydell             g_assert_not_reached();
608c5ffe6c8SPeter Maydell         }
609c5ffe6c8SPeter Maydell         break;
6101cbd6fe4SPeter Maydell     case A_PDCM_PD_SRAM0_SENSE:
6111cbd6fe4SPeter Maydell         switch (s->sse_version) {
6121cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
6131cbd6fe4SPeter Maydell             goto bad_offset;
6141cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
61504836414SPeter Maydell             qemu_log_mask(LOG_UNIMP,
61604836414SPeter Maydell                           "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
61704836414SPeter Maydell             s->pdcm_pd_sram0_sense = value;
61804836414SPeter Maydell             break;
619c5ffe6c8SPeter Maydell         case ARMSSE_SSE300:
620c5ffe6c8SPeter Maydell             goto bad_offset;
6211cbd6fe4SPeter Maydell         default:
6221cbd6fe4SPeter Maydell             g_assert_not_reached();
62304836414SPeter Maydell         }
6241cbd6fe4SPeter Maydell         break;
6251cbd6fe4SPeter Maydell     case A_PDCM_PD_SRAM1_SENSE:
6261cbd6fe4SPeter Maydell         switch (s->sse_version) {
6271cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
6281cbd6fe4SPeter Maydell             goto bad_offset;
6291cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
63004836414SPeter Maydell             qemu_log_mask(LOG_UNIMP,
63104836414SPeter Maydell                           "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
63204836414SPeter Maydell             s->pdcm_pd_sram1_sense = value;
63304836414SPeter Maydell             break;
634c5ffe6c8SPeter Maydell         case ARMSSE_SSE300:
635c5ffe6c8SPeter Maydell             goto bad_offset;
6361cbd6fe4SPeter Maydell         default:
6371cbd6fe4SPeter Maydell             g_assert_not_reached();
63804836414SPeter Maydell         }
6391cbd6fe4SPeter Maydell         break;
6401cbd6fe4SPeter Maydell     case A_PDCM_PD_SRAM2_SENSE:
6411cbd6fe4SPeter Maydell         switch (s->sse_version) {
6421cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
6431cbd6fe4SPeter Maydell             goto bad_offset;
6441cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
64504836414SPeter Maydell             qemu_log_mask(LOG_UNIMP,
64604836414SPeter Maydell                           "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
64704836414SPeter Maydell             s->pdcm_pd_sram2_sense = value;
64804836414SPeter Maydell             break;
649c5ffe6c8SPeter Maydell         case ARMSSE_SSE300:
650c5ffe6c8SPeter Maydell             qemu_log_mask(LOG_UNIMP,
651c5ffe6c8SPeter Maydell                           "IoTKit SysCtl PDCM_PD_VMR0_SENSE unimplemented\n");
652c5ffe6c8SPeter Maydell             s->pdcm_pd_vmr0_sense = value;
653c5ffe6c8SPeter Maydell             break;
6541cbd6fe4SPeter Maydell         default:
6551cbd6fe4SPeter Maydell             g_assert_not_reached();
65604836414SPeter Maydell         }
6571cbd6fe4SPeter Maydell         break;
6581cbd6fe4SPeter Maydell     case A_PDCM_PD_SRAM3_SENSE:
6591cbd6fe4SPeter Maydell         switch (s->sse_version) {
6601cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
6611cbd6fe4SPeter Maydell             goto bad_offset;
6621cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
66304836414SPeter Maydell             qemu_log_mask(LOG_UNIMP,
66404836414SPeter Maydell                           "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
66504836414SPeter Maydell             s->pdcm_pd_sram3_sense = value;
66604836414SPeter Maydell             break;
667c5ffe6c8SPeter Maydell         case ARMSSE_SSE300:
668c5ffe6c8SPeter Maydell             qemu_log_mask(LOG_UNIMP,
669c5ffe6c8SPeter Maydell                           "IoTKit SysCtl PDCM_PD_VMR1_SENSE unimplemented\n");
670c5ffe6c8SPeter Maydell             s->pdcm_pd_vmr1_sense = value;
671c5ffe6c8SPeter Maydell             break;
6721cbd6fe4SPeter Maydell         default:
6731cbd6fe4SPeter Maydell             g_assert_not_reached();
6741cbd6fe4SPeter Maydell         }
6751cbd6fe4SPeter Maydell         break;
67604836414SPeter Maydell     case A_NMI_ENABLE:
67704836414SPeter Maydell         /* In IoTKit this is BUSWAIT: reserved, R/O, zero */
6781cbd6fe4SPeter Maydell         switch (s->sse_version) {
6791cbd6fe4SPeter Maydell         case ARMSSE_IOTKIT:
68004836414SPeter Maydell             goto ro_offset;
6811cbd6fe4SPeter Maydell         case ARMSSE_SSE200:
68204836414SPeter Maydell             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
68304836414SPeter Maydell             s->nmi_enable = value;
68404836414SPeter Maydell             break;
68592ecf2d5SPeter Maydell         case ARMSSE_SSE300:
68692ecf2d5SPeter Maydell             /* In SSE300 this is reserved (for INITSVTOR3) */
68792ecf2d5SPeter Maydell             goto bad_offset;
6881cbd6fe4SPeter Maydell         default:
6891cbd6fe4SPeter Maydell             g_assert_not_reached();
6901cbd6fe4SPeter Maydell         }
6911cbd6fe4SPeter Maydell         break;
69275750e4dSPeter Maydell     case A_SECDBGSTAT:
69375750e4dSPeter Maydell     case A_PID4 ... A_CID3:
69404836414SPeter Maydell     ro_offset:
69575750e4dSPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
69675750e4dSPeter Maydell                       "IoTKit SysCtl write: write of RO offset %x\n",
69775750e4dSPeter Maydell                       (int)offset);
69875750e4dSPeter Maydell         break;
69975750e4dSPeter Maydell     default:
70004836414SPeter Maydell     bad_offset:
70175750e4dSPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
70275750e4dSPeter Maydell                       "IoTKit SysCtl write: bad offset %x\n", (int)offset);
70375750e4dSPeter Maydell         break;
70475750e4dSPeter Maydell     }
70575750e4dSPeter Maydell }
70675750e4dSPeter Maydell 
70775750e4dSPeter Maydell static const MemoryRegionOps iotkit_sysctl_ops = {
70875750e4dSPeter Maydell     .read = iotkit_sysctl_read,
70975750e4dSPeter Maydell     .write = iotkit_sysctl_write,
71075750e4dSPeter Maydell     .endianness = DEVICE_LITTLE_ENDIAN,
71175750e4dSPeter Maydell     /* byte/halfword accesses are just zero-padded on reads and writes */
71275750e4dSPeter Maydell     .impl.min_access_size = 4,
71375750e4dSPeter Maydell     .impl.max_access_size = 4,
71475750e4dSPeter Maydell     .valid.min_access_size = 1,
71575750e4dSPeter Maydell     .valid.max_access_size = 4,
71675750e4dSPeter Maydell };
71775750e4dSPeter Maydell 
iotkit_sysctl_reset(DeviceState * dev)71875750e4dSPeter Maydell static void iotkit_sysctl_reset(DeviceState *dev)
71975750e4dSPeter Maydell {
72075750e4dSPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
72175750e4dSPeter Maydell 
72275750e4dSPeter Maydell     trace_iotkit_sysctl_reset();
72375750e4dSPeter Maydell     s->secure_debug = 0;
72475750e4dSPeter Maydell     s->reset_syndrome = 1;
72575750e4dSPeter Maydell     s->reset_mask = 0;
72675750e4dSPeter Maydell     s->gretreg = 0;
727aab7a378SPeter Maydell     s->initsvtor0 = s->initsvtor0_rst;
728aab7a378SPeter Maydell     s->initsvtor1 = s->initsvtor1_rst;
729aab7a378SPeter Maydell     s->cpuwait = s->cpuwait_rst;
73075750e4dSPeter Maydell     s->wicctrl = 0;
73104836414SPeter Maydell     s->scsecctrl = 0;
73204836414SPeter Maydell     s->fclk_div = 0;
73304836414SPeter Maydell     s->sysclk_div = 0;
73404836414SPeter Maydell     s->clock_force = 0;
73504836414SPeter Maydell     s->nmi_enable = 0;
73604836414SPeter Maydell     s->ewctrl = 0;
7372672a6caSPeter Maydell     s->pwrctrl = 0x3;
73804836414SPeter Maydell     s->pdcm_pd_sys_sense = 0x7f;
73904836414SPeter Maydell     s->pdcm_pd_sram0_sense = 0;
74004836414SPeter Maydell     s->pdcm_pd_sram1_sense = 0;
74104836414SPeter Maydell     s->pdcm_pd_sram2_sense = 0;
74204836414SPeter Maydell     s->pdcm_pd_sram3_sense = 0;
743c5ffe6c8SPeter Maydell     s->pdcm_pd_cpu0_sense = 0;
744c5ffe6c8SPeter Maydell     s->pdcm_pd_vmr0_sense = 0;
745c5ffe6c8SPeter Maydell     s->pdcm_pd_vmr1_sense = 0;
74675750e4dSPeter Maydell }
74775750e4dSPeter Maydell 
iotkit_sysctl_init(Object * obj)74875750e4dSPeter Maydell static void iotkit_sysctl_init(Object *obj)
74975750e4dSPeter Maydell {
75075750e4dSPeter Maydell     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
75175750e4dSPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(obj);
75275750e4dSPeter Maydell 
75375750e4dSPeter Maydell     memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops,
75475750e4dSPeter Maydell                           s, "iotkit-sysctl", 0x1000);
75575750e4dSPeter Maydell     sysbus_init_mmio(sbd, &s->iomem);
75675750e4dSPeter Maydell }
75775750e4dSPeter Maydell 
iotkit_sysctl_realize(DeviceState * dev,Error ** errp)75804836414SPeter Maydell static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
75904836414SPeter Maydell {
76004836414SPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
76104836414SPeter Maydell 
762419a7f80SPeter Maydell     if (!armsse_version_valid(s->sse_version)) {
763419a7f80SPeter Maydell         error_setg(errp, "invalid sse-version value %d", s->sse_version);
764419a7f80SPeter Maydell         return;
76504836414SPeter Maydell     }
76604836414SPeter Maydell }
76704836414SPeter Maydell 
sse300_needed(void * opaque)7682672a6caSPeter Maydell static bool sse300_needed(void *opaque)
7692672a6caSPeter Maydell {
7702672a6caSPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
7712672a6caSPeter Maydell 
7722672a6caSPeter Maydell     return s->sse_version == ARMSSE_SSE300;
7732672a6caSPeter Maydell }
7742672a6caSPeter Maydell 
7752672a6caSPeter Maydell static const VMStateDescription iotkit_sysctl_sse300_vmstate = {
7762672a6caSPeter Maydell     .name = "iotkit-sysctl/sse-300",
7772672a6caSPeter Maydell     .version_id = 1,
7782672a6caSPeter Maydell     .minimum_version_id = 1,
7792672a6caSPeter Maydell     .needed = sse300_needed,
780e4ea952fSRichard Henderson     .fields = (const VMStateField[]) {
7812672a6caSPeter Maydell         VMSTATE_UINT32(pwrctrl, IoTKitSysCtl),
782c5ffe6c8SPeter Maydell         VMSTATE_UINT32(pdcm_pd_cpu0_sense, IoTKitSysCtl),
783c5ffe6c8SPeter Maydell         VMSTATE_UINT32(pdcm_pd_vmr0_sense, IoTKitSysCtl),
784c5ffe6c8SPeter Maydell         VMSTATE_UINT32(pdcm_pd_vmr1_sense, IoTKitSysCtl),
7852672a6caSPeter Maydell         VMSTATE_END_OF_LIST()
7862672a6caSPeter Maydell     }
7872672a6caSPeter Maydell };
7882672a6caSPeter Maydell 
sse200_needed(void * opaque)78904836414SPeter Maydell static bool sse200_needed(void *opaque)
79004836414SPeter Maydell {
79104836414SPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
79204836414SPeter Maydell 
79331b0c6b1SPeter Maydell     return s->sse_version != ARMSSE_IOTKIT;
79404836414SPeter Maydell }
79504836414SPeter Maydell 
79604836414SPeter Maydell static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
79704836414SPeter Maydell     .name = "iotkit-sysctl/sse-200",
79804836414SPeter Maydell     .version_id = 1,
79904836414SPeter Maydell     .minimum_version_id = 1,
80004836414SPeter Maydell     .needed = sse200_needed,
801e4ea952fSRichard Henderson     .fields = (const VMStateField[]) {
80204836414SPeter Maydell         VMSTATE_UINT32(scsecctrl, IoTKitSysCtl),
80304836414SPeter Maydell         VMSTATE_UINT32(fclk_div, IoTKitSysCtl),
80404836414SPeter Maydell         VMSTATE_UINT32(sysclk_div, IoTKitSysCtl),
80504836414SPeter Maydell         VMSTATE_UINT32(clock_force, IoTKitSysCtl),
80604836414SPeter Maydell         VMSTATE_UINT32(initsvtor1, IoTKitSysCtl),
80704836414SPeter Maydell         VMSTATE_UINT32(nmi_enable, IoTKitSysCtl),
80804836414SPeter Maydell         VMSTATE_UINT32(pdcm_pd_sys_sense, IoTKitSysCtl),
80904836414SPeter Maydell         VMSTATE_UINT32(pdcm_pd_sram0_sense, IoTKitSysCtl),
81004836414SPeter Maydell         VMSTATE_UINT32(pdcm_pd_sram1_sense, IoTKitSysCtl),
81104836414SPeter Maydell         VMSTATE_UINT32(pdcm_pd_sram2_sense, IoTKitSysCtl),
81204836414SPeter Maydell         VMSTATE_UINT32(pdcm_pd_sram3_sense, IoTKitSysCtl),
81304836414SPeter Maydell         VMSTATE_END_OF_LIST()
81404836414SPeter Maydell     }
81504836414SPeter Maydell };
81604836414SPeter Maydell 
81775750e4dSPeter Maydell static const VMStateDescription iotkit_sysctl_vmstate = {
81875750e4dSPeter Maydell     .name = "iotkit-sysctl",
81975750e4dSPeter Maydell     .version_id = 1,
82075750e4dSPeter Maydell     .minimum_version_id = 1,
821e4ea952fSRichard Henderson     .fields = (const VMStateField[]) {
82275750e4dSPeter Maydell         VMSTATE_UINT32(secure_debug, IoTKitSysCtl),
82375750e4dSPeter Maydell         VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl),
82475750e4dSPeter Maydell         VMSTATE_UINT32(reset_mask, IoTKitSysCtl),
82575750e4dSPeter Maydell         VMSTATE_UINT32(gretreg, IoTKitSysCtl),
826394e10d2SPeter Maydell         VMSTATE_UINT32(initsvtor0, IoTKitSysCtl),
82775750e4dSPeter Maydell         VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
82875750e4dSPeter Maydell         VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
82975750e4dSPeter Maydell         VMSTATE_END_OF_LIST()
83004836414SPeter Maydell     },
831e4ea952fSRichard Henderson     .subsections = (const VMStateDescription * const []) {
83204836414SPeter Maydell         &iotkit_sysctl_sse200_vmstate,
8332672a6caSPeter Maydell         &iotkit_sysctl_sse300_vmstate,
83404836414SPeter Maydell         NULL
83575750e4dSPeter Maydell     }
83675750e4dSPeter Maydell };
83775750e4dSPeter Maydell 
83830029973SRichard Henderson static const Property iotkit_sysctl_props[] = {
839419a7f80SPeter Maydell     DEFINE_PROP_UINT32("sse-version", IoTKitSysCtl, sse_version, 0),
840aab7a378SPeter Maydell     DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0),
841aab7a378SPeter Maydell     DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst,
842aab7a378SPeter Maydell                        0x10000000),
843aab7a378SPeter Maydell     DEFINE_PROP_UINT32("INITSVTOR1_RST", IoTKitSysCtl, initsvtor1_rst,
844aab7a378SPeter Maydell                        0x10000000),
84504836414SPeter Maydell };
84604836414SPeter Maydell 
iotkit_sysctl_class_init(ObjectClass * klass,const void * data)847*12d1a768SPhilippe Mathieu-Daudé static void iotkit_sysctl_class_init(ObjectClass *klass, const void *data)
84875750e4dSPeter Maydell {
84975750e4dSPeter Maydell     DeviceClass *dc = DEVICE_CLASS(klass);
85075750e4dSPeter Maydell 
85175750e4dSPeter Maydell     dc->vmsd = &iotkit_sysctl_vmstate;
852e3d08143SPeter Maydell     device_class_set_legacy_reset(dc, iotkit_sysctl_reset);
8534f67d30bSMarc-André Lureau     device_class_set_props(dc, iotkit_sysctl_props);
85404836414SPeter Maydell     dc->realize = iotkit_sysctl_realize;
85575750e4dSPeter Maydell }
85675750e4dSPeter Maydell 
85775750e4dSPeter Maydell static const TypeInfo iotkit_sysctl_info = {
85875750e4dSPeter Maydell     .name = TYPE_IOTKIT_SYSCTL,
85975750e4dSPeter Maydell     .parent = TYPE_SYS_BUS_DEVICE,
86075750e4dSPeter Maydell     .instance_size = sizeof(IoTKitSysCtl),
86175750e4dSPeter Maydell     .instance_init = iotkit_sysctl_init,
86275750e4dSPeter Maydell     .class_init = iotkit_sysctl_class_init,
86375750e4dSPeter Maydell };
86475750e4dSPeter Maydell 
iotkit_sysctl_register_types(void)86575750e4dSPeter Maydell static void iotkit_sysctl_register_types(void)
86675750e4dSPeter Maydell {
86775750e4dSPeter Maydell     type_register_static(&iotkit_sysctl_info);
86875750e4dSPeter Maydell }
86975750e4dSPeter Maydell 
87075750e4dSPeter Maydell type_init(iotkit_sysctl_register_types);
871