1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
35REG32(SECDBGSTAT, 0x0)
36REG32(SECDBGSET, 0x4)
37REG32(SECDBGCLR, 0x8)
38REG32(SCSECCTRL, 0xc)
39REG32(FCLK_DIV, 0x10)
40REG32(SYSCLK_DIV, 0x14)
41REG32(CLOCK_FORCE, 0x18)
42REG32(RESET_SYNDROME, 0x100)
43REG32(RESET_MASK, 0x104)
44REG32(SWRESET, 0x108)
45 FIELD(SWRESET, SWRESETREQ, 9, 1)
46REG32(GRETREG, 0x10c)
47REG32(INITSVTOR0, 0x110)
48 FIELD(INITSVTOR0, LOCK, 0, 1)
49 FIELD(INITSVTOR0, VTOR, 7, 25)
50REG32(INITSVTOR1, 0x114)
51REG32(CPUWAIT, 0x118)
52REG32(NMI_ENABLE, 0x11c)
53REG32(WICCTRL, 0x120)
54REG32(EWCTRL, 0x124)
55REG32(PWRCTRL, 0x1fc)
56 FIELD(PWRCTRL, PPU_ACCESS_UNLOCK, 0, 1)
57 FIELD(PWRCTRL, PPU_ACCESS_FILTER, 1, 1)
58REG32(PDCM_PD_SYS_SENSE, 0x200)
59REG32(PDCM_PD_CPU0_SENSE, 0x204)
60REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
61REG32(PDCM_PD_SRAM1_SENSE, 0x210)
62REG32(PDCM_PD_SRAM2_SENSE, 0x214)
63REG32(PDCM_PD_SRAM3_SENSE, 0x218)
64REG32(PID4, 0xfd0)
65REG32(PID5, 0xfd4)
66REG32(PID6, 0xfd8)
67REG32(PID7, 0xfdc)
68REG32(PID0, 0xfe0)
69REG32(PID1, 0xfe4)
70REG32(PID2, 0xfe8)
71REG32(PID3, 0xfec)
72REG32(CID0, 0xff0)
73REG32(CID1, 0xff4)
74REG32(CID2, 0xff8)
75REG32(CID3, 0xffc)
76
77
78static const int iotkit_sysctl_id[] = {
79 0x04, 0x00, 0x00, 0x00,
80 0x54, 0xb8, 0x0b, 0x00,
81 0x0d, 0xf0, 0x05, 0xb1,
82};
83
84
85static const int sse200_sysctl_id[] = {
86 0x04, 0x00, 0x00, 0x00,
87 0x54, 0xb8, 0x1b, 0x00,
88 0x0d, 0xf0, 0x05, 0xb1,
89};
90
91
92
93
94
95static void set_init_vtor(uint64_t cpuid, uint32_t vtor)
96{
97 Object *cpuobj = OBJECT(arm_get_cpu_by_id(cpuid));
98
99 if (cpuobj) {
100 if (object_property_find(cpuobj, "init-svtor")) {
101 object_property_set_uint(cpuobj, "init-svtor", vtor, &error_abort);
102 }
103 }
104}
105
106static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
107 unsigned size)
108{
109 IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
110 uint64_t r;
111
112 switch (offset) {
113 case A_SECDBGSTAT:
114 r = s->secure_debug;
115 break;
116 case A_SCSECCTRL:
117 switch (s->sse_version) {
118 case ARMSSE_IOTKIT:
119 goto bad_offset;
120 case ARMSSE_SSE200:
121 case ARMSSE_SSE300:
122 r = s->scsecctrl;
123 break;
124 default:
125 g_assert_not_reached();
126 }
127 break;
128 case A_FCLK_DIV:
129 switch (s->sse_version) {
130 case ARMSSE_IOTKIT:
131 goto bad_offset;
132 case ARMSSE_SSE200:
133 case ARMSSE_SSE300:
134 r = s->fclk_div;
135 break;
136 default:
137 g_assert_not_reached();
138 }
139 break;
140 case A_SYSCLK_DIV:
141 switch (s->sse_version) {
142 case ARMSSE_IOTKIT:
143 goto bad_offset;
144 case ARMSSE_SSE200:
145 case ARMSSE_SSE300:
146 r = s->sysclk_div;
147 break;
148 default:
149 g_assert_not_reached();
150 }
151 break;
152 case A_CLOCK_FORCE:
153 switch (s->sse_version) {
154 case ARMSSE_IOTKIT:
155 goto bad_offset;
156 case ARMSSE_SSE200:
157 case ARMSSE_SSE300:
158 r = s->clock_force;
159 break;
160 default:
161 g_assert_not_reached();
162 }
163 break;
164 case A_RESET_SYNDROME:
165 r = s->reset_syndrome;
166 break;
167 case A_RESET_MASK:
168 r = s->reset_mask;
169 break;
170 case A_GRETREG:
171 r = s->gretreg;
172 break;
173 case A_INITSVTOR0:
174 r = s->initsvtor0;
175 break;
176 case A_INITSVTOR1:
177 switch (s->sse_version) {
178 case ARMSSE_IOTKIT:
179 goto bad_offset;
180 case ARMSSE_SSE200:
181 r = s->initsvtor1;
182 break;
183 case ARMSSE_SSE300:
184 goto bad_offset;
185 default:
186 g_assert_not_reached();
187 }
188 break;
189 case A_CPUWAIT:
190 switch (s->sse_version) {
191 case ARMSSE_IOTKIT:
192 case ARMSSE_SSE200:
193 r = s->cpuwait;
194 break;
195 case ARMSSE_SSE300:
196
197 goto bad_offset;
198 default:
199 g_assert_not_reached();
200 }
201 break;
202 case A_NMI_ENABLE:
203 switch (s->sse_version) {
204 case ARMSSE_IOTKIT:
205
206 r = 0;
207 break;
208 case ARMSSE_SSE200:
209 r = s->nmi_enable;
210 break;
211 case ARMSSE_SSE300:
212
213 goto bad_offset;
214 default:
215 g_assert_not_reached();
216 }
217 break;
218 case A_WICCTRL:
219 switch (s->sse_version) {
220 case ARMSSE_IOTKIT:
221 case ARMSSE_SSE200:
222 r = s->wicctrl;
223 break;
224 case ARMSSE_SSE300:
225
226 r = s->cpuwait;
227 break;
228 default:
229 g_assert_not_reached();
230 }
231 break;
232 case A_EWCTRL:
233 switch (s->sse_version) {
234 case ARMSSE_IOTKIT:
235 goto bad_offset;
236 case ARMSSE_SSE200:
237 r = s->ewctrl;
238 break;
239 case ARMSSE_SSE300:
240
241 r = s->nmi_enable;
242 break;
243 default:
244 g_assert_not_reached();
245 }
246 break;
247 case A_PWRCTRL:
248 switch (s->sse_version) {
249 case ARMSSE_IOTKIT:
250 case ARMSSE_SSE200:
251 goto bad_offset;
252 case ARMSSE_SSE300:
253 r = s->pwrctrl;
254 break;
255 default:
256 g_assert_not_reached();
257 }
258 break;
259 case A_PDCM_PD_SYS_SENSE:
260 switch (s->sse_version) {
261 case ARMSSE_IOTKIT:
262 goto bad_offset;
263 case ARMSSE_SSE200:
264 case ARMSSE_SSE300:
265 r = s->pdcm_pd_sys_sense;
266 break;
267 default:
268 g_assert_not_reached();
269 }
270 break;
271 case A_PDCM_PD_CPU0_SENSE:
272 switch (s->sse_version) {
273 case ARMSSE_IOTKIT:
274 case ARMSSE_SSE200:
275 goto bad_offset;
276 case ARMSSE_SSE300:
277 r = s->pdcm_pd_cpu0_sense;
278 break;
279 default:
280 g_assert_not_reached();
281 }
282 break;
283 case A_PDCM_PD_SRAM0_SENSE:
284 switch (s->sse_version) {
285 case ARMSSE_IOTKIT:
286 goto bad_offset;
287 case ARMSSE_SSE200:
288 r = s->pdcm_pd_sram0_sense;
289 break;
290 case ARMSSE_SSE300:
291 goto bad_offset;
292 default:
293 g_assert_not_reached();
294 }
295 break;
296 case A_PDCM_PD_SRAM1_SENSE:
297 switch (s->sse_version) {
298 case ARMSSE_IOTKIT:
299 goto bad_offset;
300 case ARMSSE_SSE200:
301 r = s->pdcm_pd_sram1_sense;
302 break;
303 case ARMSSE_SSE300:
304 goto bad_offset;
305 default:
306 g_assert_not_reached();
307 }
308 break;
309 case A_PDCM_PD_SRAM2_SENSE:
310 switch (s->sse_version) {
311 case ARMSSE_IOTKIT:
312 goto bad_offset;
313 case ARMSSE_SSE200:
314 r = s->pdcm_pd_sram2_sense;
315 break;
316 case ARMSSE_SSE300:
317 r = s->pdcm_pd_vmr0_sense;
318 break;
319 default:
320 g_assert_not_reached();
321 }
322 break;
323 case A_PDCM_PD_SRAM3_SENSE:
324 switch (s->sse_version) {
325 case ARMSSE_IOTKIT:
326 goto bad_offset;
327 case ARMSSE_SSE200:
328 r = s->pdcm_pd_sram3_sense;
329 break;
330 case ARMSSE_SSE300:
331 r = s->pdcm_pd_vmr1_sense;
332 break;
333 default:
334 g_assert_not_reached();
335 }
336 break;
337 case A_PID4 ... A_CID3:
338 switch (s->sse_version) {
339 case ARMSSE_IOTKIT:
340 r = iotkit_sysctl_id[(offset - A_PID4) / 4];
341 break;
342 case ARMSSE_SSE200:
343 case ARMSSE_SSE300:
344 r = sse200_sysctl_id[(offset - A_PID4) / 4];
345 break;
346 default:
347 g_assert_not_reached();
348 }
349 break;
350 case A_SECDBGSET:
351 case A_SECDBGCLR:
352 case A_SWRESET:
353 qemu_log_mask(LOG_GUEST_ERROR,
354 "IoTKit SysCtl read: read of WO offset %x\n",
355 (int)offset);
356 r = 0;
357 break;
358 default:
359 bad_offset:
360 qemu_log_mask(LOG_GUEST_ERROR,
361 "IoTKit SysCtl read: bad offset %x\n", (int)offset);
362 r = 0;
363 break;
364 }
365 trace_iotkit_sysctl_read(offset, r, size);
366 return r;
367}
368
369static void cpuwait_write(IoTKitSysCtl *s, uint32_t value)
370{
371 int num_cpus = (s->sse_version == ARMSSE_SSE300) ? 1 : 2;
372 int i;
373
374 for (i = 0; i < num_cpus; i++) {
375 uint32_t mask = 1 << i;
376 if ((s->cpuwait & mask) && !(value & mask)) {
377
378 arm_set_cpu_on_and_reset(i);
379 }
380 }
381 s->cpuwait = value;
382}
383
384static void iotkit_sysctl_write(void *opaque, hwaddr offset,
385 uint64_t value, unsigned size)
386{
387 IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
388
389 trace_iotkit_sysctl_write(offset, value, size);
390
391
392
393
394
395
396
397
398
399
400
401 switch (offset) {
402 case A_RESET_SYNDROME:
403 qemu_log_mask(LOG_UNIMP,
404 "IoTKit SysCtl RESET_SYNDROME unimplemented\n");
405 s->reset_syndrome = value;
406 break;
407 case A_RESET_MASK:
408 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n");
409 s->reset_mask = value;
410 break;
411 case A_GRETREG:
412
413
414
415
416
417 s->gretreg = value;
418 break;
419 case A_INITSVTOR0:
420 switch (s->sse_version) {
421 case ARMSSE_SSE300:
422
423 if (s->initsvtor0 & R_INITSVTOR0_LOCK_MASK) {
424 qemu_log_mask(LOG_GUEST_ERROR,
425 "IoTKit INITSVTOR0 write when register locked\n");
426 break;
427 }
428 s->initsvtor0 = value;
429 set_init_vtor(0, s->initsvtor0 & R_INITSVTOR0_VTOR_MASK);
430 break;
431 case ARMSSE_IOTKIT:
432 case ARMSSE_SSE200:
433 s->initsvtor0 = value;
434 set_init_vtor(0, s->initsvtor0);
435 break;
436 default:
437 g_assert_not_reached();
438 }
439 break;
440 case A_CPUWAIT:
441 switch (s->sse_version) {
442 case ARMSSE_IOTKIT:
443 case ARMSSE_SSE200:
444 cpuwait_write(s, value);
445 break;
446 case ARMSSE_SSE300:
447
448 goto bad_offset;
449 default:
450 g_assert_not_reached();
451 }
452 break;
453 case A_WICCTRL:
454 switch (s->sse_version) {
455 case ARMSSE_IOTKIT:
456 case ARMSSE_SSE200:
457 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
458 s->wicctrl = value;
459 break;
460 case ARMSSE_SSE300:
461
462 cpuwait_write(s, value);
463 break;
464 default:
465 g_assert_not_reached();
466 }
467 break;
468 case A_SECDBGSET:
469
470 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n");
471 s->secure_debug |= value;
472 break;
473 case A_SECDBGCLR:
474
475 s->secure_debug &= ~value;
476 break;
477 case A_SWRESET:
478
479 if (value & R_SWRESET_SWRESETREQ_MASK) {
480 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
481 }
482 break;
483 case A_SCSECCTRL:
484 switch (s->sse_version) {
485 case ARMSSE_IOTKIT:
486 goto bad_offset;
487 case ARMSSE_SSE200:
488 case ARMSSE_SSE300:
489 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
490 s->scsecctrl = value;
491 break;
492 default:
493 g_assert_not_reached();
494 }
495 break;
496 case A_FCLK_DIV:
497 switch (s->sse_version) {
498 case ARMSSE_IOTKIT:
499 goto bad_offset;
500 case ARMSSE_SSE200:
501 case ARMSSE_SSE300:
502 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
503 s->fclk_div = value;
504 break;
505 default:
506 g_assert_not_reached();
507 }
508 break;
509 case A_SYSCLK_DIV:
510 switch (s->sse_version) {
511 case ARMSSE_IOTKIT:
512 goto bad_offset;
513 case ARMSSE_SSE200:
514 case ARMSSE_SSE300:
515 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
516 s->sysclk_div = value;
517 break;
518 default:
519 g_assert_not_reached();
520 }
521 break;
522 case A_CLOCK_FORCE:
523 switch (s->sse_version) {
524 case ARMSSE_IOTKIT:
525 goto bad_offset;
526 case ARMSSE_SSE200:
527 case ARMSSE_SSE300:
528 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
529 s->clock_force = value;
530 break;
531 default:
532 g_assert_not_reached();
533 }
534 break;
535 case A_INITSVTOR1:
536 switch (s->sse_version) {
537 case ARMSSE_IOTKIT:
538 goto bad_offset;
539 case ARMSSE_SSE200:
540 s->initsvtor1 = value;
541 set_init_vtor(1, s->initsvtor1);
542 break;
543 case ARMSSE_SSE300:
544 goto bad_offset;
545 default:
546 g_assert_not_reached();
547 }
548 break;
549 case A_EWCTRL:
550 switch (s->sse_version) {
551 case ARMSSE_IOTKIT:
552 goto bad_offset;
553 case ARMSSE_SSE200:
554 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
555 s->ewctrl = value;
556 break;
557 case ARMSSE_SSE300:
558
559 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
560 s->nmi_enable = value;
561 break;
562 default:
563 g_assert_not_reached();
564 }
565 break;
566 case A_PWRCTRL:
567 switch (s->sse_version) {
568 case ARMSSE_IOTKIT:
569 case ARMSSE_SSE200:
570 goto bad_offset;
571 case ARMSSE_SSE300:
572 if (!(s->pwrctrl & R_PWRCTRL_PPU_ACCESS_UNLOCK_MASK)) {
573 qemu_log_mask(LOG_GUEST_ERROR,
574 "IoTKit PWRCTRL write when register locked\n");
575 break;
576 }
577 s->pwrctrl = value;
578 break;
579 default:
580 g_assert_not_reached();
581 }
582 break;
583 case A_PDCM_PD_SYS_SENSE:
584 switch (s->sse_version) {
585 case ARMSSE_IOTKIT:
586 goto bad_offset;
587 case ARMSSE_SSE200:
588 case ARMSSE_SSE300:
589 qemu_log_mask(LOG_UNIMP,
590 "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
591 s->pdcm_pd_sys_sense = value;
592 break;
593 default:
594 g_assert_not_reached();
595 }
596 break;
597 case A_PDCM_PD_CPU0_SENSE:
598 switch (s->sse_version) {
599 case ARMSSE_IOTKIT:
600 case ARMSSE_SSE200:
601 goto bad_offset;
602 case ARMSSE_SSE300:
603 qemu_log_mask(LOG_UNIMP,
604 "IoTKit SysCtl PDCM_PD_CPU0_SENSE unimplemented\n");
605 s->pdcm_pd_cpu0_sense = value;
606 break;
607 default:
608 g_assert_not_reached();
609 }
610 break;
611 case A_PDCM_PD_SRAM0_SENSE:
612 switch (s->sse_version) {
613 case ARMSSE_IOTKIT:
614 goto bad_offset;
615 case ARMSSE_SSE200:
616 qemu_log_mask(LOG_UNIMP,
617 "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
618 s->pdcm_pd_sram0_sense = value;
619 break;
620 case ARMSSE_SSE300:
621 goto bad_offset;
622 default:
623 g_assert_not_reached();
624 }
625 break;
626 case A_PDCM_PD_SRAM1_SENSE:
627 switch (s->sse_version) {
628 case ARMSSE_IOTKIT:
629 goto bad_offset;
630 case ARMSSE_SSE200:
631 qemu_log_mask(LOG_UNIMP,
632 "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
633 s->pdcm_pd_sram1_sense = value;
634 break;
635 case ARMSSE_SSE300:
636 goto bad_offset;
637 default:
638 g_assert_not_reached();
639 }
640 break;
641 case A_PDCM_PD_SRAM2_SENSE:
642 switch (s->sse_version) {
643 case ARMSSE_IOTKIT:
644 goto bad_offset;
645 case ARMSSE_SSE200:
646 qemu_log_mask(LOG_UNIMP,
647 "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
648 s->pdcm_pd_sram2_sense = value;
649 break;
650 case ARMSSE_SSE300:
651 qemu_log_mask(LOG_UNIMP,
652 "IoTKit SysCtl PDCM_PD_VMR0_SENSE unimplemented\n");
653 s->pdcm_pd_vmr0_sense = value;
654 break;
655 default:
656 g_assert_not_reached();
657 }
658 break;
659 case A_PDCM_PD_SRAM3_SENSE:
660 switch (s->sse_version) {
661 case ARMSSE_IOTKIT:
662 goto bad_offset;
663 case ARMSSE_SSE200:
664 qemu_log_mask(LOG_UNIMP,
665 "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
666 s->pdcm_pd_sram3_sense = value;
667 break;
668 case ARMSSE_SSE300:
669 qemu_log_mask(LOG_UNIMP,
670 "IoTKit SysCtl PDCM_PD_VMR1_SENSE unimplemented\n");
671 s->pdcm_pd_vmr1_sense = value;
672 break;
673 default:
674 g_assert_not_reached();
675 }
676 break;
677 case A_NMI_ENABLE:
678
679 switch (s->sse_version) {
680 case ARMSSE_IOTKIT:
681 goto ro_offset;
682 case ARMSSE_SSE200:
683 qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
684 s->nmi_enable = value;
685 break;
686 case ARMSSE_SSE300:
687
688 goto bad_offset;
689 default:
690 g_assert_not_reached();
691 }
692 break;
693 case A_SECDBGSTAT:
694 case A_PID4 ... A_CID3:
695 ro_offset:
696 qemu_log_mask(LOG_GUEST_ERROR,
697 "IoTKit SysCtl write: write of RO offset %x\n",
698 (int)offset);
699 break;
700 default:
701 bad_offset:
702 qemu_log_mask(LOG_GUEST_ERROR,
703 "IoTKit SysCtl write: bad offset %x\n", (int)offset);
704 break;
705 }
706}
707
708static const MemoryRegionOps iotkit_sysctl_ops = {
709 .read = iotkit_sysctl_read,
710 .write = iotkit_sysctl_write,
711 .endianness = DEVICE_LITTLE_ENDIAN,
712
713 .impl.min_access_size = 4,
714 .impl.max_access_size = 4,
715 .valid.min_access_size = 1,
716 .valid.max_access_size = 4,
717};
718
719static void iotkit_sysctl_reset(DeviceState *dev)
720{
721 IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
722
723 trace_iotkit_sysctl_reset();
724 s->secure_debug = 0;
725 s->reset_syndrome = 1;
726 s->reset_mask = 0;
727 s->gretreg = 0;
728 s->initsvtor0 = s->initsvtor0_rst;
729 s->initsvtor1 = s->initsvtor1_rst;
730 s->cpuwait = s->cpuwait_rst;
731 s->wicctrl = 0;
732 s->scsecctrl = 0;
733 s->fclk_div = 0;
734 s->sysclk_div = 0;
735 s->clock_force = 0;
736 s->nmi_enable = 0;
737 s->ewctrl = 0;
738 s->pwrctrl = 0x3;
739 s->pdcm_pd_sys_sense = 0x7f;
740 s->pdcm_pd_sram0_sense = 0;
741 s->pdcm_pd_sram1_sense = 0;
742 s->pdcm_pd_sram2_sense = 0;
743 s->pdcm_pd_sram3_sense = 0;
744 s->pdcm_pd_cpu0_sense = 0;
745 s->pdcm_pd_vmr0_sense = 0;
746 s->pdcm_pd_vmr1_sense = 0;
747}
748
749static void iotkit_sysctl_init(Object *obj)
750{
751 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
752 IoTKitSysCtl *s = IOTKIT_SYSCTL(obj);
753
754 memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops,
755 s, "iotkit-sysctl", 0x1000);
756 sysbus_init_mmio(sbd, &s->iomem);
757}
758
759static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
760{
761 IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
762
763 if (!armsse_version_valid(s->sse_version)) {
764 error_setg(errp, "invalid sse-version value %d", s->sse_version);
765 return;
766 }
767}
768
769static bool sse300_needed(void *opaque)
770{
771 IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
772
773 return s->sse_version == ARMSSE_SSE300;
774}
775
776static const VMStateDescription iotkit_sysctl_sse300_vmstate = {
777 .name = "iotkit-sysctl/sse-300",
778 .version_id = 1,
779 .minimum_version_id = 1,
780 .needed = sse300_needed,
781 .fields = (VMStateField[]) {
782 VMSTATE_UINT32(pwrctrl, IoTKitSysCtl),
783 VMSTATE_UINT32(pdcm_pd_cpu0_sense, IoTKitSysCtl),
784 VMSTATE_UINT32(pdcm_pd_vmr0_sense, IoTKitSysCtl),
785 VMSTATE_UINT32(pdcm_pd_vmr1_sense, IoTKitSysCtl),
786 VMSTATE_END_OF_LIST()
787 }
788};
789
790static bool sse200_needed(void *opaque)
791{
792 IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
793
794 return s->sse_version != ARMSSE_IOTKIT;
795}
796
797static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
798 .name = "iotkit-sysctl/sse-200",
799 .version_id = 1,
800 .minimum_version_id = 1,
801 .needed = sse200_needed,
802 .fields = (VMStateField[]) {
803 VMSTATE_UINT32(scsecctrl, IoTKitSysCtl),
804 VMSTATE_UINT32(fclk_div, IoTKitSysCtl),
805 VMSTATE_UINT32(sysclk_div, IoTKitSysCtl),
806 VMSTATE_UINT32(clock_force, IoTKitSysCtl),
807 VMSTATE_UINT32(initsvtor1, IoTKitSysCtl),
808 VMSTATE_UINT32(nmi_enable, IoTKitSysCtl),
809 VMSTATE_UINT32(pdcm_pd_sys_sense, IoTKitSysCtl),
810 VMSTATE_UINT32(pdcm_pd_sram0_sense, IoTKitSysCtl),
811 VMSTATE_UINT32(pdcm_pd_sram1_sense, IoTKitSysCtl),
812 VMSTATE_UINT32(pdcm_pd_sram2_sense, IoTKitSysCtl),
813 VMSTATE_UINT32(pdcm_pd_sram3_sense, IoTKitSysCtl),
814 VMSTATE_END_OF_LIST()
815 }
816};
817
818static const VMStateDescription iotkit_sysctl_vmstate = {
819 .name = "iotkit-sysctl",
820 .version_id = 1,
821 .minimum_version_id = 1,
822 .fields = (VMStateField[]) {
823 VMSTATE_UINT32(secure_debug, IoTKitSysCtl),
824 VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl),
825 VMSTATE_UINT32(reset_mask, IoTKitSysCtl),
826 VMSTATE_UINT32(gretreg, IoTKitSysCtl),
827 VMSTATE_UINT32(initsvtor0, IoTKitSysCtl),
828 VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
829 VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
830 VMSTATE_END_OF_LIST()
831 },
832 .subsections = (const VMStateDescription*[]) {
833 &iotkit_sysctl_sse200_vmstate,
834 &iotkit_sysctl_sse300_vmstate,
835 NULL
836 }
837};
838
839static Property iotkit_sysctl_props[] = {
840 DEFINE_PROP_UINT32("sse-version", IoTKitSysCtl, sse_version, 0),
841 DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0),
842 DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst,
843 0x10000000),
844 DEFINE_PROP_UINT32("INITSVTOR1_RST", IoTKitSysCtl, initsvtor1_rst,
845 0x10000000),
846 DEFINE_PROP_END_OF_LIST()
847};
848
849static void iotkit_sysctl_class_init(ObjectClass *klass, void *data)
850{
851 DeviceClass *dc = DEVICE_CLASS(klass);
852
853 dc->vmsd = &iotkit_sysctl_vmstate;
854 dc->reset = iotkit_sysctl_reset;
855 device_class_set_props(dc, iotkit_sysctl_props);
856 dc->realize = iotkit_sysctl_realize;
857}
858
859static const TypeInfo iotkit_sysctl_info = {
860 .name = TYPE_IOTKIT_SYSCTL,
861 .parent = TYPE_SYS_BUS_DEVICE,
862 .instance_size = sizeof(IoTKitSysCtl),
863 .instance_init = iotkit_sysctl_init,
864 .class_init = iotkit_sysctl_class_init,
865};
866
867static void iotkit_sysctl_register_types(void)
868{
869 type_register_static(&iotkit_sysctl_info);
870}
871
872type_init(iotkit_sysctl_register_types);
873