xref: /openbmc/qemu/hw/misc/iotkit-sysctl.c (revision 24496b8d)
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  * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
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 "trace.h"
23 #include "qapi/error.h"
24 #include "sysemu/sysemu.h"
25 #include "hw/sysbus.h"
26 #include "hw/registerfields.h"
27 #include "hw/misc/iotkit-sysctl.h"
28 #include "target/arm/arm-powerctl.h"
29 #include "target/arm/cpu.h"
30 
31 REG32(SECDBGSTAT, 0x0)
32 REG32(SECDBGSET, 0x4)
33 REG32(SECDBGCLR, 0x8)
34 REG32(SCSECCTRL, 0xc)
35 REG32(FCLK_DIV, 0x10)
36 REG32(SYSCLK_DIV, 0x14)
37 REG32(CLOCK_FORCE, 0x18)
38 REG32(RESET_SYNDROME, 0x100)
39 REG32(RESET_MASK, 0x104)
40 REG32(SWRESET, 0x108)
41     FIELD(SWRESET, SWRESETREQ, 9, 1)
42 REG32(GRETREG, 0x10c)
43 REG32(INITSVTOR0, 0x110)
44 REG32(INITSVTOR1, 0x114)
45 REG32(CPUWAIT, 0x118)
46 REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
47 REG32(WICCTRL, 0x120)
48 REG32(EWCTRL, 0x124)
49 REG32(PDCM_PD_SYS_SENSE, 0x200)
50 REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
51 REG32(PDCM_PD_SRAM1_SENSE, 0x210)
52 REG32(PDCM_PD_SRAM2_SENSE, 0x214)
53 REG32(PDCM_PD_SRAM3_SENSE, 0x218)
54 REG32(PID4, 0xfd0)
55 REG32(PID5, 0xfd4)
56 REG32(PID6, 0xfd8)
57 REG32(PID7, 0xfdc)
58 REG32(PID0, 0xfe0)
59 REG32(PID1, 0xfe4)
60 REG32(PID2, 0xfe8)
61 REG32(PID3, 0xfec)
62 REG32(CID0, 0xff0)
63 REG32(CID1, 0xff4)
64 REG32(CID2, 0xff8)
65 REG32(CID3, 0xffc)
66 
67 /* PID/CID values */
68 static const int sysctl_id[] = {
69     0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
70     0x54, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
71     0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
72 };
73 
74 /*
75  * Set the initial secure vector table offset address for the core.
76  * This will take effect when the CPU next resets.
77  */
78 static void set_init_vtor(uint64_t cpuid, uint32_t vtor)
79 {
80     Object *cpuobj = OBJECT(arm_get_cpu_by_id(cpuid));
81 
82     if (cpuobj) {
83         if (object_property_find(cpuobj, "init-svtor", NULL)) {
84             object_property_set_uint(cpuobj, vtor, "init-svtor", &error_abort);
85         }
86     }
87 }
88 
89 static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
90                                     unsigned size)
91 {
92     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
93     uint64_t r;
94 
95     switch (offset) {
96     case A_SECDBGSTAT:
97         r = s->secure_debug;
98         break;
99     case A_SCSECCTRL:
100         if (!s->is_sse200) {
101             goto bad_offset;
102         }
103         r = s->scsecctrl;
104         break;
105     case A_FCLK_DIV:
106         if (!s->is_sse200) {
107             goto bad_offset;
108         }
109         r = s->fclk_div;
110         break;
111     case A_SYSCLK_DIV:
112         if (!s->is_sse200) {
113             goto bad_offset;
114         }
115         r = s->sysclk_div;
116         break;
117     case A_CLOCK_FORCE:
118         if (!s->is_sse200) {
119             goto bad_offset;
120         }
121         r = s->clock_force;
122         break;
123     case A_RESET_SYNDROME:
124         r = s->reset_syndrome;
125         break;
126     case A_RESET_MASK:
127         r = s->reset_mask;
128         break;
129     case A_GRETREG:
130         r = s->gretreg;
131         break;
132     case A_INITSVTOR0:
133         r = s->initsvtor0;
134         break;
135     case A_INITSVTOR1:
136         if (!s->is_sse200) {
137             goto bad_offset;
138         }
139         r = s->initsvtor1;
140         break;
141     case A_CPUWAIT:
142         r = s->cpuwait;
143         break;
144     case A_NMI_ENABLE:
145         /* In IoTKit this is named BUSWAIT but is marked reserved, R/O, zero */
146         if (!s->is_sse200) {
147             r = 0;
148             break;
149         }
150         r = s->nmi_enable;
151         break;
152     case A_WICCTRL:
153         r = s->wicctrl;
154         break;
155     case A_EWCTRL:
156         if (!s->is_sse200) {
157             goto bad_offset;
158         }
159         r = s->ewctrl;
160         break;
161     case A_PDCM_PD_SYS_SENSE:
162         if (!s->is_sse200) {
163             goto bad_offset;
164         }
165         r = s->pdcm_pd_sys_sense;
166         break;
167     case A_PDCM_PD_SRAM0_SENSE:
168         if (!s->is_sse200) {
169             goto bad_offset;
170         }
171         r = s->pdcm_pd_sram0_sense;
172         break;
173     case A_PDCM_PD_SRAM1_SENSE:
174         if (!s->is_sse200) {
175             goto bad_offset;
176         }
177         r = s->pdcm_pd_sram1_sense;
178         break;
179     case A_PDCM_PD_SRAM2_SENSE:
180         if (!s->is_sse200) {
181             goto bad_offset;
182         }
183         r = s->pdcm_pd_sram2_sense;
184         break;
185     case A_PDCM_PD_SRAM3_SENSE:
186         if (!s->is_sse200) {
187             goto bad_offset;
188         }
189         r = s->pdcm_pd_sram3_sense;
190         break;
191     case A_PID4 ... A_CID3:
192         r = sysctl_id[(offset - A_PID4) / 4];
193         break;
194     case A_SECDBGSET:
195     case A_SECDBGCLR:
196     case A_SWRESET:
197         qemu_log_mask(LOG_GUEST_ERROR,
198                       "IoTKit SysCtl read: read of WO offset %x\n",
199                       (int)offset);
200         r = 0;
201         break;
202     default:
203     bad_offset:
204         qemu_log_mask(LOG_GUEST_ERROR,
205                       "IoTKit SysCtl read: bad offset %x\n", (int)offset);
206         r = 0;
207         break;
208     }
209     trace_iotkit_sysctl_read(offset, r, size);
210     return r;
211 }
212 
213 static void iotkit_sysctl_write(void *opaque, hwaddr offset,
214                                  uint64_t value, unsigned size)
215 {
216     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
217 
218     trace_iotkit_sysctl_write(offset, value, size);
219 
220     /*
221      * Most of the state here has to do with control of reset and
222      * similar kinds of power up -- for instance the guest can ask
223      * what the reason for the last reset was, or forbid reset for
224      * some causes (like the non-secure watchdog). Most of this is
225      * not relevant to QEMU, which doesn't really model anything other
226      * than a full power-on reset.
227      * We just model the registers as reads-as-written.
228      */
229 
230     switch (offset) {
231     case A_RESET_SYNDROME:
232         qemu_log_mask(LOG_UNIMP,
233                       "IoTKit SysCtl RESET_SYNDROME unimplemented\n");
234         s->reset_syndrome = value;
235         break;
236     case A_RESET_MASK:
237         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl RESET_MASK unimplemented\n");
238         s->reset_mask = value;
239         break;
240     case A_GRETREG:
241         /*
242          * General retention register, which is only reset by a power-on
243          * reset. Technically this implementation is complete, since
244          * QEMU only supports power-on resets...
245          */
246         s->gretreg = value;
247         break;
248     case A_INITSVTOR0:
249         s->initsvtor0 = value;
250         set_init_vtor(0, s->initsvtor0);
251         break;
252     case A_CPUWAIT:
253         if ((s->cpuwait & 1) && !(value & 1)) {
254             /* Powering up CPU 0 */
255             arm_set_cpu_on_and_reset(0);
256         }
257         if ((s->cpuwait & 2) && !(value & 2)) {
258             /* Powering up CPU 1 */
259             arm_set_cpu_on_and_reset(1);
260         }
261         s->cpuwait = value;
262         break;
263     case A_WICCTRL:
264         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl WICCTRL unimplemented\n");
265         s->wicctrl = value;
266         break;
267     case A_SECDBGSET:
268         /* write-1-to-set */
269         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SECDBGSET unimplemented\n");
270         s->secure_debug |= value;
271         break;
272     case A_SECDBGCLR:
273         /* write-1-to-clear */
274         s->secure_debug &= ~value;
275         break;
276     case A_SWRESET:
277         /* One w/o bit to request a reset; all other bits reserved */
278         if (value & R_SWRESET_SWRESETREQ_MASK) {
279             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
280         }
281         break;
282     case A_SCSECCTRL:
283         if (!s->is_sse200) {
284             goto bad_offset;
285         }
286         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
287         s->scsecctrl = value;
288         break;
289     case A_FCLK_DIV:
290         if (!s->is_sse200) {
291             goto bad_offset;
292         }
293         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
294         s->fclk_div = value;
295         break;
296     case A_SYSCLK_DIV:
297         if (!s->is_sse200) {
298             goto bad_offset;
299         }
300         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
301         s->sysclk_div = value;
302         break;
303     case A_CLOCK_FORCE:
304         if (!s->is_sse200) {
305             goto bad_offset;
306         }
307         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
308         s->clock_force = value;
309         break;
310     case A_INITSVTOR1:
311         if (!s->is_sse200) {
312             goto bad_offset;
313         }
314         s->initsvtor1 = value;
315         set_init_vtor(1, s->initsvtor1);
316         break;
317     case A_EWCTRL:
318         if (!s->is_sse200) {
319             goto bad_offset;
320         }
321         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
322         s->ewctrl = value;
323         break;
324     case A_PDCM_PD_SYS_SENSE:
325         if (!s->is_sse200) {
326             goto bad_offset;
327         }
328         qemu_log_mask(LOG_UNIMP,
329                       "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
330         s->pdcm_pd_sys_sense = value;
331         break;
332     case A_PDCM_PD_SRAM0_SENSE:
333         if (!s->is_sse200) {
334             goto bad_offset;
335         }
336         qemu_log_mask(LOG_UNIMP,
337                       "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
338         s->pdcm_pd_sram0_sense = value;
339         break;
340     case A_PDCM_PD_SRAM1_SENSE:
341         if (!s->is_sse200) {
342             goto bad_offset;
343         }
344         qemu_log_mask(LOG_UNIMP,
345                       "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
346         s->pdcm_pd_sram1_sense = value;
347         break;
348     case A_PDCM_PD_SRAM2_SENSE:
349         if (!s->is_sse200) {
350             goto bad_offset;
351         }
352         qemu_log_mask(LOG_UNIMP,
353                       "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
354         s->pdcm_pd_sram2_sense = value;
355         break;
356     case A_PDCM_PD_SRAM3_SENSE:
357         if (!s->is_sse200) {
358             goto bad_offset;
359         }
360         qemu_log_mask(LOG_UNIMP,
361                       "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
362         s->pdcm_pd_sram3_sense = value;
363         break;
364     case A_NMI_ENABLE:
365         /* In IoTKit this is BUSWAIT: reserved, R/O, zero */
366         if (!s->is_sse200) {
367             goto ro_offset;
368         }
369         qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
370         s->nmi_enable = value;
371         break;
372     case A_SECDBGSTAT:
373     case A_PID4 ... A_CID3:
374     ro_offset:
375         qemu_log_mask(LOG_GUEST_ERROR,
376                       "IoTKit SysCtl write: write of RO offset %x\n",
377                       (int)offset);
378         break;
379     default:
380     bad_offset:
381         qemu_log_mask(LOG_GUEST_ERROR,
382                       "IoTKit SysCtl write: bad offset %x\n", (int)offset);
383         break;
384     }
385 }
386 
387 static const MemoryRegionOps iotkit_sysctl_ops = {
388     .read = iotkit_sysctl_read,
389     .write = iotkit_sysctl_write,
390     .endianness = DEVICE_LITTLE_ENDIAN,
391     /* byte/halfword accesses are just zero-padded on reads and writes */
392     .impl.min_access_size = 4,
393     .impl.max_access_size = 4,
394     .valid.min_access_size = 1,
395     .valid.max_access_size = 4,
396 };
397 
398 static void iotkit_sysctl_reset(DeviceState *dev)
399 {
400     IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
401 
402     trace_iotkit_sysctl_reset();
403     s->secure_debug = 0;
404     s->reset_syndrome = 1;
405     s->reset_mask = 0;
406     s->gretreg = 0;
407     s->initsvtor0 = s->initsvtor0_rst;
408     s->initsvtor1 = s->initsvtor1_rst;
409     s->cpuwait = s->cpuwait_rst;
410     s->wicctrl = 0;
411     s->scsecctrl = 0;
412     s->fclk_div = 0;
413     s->sysclk_div = 0;
414     s->clock_force = 0;
415     s->nmi_enable = 0;
416     s->ewctrl = 0;
417     s->pdcm_pd_sys_sense = 0x7f;
418     s->pdcm_pd_sram0_sense = 0;
419     s->pdcm_pd_sram1_sense = 0;
420     s->pdcm_pd_sram2_sense = 0;
421     s->pdcm_pd_sram3_sense = 0;
422 }
423 
424 static void iotkit_sysctl_init(Object *obj)
425 {
426     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
427     IoTKitSysCtl *s = IOTKIT_SYSCTL(obj);
428 
429     memory_region_init_io(&s->iomem, obj, &iotkit_sysctl_ops,
430                           s, "iotkit-sysctl", 0x1000);
431     sysbus_init_mmio(sbd, &s->iomem);
432 }
433 
434 static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
435 {
436     IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
437 
438     /* The top 4 bits of the SYS_VERSION register tell us if we're an SSE-200 */
439     if (extract32(s->sys_version, 28, 4) == 2) {
440         s->is_sse200 = true;
441     }
442 }
443 
444 static bool sse200_needed(void *opaque)
445 {
446     IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
447 
448     return s->is_sse200;
449 }
450 
451 static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
452     .name = "iotkit-sysctl/sse-200",
453     .version_id = 1,
454     .minimum_version_id = 1,
455     .needed = sse200_needed,
456     .fields = (VMStateField[]) {
457         VMSTATE_UINT32(scsecctrl, IoTKitSysCtl),
458         VMSTATE_UINT32(fclk_div, IoTKitSysCtl),
459         VMSTATE_UINT32(sysclk_div, IoTKitSysCtl),
460         VMSTATE_UINT32(clock_force, IoTKitSysCtl),
461         VMSTATE_UINT32(initsvtor1, IoTKitSysCtl),
462         VMSTATE_UINT32(nmi_enable, IoTKitSysCtl),
463         VMSTATE_UINT32(pdcm_pd_sys_sense, IoTKitSysCtl),
464         VMSTATE_UINT32(pdcm_pd_sram0_sense, IoTKitSysCtl),
465         VMSTATE_UINT32(pdcm_pd_sram1_sense, IoTKitSysCtl),
466         VMSTATE_UINT32(pdcm_pd_sram2_sense, IoTKitSysCtl),
467         VMSTATE_UINT32(pdcm_pd_sram3_sense, IoTKitSysCtl),
468         VMSTATE_END_OF_LIST()
469     }
470 };
471 
472 static const VMStateDescription iotkit_sysctl_vmstate = {
473     .name = "iotkit-sysctl",
474     .version_id = 1,
475     .minimum_version_id = 1,
476     .fields = (VMStateField[]) {
477         VMSTATE_UINT32(secure_debug, IoTKitSysCtl),
478         VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl),
479         VMSTATE_UINT32(reset_mask, IoTKitSysCtl),
480         VMSTATE_UINT32(gretreg, IoTKitSysCtl),
481         VMSTATE_UINT32(initsvtor0, IoTKitSysCtl),
482         VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
483         VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
484         VMSTATE_END_OF_LIST()
485     },
486     .subsections = (const VMStateDescription*[]) {
487         &iotkit_sysctl_sse200_vmstate,
488         NULL
489     }
490 };
491 
492 static Property iotkit_sysctl_props[] = {
493     DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysCtl, sys_version, 0),
494     DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0),
495     DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst,
496                        0x10000000),
497     DEFINE_PROP_UINT32("INITSVTOR1_RST", IoTKitSysCtl, initsvtor1_rst,
498                        0x10000000),
499     DEFINE_PROP_END_OF_LIST()
500 };
501 
502 static void iotkit_sysctl_class_init(ObjectClass *klass, void *data)
503 {
504     DeviceClass *dc = DEVICE_CLASS(klass);
505 
506     dc->vmsd = &iotkit_sysctl_vmstate;
507     dc->reset = iotkit_sysctl_reset;
508     dc->props = iotkit_sysctl_props;
509     dc->realize = iotkit_sysctl_realize;
510 }
511 
512 static const TypeInfo iotkit_sysctl_info = {
513     .name = TYPE_IOTKIT_SYSCTL,
514     .parent = TYPE_SYS_BUS_DEVICE,
515     .instance_size = sizeof(IoTKitSysCtl),
516     .instance_init = iotkit_sysctl_init,
517     .class_init = iotkit_sysctl_class_init,
518 };
519 
520 static void iotkit_sysctl_register_types(void)
521 {
522     type_register_static(&iotkit_sysctl_info);
523 }
524 
525 type_init(iotkit_sysctl_register_types);
526