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