xref: /qemu/hw/misc/iotkit-sysctl.c (revision 0483641418643d5d4cc4d1328fe7acc4ab36c709)
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
1575750e4dSPeter Maydell  * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
1675750e4dSPeter Maydell  * Specifically, it implements the "system control register" blocks.
1775750e4dSPeter Maydell  */
1875750e4dSPeter Maydell 
1975750e4dSPeter Maydell #include "qemu/osdep.h"
20*04836414SPeter Maydell #include "qemu/bitops.h"
2175750e4dSPeter Maydell #include "qemu/log.h"
2275750e4dSPeter Maydell #include "trace.h"
2375750e4dSPeter Maydell #include "qapi/error.h"
2475750e4dSPeter Maydell #include "sysemu/sysemu.h"
2575750e4dSPeter Maydell #include "hw/sysbus.h"
2675750e4dSPeter Maydell #include "hw/registerfields.h"
2775750e4dSPeter Maydell #include "hw/misc/iotkit-sysctl.h"
2875750e4dSPeter Maydell 
2975750e4dSPeter Maydell REG32(SECDBGSTAT, 0x0)
3075750e4dSPeter Maydell REG32(SECDBGSET, 0x4)
3175750e4dSPeter Maydell REG32(SECDBGCLR, 0x8)
32*04836414SPeter Maydell REG32(SCSECCTRL, 0xc)
33*04836414SPeter Maydell REG32(FCLK_DIV, 0x10)
34*04836414SPeter Maydell REG32(SYSCLK_DIV, 0x14)
35*04836414SPeter Maydell REG32(CLOCK_FORCE, 0x18)
3675750e4dSPeter Maydell REG32(RESET_SYNDROME, 0x100)
3775750e4dSPeter Maydell REG32(RESET_MASK, 0x104)
3875750e4dSPeter Maydell REG32(SWRESET, 0x108)
3975750e4dSPeter Maydell     FIELD(SWRESET, SWRESETREQ, 9, 1)
4075750e4dSPeter Maydell REG32(GRETREG, 0x10c)
41394e10d2SPeter Maydell REG32(INITSVTOR0, 0x110)
42*04836414SPeter Maydell REG32(INITSVTOR1, 0x114)
4375750e4dSPeter Maydell REG32(CPUWAIT, 0x118)
44*04836414SPeter Maydell REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
4575750e4dSPeter Maydell REG32(WICCTRL, 0x120)
46*04836414SPeter Maydell REG32(EWCTRL, 0x124)
47*04836414SPeter Maydell REG32(PDCM_PD_SYS_SENSE, 0x200)
48*04836414SPeter Maydell REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
49*04836414SPeter Maydell REG32(PDCM_PD_SRAM1_SENSE, 0x210)
50*04836414SPeter Maydell REG32(PDCM_PD_SRAM2_SENSE, 0x214)
51*04836414SPeter Maydell REG32(PDCM_PD_SRAM3_SENSE, 0x218)
5275750e4dSPeter Maydell REG32(PID4, 0xfd0)
5375750e4dSPeter Maydell REG32(PID5, 0xfd4)
5475750e4dSPeter Maydell REG32(PID6, 0xfd8)
5575750e4dSPeter Maydell REG32(PID7, 0xfdc)
5675750e4dSPeter Maydell REG32(PID0, 0xfe0)
5775750e4dSPeter Maydell REG32(PID1, 0xfe4)
5875750e4dSPeter Maydell REG32(PID2, 0xfe8)
5975750e4dSPeter Maydell REG32(PID3, 0xfec)
6075750e4dSPeter Maydell REG32(CID0, 0xff0)
6175750e4dSPeter Maydell REG32(CID1, 0xff4)
6275750e4dSPeter Maydell REG32(CID2, 0xff8)
6375750e4dSPeter Maydell REG32(CID3, 0xffc)
6475750e4dSPeter Maydell 
6575750e4dSPeter Maydell /* PID/CID values */
6675750e4dSPeter Maydell static const int sysctl_id[] = {
6775750e4dSPeter Maydell     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
6875750e4dSPeter Maydell     0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
6975750e4dSPeter Maydell     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
7075750e4dSPeter Maydell };
7175750e4dSPeter Maydell 
7275750e4dSPeter Maydell static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
7375750e4dSPeter Maydell                                     unsigned size)
7475750e4dSPeter Maydell {
7575750e4dSPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
7675750e4dSPeter Maydell     uint64_t r;
7775750e4dSPeter Maydell 
7875750e4dSPeter Maydell     switch (offset) {
7975750e4dSPeter Maydell     case A_SECDBGSTAT:
8075750e4dSPeter Maydell         r = s->secure_debug;
8175750e4dSPeter Maydell         break;
82*04836414SPeter Maydell     case A_SCSECCTRL:
83*04836414SPeter Maydell         if (!s->is_sse200) {
84*04836414SPeter Maydell             goto bad_offset;
85*04836414SPeter Maydell         }
86*04836414SPeter Maydell         r = s->scsecctrl;
87*04836414SPeter Maydell         break;
88*04836414SPeter Maydell     case A_FCLK_DIV:
89*04836414SPeter Maydell         if (!s->is_sse200) {
90*04836414SPeter Maydell             goto bad_offset;
91*04836414SPeter Maydell         }
92*04836414SPeter Maydell         r = s->fclk_div;
93*04836414SPeter Maydell         break;
94*04836414SPeter Maydell     case A_SYSCLK_DIV:
95*04836414SPeter Maydell         if (!s->is_sse200) {
96*04836414SPeter Maydell             goto bad_offset;
97*04836414SPeter Maydell         }
98*04836414SPeter Maydell         r = s->sysclk_div;
99*04836414SPeter Maydell         break;
100*04836414SPeter Maydell     case A_CLOCK_FORCE:
101*04836414SPeter Maydell         if (!s->is_sse200) {
102*04836414SPeter Maydell             goto bad_offset;
103*04836414SPeter Maydell         }
104*04836414SPeter Maydell         r = s->clock_force;
105*04836414SPeter Maydell         break;
10675750e4dSPeter Maydell     case A_RESET_SYNDROME:
10775750e4dSPeter Maydell         r = s->reset_syndrome;
10875750e4dSPeter Maydell         break;
10975750e4dSPeter Maydell     case A_RESET_MASK:
11075750e4dSPeter Maydell         r = s->reset_mask;
11175750e4dSPeter Maydell         break;
11275750e4dSPeter Maydell     case A_GRETREG:
11375750e4dSPeter Maydell         r = s->gretreg;
11475750e4dSPeter Maydell         break;
115394e10d2SPeter Maydell     case A_INITSVTOR0:
116394e10d2SPeter Maydell         r = s->initsvtor0;
11775750e4dSPeter Maydell         break;
118*04836414SPeter Maydell     case A_INITSVTOR1:
119*04836414SPeter Maydell         if (!s->is_sse200) {
120*04836414SPeter Maydell             goto bad_offset;
121*04836414SPeter Maydell         }
122*04836414SPeter Maydell         r = s->initsvtor1;
123*04836414SPeter Maydell         break;
12475750e4dSPeter Maydell     case A_CPUWAIT:
12575750e4dSPeter Maydell         r = s->cpuwait;
12675750e4dSPeter Maydell         break;
127*04836414SPeter Maydell     case A_NMI_ENABLE:
128*04836414SPeter Maydell         /* In IoTKit this is named BUSWAIT but is marked reserved, R/O, zero */
129*04836414SPeter Maydell         if (!s->is_sse200) {
13075750e4dSPeter Maydell             r = 0;
13175750e4dSPeter Maydell             break;
132*04836414SPeter Maydell         }
133*04836414SPeter Maydell         r = s->nmi_enable;
134*04836414SPeter Maydell         break;
13575750e4dSPeter Maydell     case A_WICCTRL:
13675750e4dSPeter Maydell         r = s->wicctrl;
13775750e4dSPeter Maydell         break;
138*04836414SPeter Maydell     case A_EWCTRL:
139*04836414SPeter Maydell         if (!s->is_sse200) {
140*04836414SPeter Maydell             goto bad_offset;
141*04836414SPeter Maydell         }
142*04836414SPeter Maydell         r = s->ewctrl;
143*04836414SPeter Maydell         break;
144*04836414SPeter Maydell     case A_PDCM_PD_SYS_SENSE:
145*04836414SPeter Maydell         if (!s->is_sse200) {
146*04836414SPeter Maydell             goto bad_offset;
147*04836414SPeter Maydell         }
148*04836414SPeter Maydell         r = s->pdcm_pd_sys_sense;
149*04836414SPeter Maydell         break;
150*04836414SPeter Maydell     case A_PDCM_PD_SRAM0_SENSE:
151*04836414SPeter Maydell         if (!s->is_sse200) {
152*04836414SPeter Maydell             goto bad_offset;
153*04836414SPeter Maydell         }
154*04836414SPeter Maydell         r = s->pdcm_pd_sram0_sense;
155*04836414SPeter Maydell         break;
156*04836414SPeter Maydell     case A_PDCM_PD_SRAM1_SENSE:
157*04836414SPeter Maydell         if (!s->is_sse200) {
158*04836414SPeter Maydell             goto bad_offset;
159*04836414SPeter Maydell         }
160*04836414SPeter Maydell         r = s->pdcm_pd_sram1_sense;
161*04836414SPeter Maydell         break;
162*04836414SPeter Maydell     case A_PDCM_PD_SRAM2_SENSE:
163*04836414SPeter Maydell         if (!s->is_sse200) {
164*04836414SPeter Maydell             goto bad_offset;
165*04836414SPeter Maydell         }
166*04836414SPeter Maydell         r = s->pdcm_pd_sram2_sense;
167*04836414SPeter Maydell         break;
168*04836414SPeter Maydell     case A_PDCM_PD_SRAM3_SENSE:
169*04836414SPeter Maydell         if (!s->is_sse200) {
170*04836414SPeter Maydell             goto bad_offset;
171*04836414SPeter Maydell         }
172*04836414SPeter Maydell         r = s->pdcm_pd_sram3_sense;
173*04836414SPeter Maydell         break;
17475750e4dSPeter Maydell     case A_PID4 ... A_CID3:
17575750e4dSPeter Maydell         r = sysctl_id[(offset - A_PID4) / 4];
17675750e4dSPeter Maydell         break;
17775750e4dSPeter Maydell     case A_SECDBGSET:
17875750e4dSPeter Maydell     case A_SECDBGCLR:
17975750e4dSPeter Maydell     case A_SWRESET:
18075750e4dSPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
18175750e4dSPeter Maydell                       "IoTKit SysCtl read: read of WO offset %x\n",
18275750e4dSPeter Maydell                       (int)offset);
18375750e4dSPeter Maydell         r = 0;
18475750e4dSPeter Maydell         break;
18575750e4dSPeter Maydell     default:
186*04836414SPeter Maydell     bad_offset:
18775750e4dSPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
18875750e4dSPeter Maydell                       "IoTKit SysCtl read: bad offset %x\n", (int)offset);
18975750e4dSPeter Maydell         r = 0;
19075750e4dSPeter Maydell         break;
19175750e4dSPeter Maydell     }
19275750e4dSPeter Maydell     trace_iotkit_sysctl_read(offset, r, size);
19375750e4dSPeter Maydell     return r;
19475750e4dSPeter Maydell }
19575750e4dSPeter Maydell 
19675750e4dSPeter Maydell static void iotkit_sysctl_write(void *opaque, hwaddr offset,
19775750e4dSPeter Maydell                                  uint64_t value, unsigned size)
19875750e4dSPeter Maydell {
19975750e4dSPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
20075750e4dSPeter Maydell 
20175750e4dSPeter Maydell     trace_iotkit_sysctl_write(offset, value, size);
20275750e4dSPeter Maydell 
20375750e4dSPeter Maydell     /*
20475750e4dSPeter Maydell      * Most of the state here has to do with control of reset and
20575750e4dSPeter Maydell      * similar kinds of power up -- for instance the guest can ask
20675750e4dSPeter Maydell      * what the reason for the last reset was, or forbid reset for
20775750e4dSPeter Maydell      * some causes (like the non-secure watchdog). Most of this is
20875750e4dSPeter Maydell      * not relevant to QEMU, which doesn't really model anything other
20975750e4dSPeter Maydell      * than a full power-on reset.
21075750e4dSPeter Maydell      * We just model the registers as reads-as-written.
21175750e4dSPeter Maydell      */
21275750e4dSPeter Maydell 
21375750e4dSPeter Maydell     switch (offset) {
21475750e4dSPeter Maydell     case A_RESET_SYNDROME:
21575750e4dSPeter Maydell         qemu_log_mask(LOG_UNIMP,
21675750e4dSPeter Maydell                       "IoTKit SysCtl RESET_SYNDROME unimplemented\n");
21775750e4dSPeter Maydell         s->reset_syndrome = value;
21875750e4dSPeter Maydell         break;
21975750e4dSPeter Maydell     case A_RESET_MASK:
22075750e4dSPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n");
22175750e4dSPeter Maydell         s->reset_mask = value;
22275750e4dSPeter Maydell         break;
22375750e4dSPeter Maydell     case A_GRETREG:
22475750e4dSPeter Maydell         /*
22575750e4dSPeter Maydell          * General retention register, which is only reset by a power-on
22675750e4dSPeter Maydell          * reset. Technically this implementation is complete, since
22775750e4dSPeter Maydell          * QEMU only supports power-on resets...
22875750e4dSPeter Maydell          */
22975750e4dSPeter Maydell         s->gretreg = value;
23075750e4dSPeter Maydell         break;
231394e10d2SPeter Maydell     case A_INITSVTOR0:
232394e10d2SPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVTOR0 unimplemented\n");
233394e10d2SPeter Maydell         s->initsvtor0 = value;
23475750e4dSPeter Maydell         break;
23575750e4dSPeter Maydell     case A_CPUWAIT:
23675750e4dSPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CPUWAIT unimplemented\n");
23775750e4dSPeter Maydell         s->cpuwait = value;
23875750e4dSPeter Maydell         break;
23975750e4dSPeter Maydell     case A_WICCTRL:
24075750e4dSPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
24175750e4dSPeter Maydell         s->wicctrl = value;
24275750e4dSPeter Maydell         break;
24375750e4dSPeter Maydell     case A_SECDBGSET:
24475750e4dSPeter Maydell         /* write-1-to-set */
24575750e4dSPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n");
24675750e4dSPeter Maydell         s->secure_debug |= value;
24775750e4dSPeter Maydell         break;
24875750e4dSPeter Maydell     case A_SECDBGCLR:
24975750e4dSPeter Maydell         /* write-1-to-clear */
25075750e4dSPeter Maydell         s->secure_debug &= ~value;
25175750e4dSPeter Maydell         break;
25275750e4dSPeter Maydell     case A_SWRESET:
25375750e4dSPeter Maydell         /* One w/o bit to request a reset; all other bits reserved */
25475750e4dSPeter Maydell         if (value & R_SWRESET_SWRESETREQ_MASK) {
25575750e4dSPeter Maydell             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
25675750e4dSPeter Maydell         }
25775750e4dSPeter Maydell         break;
258*04836414SPeter Maydell     case A_SCSECCTRL:
259*04836414SPeter Maydell         if (!s->is_sse200) {
260*04836414SPeter Maydell             goto bad_offset;
261*04836414SPeter Maydell         }
262*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
263*04836414SPeter Maydell         s->scsecctrl = value;
264*04836414SPeter Maydell         break;
265*04836414SPeter Maydell     case A_FCLK_DIV:
266*04836414SPeter Maydell         if (!s->is_sse200) {
267*04836414SPeter Maydell             goto bad_offset;
268*04836414SPeter Maydell         }
269*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
270*04836414SPeter Maydell         s->fclk_div = value;
271*04836414SPeter Maydell         break;
272*04836414SPeter Maydell     case A_SYSCLK_DIV:
273*04836414SPeter Maydell         if (!s->is_sse200) {
274*04836414SPeter Maydell             goto bad_offset;
275*04836414SPeter Maydell         }
276*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
277*04836414SPeter Maydell         s->sysclk_div = value;
278*04836414SPeter Maydell         break;
279*04836414SPeter Maydell     case A_CLOCK_FORCE:
280*04836414SPeter Maydell         if (!s->is_sse200) {
281*04836414SPeter Maydell             goto bad_offset;
282*04836414SPeter Maydell         }
283*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
284*04836414SPeter Maydell         s->clock_force = value;
285*04836414SPeter Maydell         break;
286*04836414SPeter Maydell     case A_INITSVTOR1:
287*04836414SPeter Maydell         if (!s->is_sse200) {
288*04836414SPeter Maydell             goto bad_offset;
289*04836414SPeter Maydell         }
290*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVTOR1 unimplemented\n");
291*04836414SPeter Maydell         s->initsvtor1 = value;
292*04836414SPeter Maydell         break;
293*04836414SPeter Maydell     case A_EWCTRL:
294*04836414SPeter Maydell         if (!s->is_sse200) {
295*04836414SPeter Maydell             goto bad_offset;
296*04836414SPeter Maydell         }
297*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
298*04836414SPeter Maydell         s->ewctrl = value;
299*04836414SPeter Maydell         break;
300*04836414SPeter Maydell     case A_PDCM_PD_SYS_SENSE:
301*04836414SPeter Maydell         if (!s->is_sse200) {
302*04836414SPeter Maydell             goto bad_offset;
303*04836414SPeter Maydell         }
304*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP,
305*04836414SPeter Maydell                       "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
306*04836414SPeter Maydell         s->pdcm_pd_sys_sense = value;
307*04836414SPeter Maydell         break;
308*04836414SPeter Maydell     case A_PDCM_PD_SRAM0_SENSE:
309*04836414SPeter Maydell         if (!s->is_sse200) {
310*04836414SPeter Maydell             goto bad_offset;
311*04836414SPeter Maydell         }
312*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP,
313*04836414SPeter Maydell                       "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
314*04836414SPeter Maydell         s->pdcm_pd_sram0_sense = value;
315*04836414SPeter Maydell         break;
316*04836414SPeter Maydell     case A_PDCM_PD_SRAM1_SENSE:
317*04836414SPeter Maydell         if (!s->is_sse200) {
318*04836414SPeter Maydell             goto bad_offset;
319*04836414SPeter Maydell         }
320*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP,
321*04836414SPeter Maydell                       "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
322*04836414SPeter Maydell         s->pdcm_pd_sram1_sense = value;
323*04836414SPeter Maydell         break;
324*04836414SPeter Maydell     case A_PDCM_PD_SRAM2_SENSE:
325*04836414SPeter Maydell         if (!s->is_sse200) {
326*04836414SPeter Maydell             goto bad_offset;
327*04836414SPeter Maydell         }
328*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP,
329*04836414SPeter Maydell                       "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
330*04836414SPeter Maydell         s->pdcm_pd_sram2_sense = value;
331*04836414SPeter Maydell         break;
332*04836414SPeter Maydell     case A_PDCM_PD_SRAM3_SENSE:
333*04836414SPeter Maydell         if (!s->is_sse200) {
334*04836414SPeter Maydell             goto bad_offset;
335*04836414SPeter Maydell         }
336*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP,
337*04836414SPeter Maydell                       "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
338*04836414SPeter Maydell         s->pdcm_pd_sram3_sense = value;
339*04836414SPeter Maydell         break;
340*04836414SPeter Maydell     case A_NMI_ENABLE:
341*04836414SPeter Maydell         /* In IoTKit this is BUSWAIT: reserved, R/O, zero */
342*04836414SPeter Maydell         if (!s->is_sse200) {
343*04836414SPeter Maydell             goto ro_offset;
344*04836414SPeter Maydell         }
345*04836414SPeter Maydell         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
346*04836414SPeter Maydell         s->nmi_enable = value;
347*04836414SPeter Maydell         break;
34875750e4dSPeter Maydell     case A_SECDBGSTAT:
34975750e4dSPeter Maydell     case A_PID4 ... A_CID3:
350*04836414SPeter Maydell     ro_offset:
35175750e4dSPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
35275750e4dSPeter Maydell                       "IoTKit SysCtl write: write of RO offset %x\n",
35375750e4dSPeter Maydell                       (int)offset);
35475750e4dSPeter Maydell         break;
35575750e4dSPeter Maydell     default:
356*04836414SPeter Maydell     bad_offset:
35775750e4dSPeter Maydell         qemu_log_mask(LOG_GUEST_ERROR,
35875750e4dSPeter Maydell                       "IoTKit SysCtl write: bad offset %x\n", (int)offset);
35975750e4dSPeter Maydell         break;
36075750e4dSPeter Maydell     }
36175750e4dSPeter Maydell }
36275750e4dSPeter Maydell 
36375750e4dSPeter Maydell static const MemoryRegionOps iotkit_sysctl_ops = {
36475750e4dSPeter Maydell     .read = iotkit_sysctl_read,
36575750e4dSPeter Maydell     .write = iotkit_sysctl_write,
36675750e4dSPeter Maydell     .endianness = DEVICE_LITTLE_ENDIAN,
36775750e4dSPeter Maydell     /* byte/halfword accesses are just zero-padded on reads and writes */
36875750e4dSPeter Maydell     .impl.min_access_size = 4,
36975750e4dSPeter Maydell     .impl.max_access_size = 4,
37075750e4dSPeter Maydell     .valid.min_access_size = 1,
37175750e4dSPeter Maydell     .valid.max_access_size = 4,
37275750e4dSPeter Maydell };
37375750e4dSPeter Maydell 
37475750e4dSPeter Maydell static void iotkit_sysctl_reset(DeviceState *dev)
37575750e4dSPeter Maydell {
37675750e4dSPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
37775750e4dSPeter Maydell 
37875750e4dSPeter Maydell     trace_iotkit_sysctl_reset();
37975750e4dSPeter Maydell     s->secure_debug = 0;
38075750e4dSPeter Maydell     s->reset_syndrome = 1;
38175750e4dSPeter Maydell     s->reset_mask = 0;
38275750e4dSPeter Maydell     s->gretreg = 0;
383394e10d2SPeter Maydell     s->initsvtor0 = 0x10000000;
384*04836414SPeter Maydell     s->initsvtor1 = 0x10000000;
38575750e4dSPeter Maydell     s->cpuwait = 0;
38675750e4dSPeter Maydell     s->wicctrl = 0;
387*04836414SPeter Maydell     s->scsecctrl = 0;
388*04836414SPeter Maydell     s->fclk_div = 0;
389*04836414SPeter Maydell     s->sysclk_div = 0;
390*04836414SPeter Maydell     s->clock_force = 0;
391*04836414SPeter Maydell     s->nmi_enable = 0;
392*04836414SPeter Maydell     s->ewctrl = 0;
393*04836414SPeter Maydell     s->pdcm_pd_sys_sense = 0x7f;
394*04836414SPeter Maydell     s->pdcm_pd_sram0_sense = 0;
395*04836414SPeter Maydell     s->pdcm_pd_sram1_sense = 0;
396*04836414SPeter Maydell     s->pdcm_pd_sram2_sense = 0;
397*04836414SPeter Maydell     s->pdcm_pd_sram3_sense = 0;
39875750e4dSPeter Maydell }
39975750e4dSPeter Maydell 
40075750e4dSPeter Maydell static void iotkit_sysctl_init(Object *obj)
40175750e4dSPeter Maydell {
40275750e4dSPeter Maydell     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
40375750e4dSPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(obj);
40475750e4dSPeter Maydell 
40575750e4dSPeter Maydell     memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops,
40675750e4dSPeter Maydell                           s, "iotkit-sysctl", 0x1000);
40775750e4dSPeter Maydell     sysbus_init_mmio(sbd, &s->iomem);
40875750e4dSPeter Maydell }
40975750e4dSPeter Maydell 
410*04836414SPeter Maydell static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
411*04836414SPeter Maydell {
412*04836414SPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
413*04836414SPeter Maydell 
414*04836414SPeter Maydell     /* The top 4 bits of the SYS_VERSION register tell us if we're an SSE-200 */
415*04836414SPeter Maydell     if (extract32(s->sys_version, 28, 4) == 2) {
416*04836414SPeter Maydell         s->is_sse200 = true;
417*04836414SPeter Maydell     }
418*04836414SPeter Maydell }
419*04836414SPeter Maydell 
420*04836414SPeter Maydell static bool sse200_needed(void *opaque)
421*04836414SPeter Maydell {
422*04836414SPeter Maydell     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
423*04836414SPeter Maydell 
424*04836414SPeter Maydell     return s->is_sse200;
425*04836414SPeter Maydell }
426*04836414SPeter Maydell 
427*04836414SPeter Maydell static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
428*04836414SPeter Maydell     .name = "iotkit-sysctl/sse-200",
429*04836414SPeter Maydell     .version_id = 1,
430*04836414SPeter Maydell     .minimum_version_id = 1,
431*04836414SPeter Maydell     .needed = sse200_needed,
432*04836414SPeter Maydell     .fields = (VMStateField[]) {
433*04836414SPeter Maydell         VMSTATE_UINT32(scsecctrl, IoTKitSysCtl),
434*04836414SPeter Maydell         VMSTATE_UINT32(fclk_div, IoTKitSysCtl),
435*04836414SPeter Maydell         VMSTATE_UINT32(sysclk_div, IoTKitSysCtl),
436*04836414SPeter Maydell         VMSTATE_UINT32(clock_force, IoTKitSysCtl),
437*04836414SPeter Maydell         VMSTATE_UINT32(initsvtor1, IoTKitSysCtl),
438*04836414SPeter Maydell         VMSTATE_UINT32(nmi_enable, IoTKitSysCtl),
439*04836414SPeter Maydell         VMSTATE_UINT32(pdcm_pd_sys_sense, IoTKitSysCtl),
440*04836414SPeter Maydell         VMSTATE_UINT32(pdcm_pd_sram0_sense, IoTKitSysCtl),
441*04836414SPeter Maydell         VMSTATE_UINT32(pdcm_pd_sram1_sense, IoTKitSysCtl),
442*04836414SPeter Maydell         VMSTATE_UINT32(pdcm_pd_sram2_sense, IoTKitSysCtl),
443*04836414SPeter Maydell         VMSTATE_UINT32(pdcm_pd_sram3_sense, IoTKitSysCtl),
444*04836414SPeter Maydell         VMSTATE_END_OF_LIST()
445*04836414SPeter Maydell     }
446*04836414SPeter Maydell };
447*04836414SPeter Maydell 
44875750e4dSPeter Maydell static const VMStateDescription iotkit_sysctl_vmstate = {
44975750e4dSPeter Maydell     .name = "iotkit-sysctl",
45075750e4dSPeter Maydell     .version_id = 1,
45175750e4dSPeter Maydell     .minimum_version_id = 1,
45275750e4dSPeter Maydell     .fields = (VMStateField[]) {
45375750e4dSPeter Maydell         VMSTATE_UINT32(secure_debug, IoTKitSysCtl),
45475750e4dSPeter Maydell         VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl),
45575750e4dSPeter Maydell         VMSTATE_UINT32(reset_mask, IoTKitSysCtl),
45675750e4dSPeter Maydell         VMSTATE_UINT32(gretreg, IoTKitSysCtl),
457394e10d2SPeter Maydell         VMSTATE_UINT32(initsvtor0, IoTKitSysCtl),
45875750e4dSPeter Maydell         VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
45975750e4dSPeter Maydell         VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
46075750e4dSPeter Maydell         VMSTATE_END_OF_LIST()
461*04836414SPeter Maydell     },
462*04836414SPeter Maydell     .subsections = (const VMStateDescription*[]) {
463*04836414SPeter Maydell         &iotkit_sysctl_sse200_vmstate,
464*04836414SPeter Maydell         NULL
46575750e4dSPeter Maydell     }
46675750e4dSPeter Maydell };
46775750e4dSPeter Maydell 
468*04836414SPeter Maydell static Property iotkit_sysctl_props[] = {
469*04836414SPeter Maydell     DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysCtl, sys_version, 0),
470*04836414SPeter Maydell     DEFINE_PROP_END_OF_LIST()
471*04836414SPeter Maydell };
472*04836414SPeter Maydell 
47375750e4dSPeter Maydell static void iotkit_sysctl_class_init(ObjectClass *klass, void *data)
47475750e4dSPeter Maydell {
47575750e4dSPeter Maydell     DeviceClass *dc = DEVICE_CLASS(klass);
47675750e4dSPeter Maydell 
47775750e4dSPeter Maydell     dc->vmsd = &iotkit_sysctl_vmstate;
47875750e4dSPeter Maydell     dc->reset = iotkit_sysctl_reset;
479*04836414SPeter Maydell     dc->props = iotkit_sysctl_props;
480*04836414SPeter Maydell     dc->realize = iotkit_sysctl_realize;
48175750e4dSPeter Maydell }
48275750e4dSPeter Maydell 
48375750e4dSPeter Maydell static const TypeInfo iotkit_sysctl_info = {
48475750e4dSPeter Maydell     .name = TYPE_IOTKIT_SYSCTL,
48575750e4dSPeter Maydell     .parent = TYPE_SYS_BUS_DEVICE,
48675750e4dSPeter Maydell     .instance_size = sizeof(IoTKitSysCtl),
48775750e4dSPeter Maydell     .instance_init = iotkit_sysctl_init,
48875750e4dSPeter Maydell     .class_init = iotkit_sysctl_class_init,
48975750e4dSPeter Maydell };
49075750e4dSPeter Maydell 
49175750e4dSPeter Maydell static void iotkit_sysctl_register_types(void)
49275750e4dSPeter Maydell {
49375750e4dSPeter Maydell     type_register_static(&iotkit_sysctl_info);
49475750e4dSPeter Maydell }
49575750e4dSPeter Maydell 
49675750e4dSPeter Maydell type_init(iotkit_sysctl_register_types);
497