xref: /qemu/hw/misc/iotkit-sysctl.c (revision 92ecf2d5eeaecec2454e95acf2416162538c1225)
1 /*
2  * ARM IoTKit system control element
3  *
4  * Copyright (c) 2018 Linaro Limited
5  * Written by Peter Maydell
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 or
9  *  (at your option) any later version.
10  */
11 
12 /*
13  * This is a model of the "system control element" which is part of the
14  * Arm IoTKit and documented in
15  * https://developer.arm.com/documentation/ecm0601256/latest
16  * Specifically, it implements the "system control register" blocks.
17  */
18 
19 #include "qemu/osdep.h"
20 #include "qemu/bitops.h"
21 #include "qemu/log.h"
22 #include "qemu/module.h"
23 #include "sysemu/runstate.h"
24 #include "trace.h"
25 #include "qapi/error.h"
26 #include "hw/sysbus.h"
27 #include "migration/vmstate.h"
28 #include "hw/registerfields.h"
29 #include "hw/misc/iotkit-sysctl.h"
30 #include "hw/qdev-properties.h"
31 #include "hw/arm/armsse-version.h"
32 #include "target/arm/arm-powerctl.h"
33 #include "target/arm/cpu.h"
34 
35 REG32(SECDBGSTAT, 0x0)
36 REG32(SECDBGSET, 0x4)
37 REG32(SECDBGCLR, 0x8)
38 REG32(SCSECCTRL, 0xc)
39 REG32(FCLK_DIV, 0x10)
40 REG32(SYSCLK_DIV, 0x14)
41 REG32(CLOCK_FORCE, 0x18)
42 REG32(RESET_SYNDROME, 0x100)
43 REG32(RESET_MASK, 0x104)
44 REG32(SWRESET, 0x108)
45     FIELD(SWRESET, SWRESETREQ, 9, 1)
46 REG32(GRETREG, 0x10c)
47 REG32(INITSVTOR0, 0x110)
48 REG32(INITSVTOR1, 0x114)
49 REG32(CPUWAIT, 0x118)
50 REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
51 REG32(WICCTRL, 0x120)
52 REG32(EWCTRL, 0x124)
53 REG32(PDCM_PD_SYS_SENSE, 0x200)
54 REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
55 REG32(PDCM_PD_SRAM1_SENSE, 0x210)
56 REG32(PDCM_PD_SRAM2_SENSE, 0x214)
57 REG32(PDCM_PD_SRAM3_SENSE, 0x218)
58 REG32(PID4, 0xfd0)
59 REG32(PID5, 0xfd4)
60 REG32(PID6, 0xfd8)
61 REG32(PID7, 0xfdc)
62 REG32(PID0, 0xfe0)
63 REG32(PID1, 0xfe4)
64 REG32(PID2, 0xfe8)
65 REG32(PID3, 0xfec)
66 REG32(CID0, 0xff0)
67 REG32(CID1, 0xff4)
68 REG32(CID2, 0xff8)
69 REG32(CID3, 0xffc)
70 
71 /* PID/CID values */
72 static const int sysctl_id[] = {
73     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
74     0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
75     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
76 };
77 
78 /*
79  * Set the initial secure vector table offset address for the core.
80  * This will take effect when the CPU next resets.
81  */
82 static void set_init_vtor(uint64_t cpuid, uint32_t vtor)
83 {
84     Object *cpuobj = OBJECT(arm_get_cpu_by_id(cpuid));
85 
86     if (cpuobj) {
87         if (object_property_find(cpuobj, "init-svtor")) {
88             object_property_set_uint(cpuobj, "init-svtor", vtor, &error_abort);
89         }
90     }
91 }
92 
93 static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
94                                     unsigned size)
95 {
96     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
97     uint64_t r;
98 
99     switch (offset) {
100     case A_SECDBGSTAT:
101         r = s->secure_debug;
102         break;
103     case A_SCSECCTRL:
104         switch (s->sse_version) {
105         case ARMSSE_IOTKIT:
106             goto bad_offset;
107         case ARMSSE_SSE200:
108         case ARMSSE_SSE300:
109             r = s->scsecctrl;
110             break;
111         default:
112             g_assert_not_reached();
113         }
114         break;
115     case A_FCLK_DIV:
116         switch (s->sse_version) {
117         case ARMSSE_IOTKIT:
118             goto bad_offset;
119         case ARMSSE_SSE200:
120         case ARMSSE_SSE300:
121             r = s->fclk_div;
122             break;
123         default:
124             g_assert_not_reached();
125         }
126         break;
127     case A_SYSCLK_DIV:
128         switch (s->sse_version) {
129         case ARMSSE_IOTKIT:
130             goto bad_offset;
131         case ARMSSE_SSE200:
132         case ARMSSE_SSE300:
133             r = s->sysclk_div;
134             break;
135         default:
136             g_assert_not_reached();
137         }
138         break;
139     case A_CLOCK_FORCE:
140         switch (s->sse_version) {
141         case ARMSSE_IOTKIT:
142             goto bad_offset;
143         case ARMSSE_SSE200:
144         case ARMSSE_SSE300:
145             r = s->clock_force;
146             break;
147         default:
148             g_assert_not_reached();
149         }
150         break;
151     case A_RESET_SYNDROME:
152         r = s->reset_syndrome;
153         break;
154     case A_RESET_MASK:
155         r = s->reset_mask;
156         break;
157     case A_GRETREG:
158         r = s->gretreg;
159         break;
160     case A_INITSVTOR0:
161         r = s->initsvtor0;
162         break;
163     case A_INITSVTOR1:
164         switch (s->sse_version) {
165         case ARMSSE_IOTKIT:
166             goto bad_offset;
167         case ARMSSE_SSE200:
168             r = s->initsvtor1;
169             break;
170         default:
171             g_assert_not_reached();
172         }
173         break;
174     case A_CPUWAIT:
175         switch (s->sse_version) {
176         case ARMSSE_IOTKIT:
177         case ARMSSE_SSE200:
178             r = s->cpuwait;
179             break;
180         case ARMSSE_SSE300:
181             /* In SSE300 this is reserved (for INITSVTOR2) */
182             goto bad_offset;
183         default:
184             g_assert_not_reached();
185         }
186         break;
187     case A_NMI_ENABLE:
188         switch (s->sse_version) {
189         case ARMSSE_IOTKIT:
190             /* In IoTKit this is named BUSWAIT but marked reserved, R/O, zero */
191             r = 0;
192             break;
193         case ARMSSE_SSE200:
194             r = s->nmi_enable;
195             break;
196         case ARMSSE_SSE300:
197             /* In SSE300 this is reserved (for INITSVTOR3) */
198             goto bad_offset;
199         default:
200             g_assert_not_reached();
201         }
202         break;
203     case A_WICCTRL:
204         switch (s->sse_version) {
205         case ARMSSE_IOTKIT:
206         case ARMSSE_SSE200:
207             r = s->wicctrl;
208             break;
209         case ARMSSE_SSE300:
210             /* In SSE300 this offset is CPUWAIT */
211             r = s->cpuwait;
212             break;
213         default:
214             g_assert_not_reached();
215         }
216         break;
217     case A_EWCTRL:
218         switch (s->sse_version) {
219         case ARMSSE_IOTKIT:
220             goto bad_offset;
221         case ARMSSE_SSE200:
222             r = s->ewctrl;
223             break;
224         case ARMSSE_SSE300:
225             /* In SSE300 this offset is is NMI_ENABLE */
226             r = s->nmi_enable;
227             break;
228         default:
229             g_assert_not_reached();
230         }
231         break;
232     case A_PDCM_PD_SYS_SENSE:
233         switch (s->sse_version) {
234         case ARMSSE_IOTKIT:
235             goto bad_offset;
236         case ARMSSE_SSE200:
237         case ARMSSE_SSE300:
238             r = s->pdcm_pd_sys_sense;
239             break;
240         default:
241             g_assert_not_reached();
242         }
243         break;
244     case A_PDCM_PD_SRAM0_SENSE:
245         switch (s->sse_version) {
246         case ARMSSE_IOTKIT:
247             goto bad_offset;
248         case ARMSSE_SSE200:
249             r = s->pdcm_pd_sram0_sense;
250             break;
251         default:
252             g_assert_not_reached();
253         }
254         break;
255     case A_PDCM_PD_SRAM1_SENSE:
256         switch (s->sse_version) {
257         case ARMSSE_IOTKIT:
258             goto bad_offset;
259         case ARMSSE_SSE200:
260             r = s->pdcm_pd_sram1_sense;
261             break;
262         default:
263             g_assert_not_reached();
264         }
265         break;
266     case A_PDCM_PD_SRAM2_SENSE:
267         switch (s->sse_version) {
268         case ARMSSE_IOTKIT:
269             goto bad_offset;
270         case ARMSSE_SSE200:
271             r = s->pdcm_pd_sram2_sense;
272             break;
273         default:
274             g_assert_not_reached();
275         }
276         break;
277     case A_PDCM_PD_SRAM3_SENSE:
278         switch (s->sse_version) {
279         case ARMSSE_IOTKIT:
280             goto bad_offset;
281         case ARMSSE_SSE200:
282             r = s->pdcm_pd_sram3_sense;
283             break;
284         default:
285             g_assert_not_reached();
286         }
287         break;
288     case A_PID4 ... A_CID3:
289         r = sysctl_id[(offset - A_PID4) / 4];
290         break;
291     case A_SECDBGSET:
292     case A_SECDBGCLR:
293     case A_SWRESET:
294         qemu_log_mask(LOG_GUEST_ERROR,
295                       "IoTKit SysCtl read: read of WO offset %x\n",
296                       (int)offset);
297         r = 0;
298         break;
299     default:
300     bad_offset:
301         qemu_log_mask(LOG_GUEST_ERROR,
302                       "IoTKit SysCtl read: bad offset %x\n", (int)offset);
303         r = 0;
304         break;
305     }
306     trace_iotkit_sysctl_read(offset, r, size);
307     return r;
308 }
309 
310 static void cpuwait_write(IoTKitSysCtl *s, uint32_t value)
311 {
312     int num_cpus = (s->sse_version == ARMSSE_SSE300) ? 1 : 2;
313     int i;
314 
315     for (i = 0; i < num_cpus; i++) {
316         uint32_t mask = 1 << i;
317         if ((s->cpuwait & mask) && !(value & mask)) {
318             /* Powering up CPU 0 */
319             arm_set_cpu_on_and_reset(i);
320         }
321     }
322     s->cpuwait = value;
323 }
324 
325 static void iotkit_sysctl_write(void *opaque, hwaddr offset,
326                                  uint64_t value, unsigned size)
327 {
328     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
329 
330     trace_iotkit_sysctl_write(offset, value, size);
331 
332     /*
333      * Most of the state here has to do with control of reset and
334      * similar kinds of power up -- for instance the guest can ask
335      * what the reason for the last reset was, or forbid reset for
336      * some causes (like the non-secure watchdog). Most of this is
337      * not relevant to QEMU, which doesn't really model anything other
338      * than a full power-on reset.
339      * We just model the registers as reads-as-written.
340      */
341 
342     switch (offset) {
343     case A_RESET_SYNDROME:
344         qemu_log_mask(LOG_UNIMP,
345                       "IoTKit SysCtl RESET_SYNDROME unimplemented\n");
346         s->reset_syndrome = value;
347         break;
348     case A_RESET_MASK:
349         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n");
350         s->reset_mask = value;
351         break;
352     case A_GRETREG:
353         /*
354          * General retention register, which is only reset by a power-on
355          * reset. Technically this implementation is complete, since
356          * QEMU only supports power-on resets...
357          */
358         s->gretreg = value;
359         break;
360     case A_INITSVTOR0:
361         s->initsvtor0 = value;
362         set_init_vtor(0, s->initsvtor0);
363         break;
364     case A_CPUWAIT:
365         switch (s->sse_version) {
366         case ARMSSE_IOTKIT:
367         case ARMSSE_SSE200:
368             cpuwait_write(s, value);
369             break;
370         case ARMSSE_SSE300:
371             /* In SSE300 this is reserved (for INITSVTOR2) */
372             goto bad_offset;
373         default:
374             g_assert_not_reached();
375         }
376         break;
377     case A_WICCTRL:
378         switch (s->sse_version) {
379         case ARMSSE_IOTKIT:
380         case ARMSSE_SSE200:
381             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
382             s->wicctrl = value;
383             break;
384         case ARMSSE_SSE300:
385             /* In SSE300 this offset is CPUWAIT */
386             cpuwait_write(s, value);
387             break;
388         default:
389             g_assert_not_reached();
390         }
391         break;
392     case A_SECDBGSET:
393         /* write-1-to-set */
394         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n");
395         s->secure_debug |= value;
396         break;
397     case A_SECDBGCLR:
398         /* write-1-to-clear */
399         s->secure_debug &= ~value;
400         break;
401     case A_SWRESET:
402         /* One w/o bit to request a reset; all other bits reserved */
403         if (value & R_SWRESET_SWRESETREQ_MASK) {
404             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
405         }
406         break;
407     case A_SCSECCTRL:
408         switch (s->sse_version) {
409         case ARMSSE_IOTKIT:
410             goto bad_offset;
411         case ARMSSE_SSE200:
412         case ARMSSE_SSE300:
413             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
414             s->scsecctrl = value;
415             break;
416         default:
417             g_assert_not_reached();
418         }
419         break;
420     case A_FCLK_DIV:
421         switch (s->sse_version) {
422         case ARMSSE_IOTKIT:
423             goto bad_offset;
424         case ARMSSE_SSE200:
425         case ARMSSE_SSE300:
426             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
427             s->fclk_div = value;
428             break;
429         default:
430             g_assert_not_reached();
431         }
432         break;
433     case A_SYSCLK_DIV:
434         switch (s->sse_version) {
435         case ARMSSE_IOTKIT:
436             goto bad_offset;
437         case ARMSSE_SSE200:
438         case ARMSSE_SSE300:
439             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
440             s->sysclk_div = value;
441             break;
442         default:
443             g_assert_not_reached();
444         }
445         break;
446     case A_CLOCK_FORCE:
447         switch (s->sse_version) {
448         case ARMSSE_IOTKIT:
449             goto bad_offset;
450         case ARMSSE_SSE200:
451         case ARMSSE_SSE300:
452             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
453             s->clock_force = value;
454             break;
455         default:
456             g_assert_not_reached();
457         }
458         break;
459     case A_INITSVTOR1:
460         switch (s->sse_version) {
461         case ARMSSE_IOTKIT:
462             goto bad_offset;
463         case ARMSSE_SSE200:
464             s->initsvtor1 = value;
465             set_init_vtor(1, s->initsvtor1);
466             break;
467         default:
468             g_assert_not_reached();
469         }
470         break;
471     case A_EWCTRL:
472         switch (s->sse_version) {
473         case ARMSSE_IOTKIT:
474             goto bad_offset;
475         case ARMSSE_SSE200:
476             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
477             s->ewctrl = value;
478             break;
479         case ARMSSE_SSE300:
480             /* In SSE300 this offset is is NMI_ENABLE */
481             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
482             s->nmi_enable = value;
483             break;
484         default:
485             g_assert_not_reached();
486         }
487         break;
488     case A_PDCM_PD_SYS_SENSE:
489         switch (s->sse_version) {
490         case ARMSSE_IOTKIT:
491             goto bad_offset;
492         case ARMSSE_SSE200:
493         case ARMSSE_SSE300:
494             qemu_log_mask(LOG_UNIMP,
495                           "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
496             s->pdcm_pd_sys_sense = value;
497             break;
498         default:
499             g_assert_not_reached();
500         }
501         break;
502     case A_PDCM_PD_SRAM0_SENSE:
503         switch (s->sse_version) {
504         case ARMSSE_IOTKIT:
505             goto bad_offset;
506         case ARMSSE_SSE200:
507             qemu_log_mask(LOG_UNIMP,
508                           "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
509             s->pdcm_pd_sram0_sense = value;
510             break;
511         default:
512             g_assert_not_reached();
513         }
514         break;
515     case A_PDCM_PD_SRAM1_SENSE:
516         switch (s->sse_version) {
517         case ARMSSE_IOTKIT:
518             goto bad_offset;
519         case ARMSSE_SSE200:
520             qemu_log_mask(LOG_UNIMP,
521                           "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
522             s->pdcm_pd_sram1_sense = value;
523             break;
524         default:
525             g_assert_not_reached();
526         }
527         break;
528     case A_PDCM_PD_SRAM2_SENSE:
529         switch (s->sse_version) {
530         case ARMSSE_IOTKIT:
531             goto bad_offset;
532         case ARMSSE_SSE200:
533             qemu_log_mask(LOG_UNIMP,
534                           "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
535             s->pdcm_pd_sram2_sense = value;
536             break;
537         default:
538             g_assert_not_reached();
539         }
540         break;
541     case A_PDCM_PD_SRAM3_SENSE:
542         switch (s->sse_version) {
543         case ARMSSE_IOTKIT:
544             goto bad_offset;
545         case ARMSSE_SSE200:
546             qemu_log_mask(LOG_UNIMP,
547                           "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
548             s->pdcm_pd_sram3_sense = value;
549             break;
550         default:
551             g_assert_not_reached();
552         }
553         break;
554     case A_NMI_ENABLE:
555         /* In IoTKit this is BUSWAIT: reserved, R/O, zero */
556         switch (s->sse_version) {
557         case ARMSSE_IOTKIT:
558             goto ro_offset;
559         case ARMSSE_SSE200:
560             qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
561             s->nmi_enable = value;
562             break;
563         case ARMSSE_SSE300:
564             /* In SSE300 this is reserved (for INITSVTOR3) */
565             goto bad_offset;
566         default:
567             g_assert_not_reached();
568         }
569         break;
570     case A_SECDBGSTAT:
571     case A_PID4 ... A_CID3:
572     ro_offset:
573         qemu_log_mask(LOG_GUEST_ERROR,
574                       "IoTKit SysCtl write: write of RO offset %x\n",
575                       (int)offset);
576         break;
577     default:
578     bad_offset:
579         qemu_log_mask(LOG_GUEST_ERROR,
580                       "IoTKit SysCtl write: bad offset %x\n", (int)offset);
581         break;
582     }
583 }
584 
585 static const MemoryRegionOps iotkit_sysctl_ops = {
586     .read = iotkit_sysctl_read,
587     .write = iotkit_sysctl_write,
588     .endianness = DEVICE_LITTLE_ENDIAN,
589     /* byte/halfword accesses are just zero-padded on reads and writes */
590     .impl.min_access_size = 4,
591     .impl.max_access_size = 4,
592     .valid.min_access_size = 1,
593     .valid.max_access_size = 4,
594 };
595 
596 static void iotkit_sysctl_reset(DeviceState *dev)
597 {
598     IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
599 
600     trace_iotkit_sysctl_reset();
601     s->secure_debug = 0;
602     s->reset_syndrome = 1;
603     s->reset_mask = 0;
604     s->gretreg = 0;
605     s->initsvtor0 = s->initsvtor0_rst;
606     s->initsvtor1 = s->initsvtor1_rst;
607     s->cpuwait = s->cpuwait_rst;
608     s->wicctrl = 0;
609     s->scsecctrl = 0;
610     s->fclk_div = 0;
611     s->sysclk_div = 0;
612     s->clock_force = 0;
613     s->nmi_enable = 0;
614     s->ewctrl = 0;
615     s->pdcm_pd_sys_sense = 0x7f;
616     s->pdcm_pd_sram0_sense = 0;
617     s->pdcm_pd_sram1_sense = 0;
618     s->pdcm_pd_sram2_sense = 0;
619     s->pdcm_pd_sram3_sense = 0;
620 }
621 
622 static void iotkit_sysctl_init(Object *obj)
623 {
624     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
625     IoTKitSysCtl *s = IOTKIT_SYSCTL(obj);
626 
627     memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops,
628                           s, "iotkit-sysctl", 0x1000);
629     sysbus_init_mmio(sbd, &s->iomem);
630 }
631 
632 static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
633 {
634     IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
635 
636     if (!armsse_version_valid(s->sse_version)) {
637         error_setg(errp, "invalid sse-version value %d", s->sse_version);
638         return;
639     }
640 }
641 
642 static bool sse200_needed(void *opaque)
643 {
644     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
645 
646     return s->sse_version != ARMSSE_IOTKIT;
647 }
648 
649 static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
650     .name = "iotkit-sysctl/sse-200",
651     .version_id = 1,
652     .minimum_version_id = 1,
653     .needed = sse200_needed,
654     .fields = (VMStateField[]) {
655         VMSTATE_UINT32(scsecctrl, IoTKitSysCtl),
656         VMSTATE_UINT32(fclk_div, IoTKitSysCtl),
657         VMSTATE_UINT32(sysclk_div, IoTKitSysCtl),
658         VMSTATE_UINT32(clock_force, IoTKitSysCtl),
659         VMSTATE_UINT32(initsvtor1, IoTKitSysCtl),
660         VMSTATE_UINT32(nmi_enable, IoTKitSysCtl),
661         VMSTATE_UINT32(pdcm_pd_sys_sense, IoTKitSysCtl),
662         VMSTATE_UINT32(pdcm_pd_sram0_sense, IoTKitSysCtl),
663         VMSTATE_UINT32(pdcm_pd_sram1_sense, IoTKitSysCtl),
664         VMSTATE_UINT32(pdcm_pd_sram2_sense, IoTKitSysCtl),
665         VMSTATE_UINT32(pdcm_pd_sram3_sense, IoTKitSysCtl),
666         VMSTATE_END_OF_LIST()
667     }
668 };
669 
670 static const VMStateDescription iotkit_sysctl_vmstate = {
671     .name = "iotkit-sysctl",
672     .version_id = 1,
673     .minimum_version_id = 1,
674     .fields = (VMStateField[]) {
675         VMSTATE_UINT32(secure_debug, IoTKitSysCtl),
676         VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl),
677         VMSTATE_UINT32(reset_mask, IoTKitSysCtl),
678         VMSTATE_UINT32(gretreg, IoTKitSysCtl),
679         VMSTATE_UINT32(initsvtor0, IoTKitSysCtl),
680         VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
681         VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
682         VMSTATE_END_OF_LIST()
683     },
684     .subsections = (const VMStateDescription*[]) {
685         &iotkit_sysctl_sse200_vmstate,
686         NULL
687     }
688 };
689 
690 static Property iotkit_sysctl_props[] = {
691     DEFINE_PROP_UINT32("sse-version", IoTKitSysCtl, sse_version, 0),
692     DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0),
693     DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst,
694                        0x10000000),
695     DEFINE_PROP_UINT32("INITSVTOR1_RST", IoTKitSysCtl, initsvtor1_rst,
696                        0x10000000),
697     DEFINE_PROP_END_OF_LIST()
698 };
699 
700 static void iotkit_sysctl_class_init(ObjectClass *klass, void *data)
701 {
702     DeviceClass *dc = DEVICE_CLASS(klass);
703 
704     dc->vmsd = &iotkit_sysctl_vmstate;
705     dc->reset = iotkit_sysctl_reset;
706     device_class_set_props(dc, iotkit_sysctl_props);
707     dc->realize = iotkit_sysctl_realize;
708 }
709 
710 static const TypeInfo iotkit_sysctl_info = {
711     .name = TYPE_IOTKIT_SYSCTL,
712     .parent = TYPE_SYS_BUS_DEVICE,
713     .instance_size = sizeof(IoTKitSysCtl),
714     .instance_init = iotkit_sysctl_init,
715     .class_init = iotkit_sysctl_class_init,
716 };
717 
718 static void iotkit_sysctl_register_types(void)
719 {
720     type_register_static(&iotkit_sysctl_info);
721 }
722 
723 type_init(iotkit_sysctl_register_types);
724