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