xref: /qemu/hw/arm/armsse.c (revision 984b0c100f74eb4a32b3d44eb80963ee82ebfba5)
1 /*
2  * Arm IoT Kit
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 #include "qemu/osdep.h"
13 #include "qemu/log.h"
14 #include "qapi/error.h"
15 #include "trace.h"
16 #include "hw/sysbus.h"
17 #include "hw/registerfields.h"
18 #include "hw/arm/iotkit.h"
19 #include "hw/misc/unimp.h"
20 #include "hw/arm/arm.h"
21 
22 /* Create an alias region of @size bytes starting at @base
23  * which mirrors the memory starting at @orig.
24  */
25 static void make_alias(IoTKit *s, MemoryRegion *mr, const char *name,
26                        hwaddr base, hwaddr size, hwaddr orig)
27 {
28     memory_region_init_alias(mr, NULL, name, &s->container, orig, size);
29     /* The alias is even lower priority than unimplemented_device regions */
30     memory_region_add_subregion_overlap(&s->container, base, mr, -1500);
31 }
32 
33 static void irq_status_forwarder(void *opaque, int n, int level)
34 {
35     qemu_irq destirq = opaque;
36 
37     qemu_set_irq(destirq, level);
38 }
39 
40 static void nsccfg_handler(void *opaque, int n, int level)
41 {
42     IoTKit *s = IOTKIT(opaque);
43 
44     s->nsccfg = level;
45 }
46 
47 static void iotkit_forward_ppc(IoTKit *s, const char *ppcname, int ppcnum)
48 {
49     /* Each of the 4 AHB and 4 APB PPCs that might be present in a
50      * system using the IoTKit has a collection of control lines which
51      * are provided by the security controller and which we want to
52      * expose as control lines on the IoTKit device itself, so the
53      * code using the IoTKit can wire them up to the PPCs.
54      */
55     SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
56     DeviceState *iotkitdev = DEVICE(s);
57     DeviceState *dev_secctl = DEVICE(&s->secctl);
58     DeviceState *dev_splitter = DEVICE(splitter);
59     char *name;
60 
61     name = g_strdup_printf("%s_nonsec", ppcname);
62     qdev_pass_gpios(dev_secctl, iotkitdev, name);
63     g_free(name);
64     name = g_strdup_printf("%s_ap", ppcname);
65     qdev_pass_gpios(dev_secctl, iotkitdev, name);
66     g_free(name);
67     name = g_strdup_printf("%s_irq_enable", ppcname);
68     qdev_pass_gpios(dev_secctl, iotkitdev, name);
69     g_free(name);
70     name = g_strdup_printf("%s_irq_clear", ppcname);
71     qdev_pass_gpios(dev_secctl, iotkitdev, name);
72     g_free(name);
73 
74     /* irq_status is a little more tricky, because we need to
75      * split it so we can send it both to the security controller
76      * and to our OR gate for the NVIC interrupt line.
77      * Connect up the splitter's outputs, and create a GPIO input
78      * which will pass the line state to the input splitter.
79      */
80     name = g_strdup_printf("%s_irq_status", ppcname);
81     qdev_connect_gpio_out(dev_splitter, 0,
82                           qdev_get_gpio_in_named(dev_secctl,
83                                                  name, 0));
84     qdev_connect_gpio_out(dev_splitter, 1,
85                           qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
86     s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
87     qdev_init_gpio_in_named_with_opaque(iotkitdev, irq_status_forwarder,
88                                         s->irq_status_in[ppcnum], name, 1);
89     g_free(name);
90 }
91 
92 static void iotkit_forward_sec_resp_cfg(IoTKit *s)
93 {
94     /* Forward the 3rd output from the splitter device as a
95      * named GPIO output of the iotkit object.
96      */
97     DeviceState *dev = DEVICE(s);
98     DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
99 
100     qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
101     s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
102                                            s->sec_resp_cfg, 1);
103     qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
104 }
105 
106 static void iotkit_init(Object *obj)
107 {
108     IoTKit *s = IOTKIT(obj);
109     int i;
110 
111     memory_region_init(&s->container, obj, "iotkit-container", UINT64_MAX);
112 
113     sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
114                           TYPE_ARMV7M);
115     qdev_prop_set_string(DEVICE(&s->armv7m), "cpu-type",
116                          ARM_CPU_TYPE_NAME("cortex-m33"));
117 
118     sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
119                           TYPE_IOTKIT_SECCTL);
120     sysbus_init_child_obj(obj, "apb-ppc0", &s->apb_ppc0, sizeof(s->apb_ppc0),
121                           TYPE_TZ_PPC);
122     sysbus_init_child_obj(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
123                           TYPE_TZ_PPC);
124     sysbus_init_child_obj(obj, "mpc", &s->mpc, sizeof(s->mpc), TYPE_TZ_MPC);
125     object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
126                             sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
127                             &error_abort, NULL);
128 
129     for (i = 0; i < ARRAY_SIZE(s->mpc_irq_splitter); i++) {
130         char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
131         SplitIRQ *splitter = &s->mpc_irq_splitter[i];
132 
133         object_initialize_child(obj, name, splitter, sizeof(*splitter),
134                                 TYPE_SPLIT_IRQ, &error_abort, NULL);
135         g_free(name);
136     }
137     sysbus_init_child_obj(obj, "timer0", &s->timer0, sizeof(s->timer0),
138                           TYPE_CMSDK_APB_TIMER);
139     sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1),
140                           TYPE_CMSDK_APB_TIMER);
141     sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
142                           TYPE_UNIMPLEMENTED_DEVICE);
143     object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
144                             sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ,
145                             &error_abort, NULL);
146     object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
147                             sizeof(s->sec_resp_splitter), TYPE_SPLIT_IRQ,
148                             &error_abort, NULL);
149     for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
150         char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
151         SplitIRQ *splitter = &s->ppc_irq_splitter[i];
152 
153         object_initialize_child(obj, name, splitter, sizeof(*splitter),
154                                 TYPE_SPLIT_IRQ, &error_abort, NULL);
155         g_free(name);
156     }
157     sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer),
158                           TYPE_UNIMPLEMENTED_DEVICE);
159 }
160 
161 static void iotkit_exp_irq(void *opaque, int n, int level)
162 {
163     IoTKit *s = IOTKIT(opaque);
164 
165     qemu_set_irq(s->exp_irqs[n], level);
166 }
167 
168 static void iotkit_mpcexp_status(void *opaque, int n, int level)
169 {
170     IoTKit *s = IOTKIT(opaque);
171     qemu_set_irq(s->mpcexp_status_in[n], level);
172 }
173 
174 static void iotkit_realize(DeviceState *dev, Error **errp)
175 {
176     IoTKit *s = IOTKIT(dev);
177     int i;
178     MemoryRegion *mr;
179     Error *err = NULL;
180     SysBusDevice *sbd_apb_ppc0;
181     SysBusDevice *sbd_secctl;
182     DeviceState *dev_apb_ppc0;
183     DeviceState *dev_apb_ppc1;
184     DeviceState *dev_secctl;
185     DeviceState *dev_splitter;
186 
187     if (!s->board_memory) {
188         error_setg(errp, "memory property was not set");
189         return;
190     }
191 
192     if (!s->mainclk_frq) {
193         error_setg(errp, "MAINCLK property was not set");
194         return;
195     }
196 
197     /* Handling of which devices should be available only to secure
198      * code is usually done differently for M profile than for A profile.
199      * Instead of putting some devices only into the secure address space,
200      * devices exist in both address spaces but with hard-wired security
201      * permissions that will cause the CPU to fault for non-secure accesses.
202      *
203      * The IoTKit has an IDAU (Implementation Defined Access Unit),
204      * which specifies hard-wired security permissions for different
205      * areas of the physical address space. For the IoTKit IDAU, the
206      * top 4 bits of the physical address are the IDAU region ID, and
207      * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
208      * region, otherwise it is an S region.
209      *
210      * The various devices and RAMs are generally all mapped twice,
211      * once into a region that the IDAU defines as secure and once
212      * into a non-secure region. They sit behind either a Memory
213      * Protection Controller (for RAM) or a Peripheral Protection
214      * Controller (for devices), which allow a more fine grained
215      * configuration of whether non-secure accesses are permitted.
216      *
217      * (The other place that guest software can configure security
218      * permissions is in the architected SAU (Security Attribution
219      * Unit), which is entirely inside the CPU. The IDAU can upgrade
220      * the security attributes for a region to more restrictive than
221      * the SAU specifies, but cannot downgrade them.)
222      *
223      * 0x10000000..0x1fffffff  alias of 0x00000000..0x0fffffff
224      * 0x20000000..0x2007ffff  32KB FPGA block RAM
225      * 0x30000000..0x3fffffff  alias of 0x20000000..0x2fffffff
226      * 0x40000000..0x4000ffff  base peripheral region 1
227      * 0x40010000..0x4001ffff  CPU peripherals (none for IoTKit)
228      * 0x40020000..0x4002ffff  system control element peripherals
229      * 0x40080000..0x400fffff  base peripheral region 2
230      * 0x50000000..0x5fffffff  alias of 0x40000000..0x4fffffff
231      */
232 
233     memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
234 
235     qdev_prop_set_uint32(DEVICE(&s->armv7m), "num-irq", s->exp_numirq + 32);
236     /* In real hardware the initial Secure VTOR is set from the INITSVTOR0
237      * register in the IoT Kit System Control Register block, and the
238      * initial value of that is in turn specifiable by the FPGA that
239      * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
240      * and simply set the CPU's init-svtor to the IoT Kit default value.
241      */
242     qdev_prop_set_uint32(DEVICE(&s->armv7m), "init-svtor", 0x10000000);
243     object_property_set_link(OBJECT(&s->armv7m), OBJECT(&s->container),
244                              "memory", &err);
245     if (err) {
246         error_propagate(errp, err);
247         return;
248     }
249     object_property_set_link(OBJECT(&s->armv7m), OBJECT(s), "idau", &err);
250     if (err) {
251         error_propagate(errp, err);
252         return;
253     }
254     object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
255     if (err) {
256         error_propagate(errp, err);
257         return;
258     }
259 
260     /* Connect our EXP_IRQ GPIOs to the NVIC's lines 32 and up. */
261     s->exp_irqs = g_new(qemu_irq, s->exp_numirq);
262     for (i = 0; i < s->exp_numirq; i++) {
263         s->exp_irqs[i] = qdev_get_gpio_in(DEVICE(&s->armv7m), i + 32);
264     }
265     qdev_init_gpio_in_named(dev, iotkit_exp_irq, "EXP_IRQ", s->exp_numirq);
266 
267     /* Set up the big aliases first */
268     make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000);
269     make_alias(s, &s->alias2, "alias 2", 0x30000000, 0x10000000, 0x20000000);
270     /* The 0x50000000..0x5fffffff region is not a pure alias: it has
271      * a few extra devices that only appear there (generally the
272      * control interfaces for the protection controllers).
273      * We implement this by mapping those devices over the top of this
274      * alias MR at a higher priority.
275      */
276     make_alias(s, &s->alias3, "alias 3", 0x50000000, 0x10000000, 0x40000000);
277 
278 
279     /* Security controller */
280     object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err);
281     if (err) {
282         error_propagate(errp, err);
283         return;
284     }
285     sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
286     dev_secctl = DEVICE(&s->secctl);
287     sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
288     sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
289 
290     s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
291     qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
292 
293     /* The sec_resp_cfg output from the security controller must be split into
294      * multiple lines, one for each of the PPCs within the IoTKit and one
295      * that will be an output from the IoTKit to the system.
296      */
297     object_property_set_int(OBJECT(&s->sec_resp_splitter), 3,
298                             "num-lines", &err);
299     if (err) {
300         error_propagate(errp, err);
301         return;
302     }
303     object_property_set_bool(OBJECT(&s->sec_resp_splitter), true,
304                              "realized", &err);
305     if (err) {
306         error_propagate(errp, err);
307         return;
308     }
309     dev_splitter = DEVICE(&s->sec_resp_splitter);
310     qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
311                                 qdev_get_gpio_in(dev_splitter, 0));
312 
313     /* This RAM lives behind the Memory Protection Controller */
314     memory_region_init_ram(&s->sram0, NULL, "iotkit.sram0", 0x00008000, &err);
315     if (err) {
316         error_propagate(errp, err);
317         return;
318     }
319     object_property_set_link(OBJECT(&s->mpc), OBJECT(&s->sram0),
320                              "downstream", &err);
321     if (err) {
322         error_propagate(errp, err);
323         return;
324     }
325     object_property_set_bool(OBJECT(&s->mpc), true, "realized", &err);
326     if (err) {
327         error_propagate(errp, err);
328         return;
329     }
330     /* Map the upstream end of the MPC into the right place... */
331     memory_region_add_subregion(&s->container, 0x20000000,
332                                 sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
333                                                        1));
334     /* ...and its register interface */
335     memory_region_add_subregion(&s->container, 0x50083000,
336                                 sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
337                                                        0));
338 
339     /* We must OR together lines from the MPC splitters to go to the NVIC */
340     object_property_set_int(OBJECT(&s->mpc_irq_orgate),
341                             IOTS_NUM_EXP_MPC + IOTS_NUM_MPC, "num-lines", &err);
342     if (err) {
343         error_propagate(errp, err);
344         return;
345     }
346     object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
347                              "realized", &err);
348     if (err) {
349         error_propagate(errp, err);
350         return;
351     }
352     qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
353                           qdev_get_gpio_in(DEVICE(&s->armv7m), 9));
354 
355     /* Devices behind APB PPC0:
356      *   0x40000000: timer0
357      *   0x40001000: timer1
358      *   0x40002000: dual timer
359      * We must configure and realize each downstream device and connect
360      * it to the appropriate PPC port; then we can realize the PPC and
361      * map its upstream ends to the right place in the container.
362      */
363     qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
364     object_property_set_bool(OBJECT(&s->timer0), true, "realized", &err);
365     if (err) {
366         error_propagate(errp, err);
367         return;
368     }
369     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
370                        qdev_get_gpio_in(DEVICE(&s->armv7m), 3));
371     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
372     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err);
373     if (err) {
374         error_propagate(errp, err);
375         return;
376     }
377 
378     qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
379     object_property_set_bool(OBJECT(&s->timer1), true, "realized", &err);
380     if (err) {
381         error_propagate(errp, err);
382         return;
383     }
384     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
385                        qdev_get_gpio_in(DEVICE(&s->armv7m), 4));
386     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
387     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err);
388     if (err) {
389         error_propagate(errp, err);
390         return;
391     }
392 
393     qdev_prop_set_string(DEVICE(&s->dualtimer), "name", "Dual timer");
394     qdev_prop_set_uint64(DEVICE(&s->dualtimer), "size", 0x1000);
395     object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err);
396     if (err) {
397         error_propagate(errp, err);
398         return;
399     }
400     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
401     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
402     if (err) {
403         error_propagate(errp, err);
404         return;
405     }
406 
407     object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err);
408     if (err) {
409         error_propagate(errp, err);
410         return;
411     }
412 
413     sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0);
414     dev_apb_ppc0 = DEVICE(&s->apb_ppc0);
415 
416     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
417     memory_region_add_subregion(&s->container, 0x40000000, mr);
418     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1);
419     memory_region_add_subregion(&s->container, 0x40001000, mr);
420     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
421     memory_region_add_subregion(&s->container, 0x40002000, mr);
422     for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
423         qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
424                                     qdev_get_gpio_in_named(dev_apb_ppc0,
425                                                            "cfg_nonsec", i));
426         qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
427                                     qdev_get_gpio_in_named(dev_apb_ppc0,
428                                                            "cfg_ap", i));
429     }
430     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
431                                 qdev_get_gpio_in_named(dev_apb_ppc0,
432                                                        "irq_enable", 0));
433     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
434                                 qdev_get_gpio_in_named(dev_apb_ppc0,
435                                                        "irq_clear", 0));
436     qdev_connect_gpio_out(dev_splitter, 0,
437                           qdev_get_gpio_in_named(dev_apb_ppc0,
438                                                  "cfg_sec_resp", 0));
439 
440     /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
441      * ones) are sent individually to the security controller, and also
442      * ORed together to give a single combined PPC interrupt to the NVIC.
443      */
444     object_property_set_int(OBJECT(&s->ppc_irq_orgate),
445                             NUM_PPCS, "num-lines", &err);
446     if (err) {
447         error_propagate(errp, err);
448         return;
449     }
450     object_property_set_bool(OBJECT(&s->ppc_irq_orgate), true,
451                              "realized", &err);
452     if (err) {
453         error_propagate(errp, err);
454         return;
455     }
456     qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
457                           qdev_get_gpio_in(DEVICE(&s->armv7m), 10));
458 
459     /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
460 
461     /* 0x40020000 .. 0x4002ffff : IoTKit system control peripheral region */
462     /* Devices behind APB PPC1:
463      *   0x4002f000: S32K timer
464      */
465     qdev_prop_set_string(DEVICE(&s->s32ktimer), "name", "S32KTIMER");
466     qdev_prop_set_uint64(DEVICE(&s->s32ktimer), "size", 0x1000);
467     object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err);
468     if (err) {
469         error_propagate(errp, err);
470         return;
471     }
472     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
473     object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
474     if (err) {
475         error_propagate(errp, err);
476         return;
477     }
478 
479     object_property_set_bool(OBJECT(&s->apb_ppc1), true, "realized", &err);
480     if (err) {
481         error_propagate(errp, err);
482         return;
483     }
484     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0);
485     memory_region_add_subregion(&s->container, 0x4002f000, mr);
486 
487     dev_apb_ppc1 = DEVICE(&s->apb_ppc1);
488     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
489                                 qdev_get_gpio_in_named(dev_apb_ppc1,
490                                                        "cfg_nonsec", 0));
491     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
492                                 qdev_get_gpio_in_named(dev_apb_ppc1,
493                                                        "cfg_ap", 0));
494     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
495                                 qdev_get_gpio_in_named(dev_apb_ppc1,
496                                                        "irq_enable", 0));
497     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
498                                 qdev_get_gpio_in_named(dev_apb_ppc1,
499                                                        "irq_clear", 0));
500     qdev_connect_gpio_out(dev_splitter, 1,
501                           qdev_get_gpio_in_named(dev_apb_ppc1,
502                                                  "cfg_sec_resp", 0));
503 
504     /* Using create_unimplemented_device() maps the stub into the
505      * system address space rather than into our container, but the
506      * overall effect to the guest is the same.
507      */
508     create_unimplemented_device("SYSINFO", 0x40020000, 0x1000);
509 
510     create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000);
511     create_unimplemented_device("S32KWATCHDOG", 0x5002e000, 0x1000);
512 
513     /* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */
514 
515     create_unimplemented_device("NS watchdog", 0x40081000, 0x1000);
516     create_unimplemented_device("S watchdog", 0x50081000, 0x1000);
517 
518     for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
519         Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
520 
521         object_property_set_int(splitter, 2, "num-lines", &err);
522         if (err) {
523             error_propagate(errp, err);
524             return;
525         }
526         object_property_set_bool(splitter, true, "realized", &err);
527         if (err) {
528             error_propagate(errp, err);
529             return;
530         }
531     }
532 
533     for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
534         char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
535 
536         iotkit_forward_ppc(s, ppcname, i);
537         g_free(ppcname);
538     }
539 
540     for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
541         char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
542 
543         iotkit_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
544         g_free(ppcname);
545     }
546 
547     for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
548         /* Wire up IRQ splitter for internal PPCs */
549         DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
550         char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
551                                          i - NUM_EXTERNAL_PPCS);
552         TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1;
553 
554         qdev_connect_gpio_out(devs, 0,
555                               qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
556         qdev_connect_gpio_out(devs, 1,
557                               qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
558         qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
559                                     qdev_get_gpio_in(devs, 0));
560         g_free(gpioname);
561     }
562 
563     /* Wire up the splitters for the MPC IRQs */
564     for (i = 0; i < IOTS_NUM_EXP_MPC + IOTS_NUM_MPC; i++) {
565         SplitIRQ *splitter = &s->mpc_irq_splitter[i];
566         DeviceState *dev_splitter = DEVICE(splitter);
567 
568         object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
569         if (err) {
570             error_propagate(errp, err);
571             return;
572         }
573         object_property_set_bool(OBJECT(splitter), true, "realized", &err);
574         if (err) {
575             error_propagate(errp, err);
576             return;
577         }
578 
579         if (i < IOTS_NUM_EXP_MPC) {
580             /* Splitter input is from GPIO input line */
581             s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
582             qdev_connect_gpio_out(dev_splitter, 0,
583                                   qdev_get_gpio_in_named(dev_secctl,
584                                                          "mpcexp_status", i));
585         } else {
586             /* Splitter input is from our own MPC */
587             qdev_connect_gpio_out_named(DEVICE(&s->mpc), "irq", 0,
588                                         qdev_get_gpio_in(dev_splitter, 0));
589             qdev_connect_gpio_out(dev_splitter, 0,
590                                   qdev_get_gpio_in_named(dev_secctl,
591                                                          "mpc_status", 0));
592         }
593 
594         qdev_connect_gpio_out(dev_splitter, 1,
595                               qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
596     }
597     /* Create GPIO inputs which will pass the line state for our
598      * mpcexp_irq inputs to the correct splitter devices.
599      */
600     qdev_init_gpio_in_named(dev, iotkit_mpcexp_status, "mpcexp_status",
601                             IOTS_NUM_EXP_MPC);
602 
603     iotkit_forward_sec_resp_cfg(s);
604 
605     system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
606 }
607 
608 static void iotkit_idau_check(IDAUInterface *ii, uint32_t address,
609                               int *iregion, bool *exempt, bool *ns, bool *nsc)
610 {
611     /* For IoTKit systems the IDAU responses are simple logical functions
612      * of the address bits. The NSC attribute is guest-adjustable via the
613      * NSCCFG register in the security controller.
614      */
615     IoTKit *s = IOTKIT(ii);
616     int region = extract32(address, 28, 4);
617 
618     *ns = !(region & 1);
619     *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
620     /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
621     *exempt = (address & 0xeff00000) == 0xe0000000;
622     *iregion = region;
623 }
624 
625 static const VMStateDescription iotkit_vmstate = {
626     .name = "iotkit",
627     .version_id = 1,
628     .minimum_version_id = 1,
629     .fields = (VMStateField[]) {
630         VMSTATE_UINT32(nsccfg, IoTKit),
631         VMSTATE_END_OF_LIST()
632     }
633 };
634 
635 static Property iotkit_properties[] = {
636     DEFINE_PROP_LINK("memory", IoTKit, board_memory, TYPE_MEMORY_REGION,
637                      MemoryRegion *),
638     DEFINE_PROP_UINT32("EXP_NUMIRQ", IoTKit, exp_numirq, 64),
639     DEFINE_PROP_UINT32("MAINCLK", IoTKit, mainclk_frq, 0),
640     DEFINE_PROP_END_OF_LIST()
641 };
642 
643 static void iotkit_reset(DeviceState *dev)
644 {
645     IoTKit *s = IOTKIT(dev);
646 
647     s->nsccfg = 0;
648 }
649 
650 static void iotkit_class_init(ObjectClass *klass, void *data)
651 {
652     DeviceClass *dc = DEVICE_CLASS(klass);
653     IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
654 
655     dc->realize = iotkit_realize;
656     dc->vmsd = &iotkit_vmstate;
657     dc->props = iotkit_properties;
658     dc->reset = iotkit_reset;
659     iic->check = iotkit_idau_check;
660 }
661 
662 static const TypeInfo iotkit_info = {
663     .name = TYPE_IOTKIT,
664     .parent = TYPE_SYS_BUS_DEVICE,
665     .instance_size = sizeof(IoTKit),
666     .instance_init = iotkit_init,
667     .class_init = iotkit_class_init,
668     .interfaces = (InterfaceInfo[]) {
669         { TYPE_IDAU_INTERFACE },
670         { }
671     }
672 };
673 
674 static void iotkit_register_types(void)
675 {
676     type_register_static(&iotkit_info);
677 }
678 
679 type_init(iotkit_register_types);
680