ui: fix icon display for GTK frontend under GNOME Shell with Wayland
[qemu/ar7.git] / hw / arm / iotkit.c
blob8742200fb42681143a5c0a5a2c089983273d143f
1 /*
2 * Arm IoT Kit
4 * Copyright (c) 2018 Linaro Limited
5 * Written by Peter Maydell
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.
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/arm/arm.h"
21 /* Clock frequency in HZ of the 32KHz "slow clock" */
22 #define S32KCLK (32 * 1000)
24 /* Create an alias region of @size bytes starting at @base
25 * which mirrors the memory starting at @orig.
27 static void make_alias(IoTKit *s, MemoryRegion *mr, const char *name,
28 hwaddr base, hwaddr size, hwaddr orig)
30 memory_region_init_alias(mr, NULL, name, &s->container, orig, size);
31 /* The alias is even lower priority than unimplemented_device regions */
32 memory_region_add_subregion_overlap(&s->container, base, mr, -1500);
35 static void irq_status_forwarder(void *opaque, int n, int level)
37 qemu_irq destirq = opaque;
39 qemu_set_irq(destirq, level);
42 static void nsccfg_handler(void *opaque, int n, int level)
44 IoTKit *s = IOTKIT(opaque);
46 s->nsccfg = level;
49 static void iotkit_forward_ppc(IoTKit *s, const char *ppcname, int ppcnum)
51 /* Each of the 4 AHB and 4 APB PPCs that might be present in a
52 * system using the IoTKit has a collection of control lines which
53 * are provided by the security controller and which we want to
54 * expose as control lines on the IoTKit device itself, so the
55 * code using the IoTKit can wire them up to the PPCs.
57 SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
58 DeviceState *iotkitdev = DEVICE(s);
59 DeviceState *dev_secctl = DEVICE(&s->secctl);
60 DeviceState *dev_splitter = DEVICE(splitter);
61 char *name;
63 name = g_strdup_printf("%s_nonsec", ppcname);
64 qdev_pass_gpios(dev_secctl, iotkitdev, name);
65 g_free(name);
66 name = g_strdup_printf("%s_ap", ppcname);
67 qdev_pass_gpios(dev_secctl, iotkitdev, name);
68 g_free(name);
69 name = g_strdup_printf("%s_irq_enable", ppcname);
70 qdev_pass_gpios(dev_secctl, iotkitdev, name);
71 g_free(name);
72 name = g_strdup_printf("%s_irq_clear", ppcname);
73 qdev_pass_gpios(dev_secctl, iotkitdev, name);
74 g_free(name);
76 /* irq_status is a little more tricky, because we need to
77 * split it so we can send it both to the security controller
78 * and to our OR gate for the NVIC interrupt line.
79 * Connect up the splitter's outputs, and create a GPIO input
80 * which will pass the line state to the input splitter.
82 name = g_strdup_printf("%s_irq_status", ppcname);
83 qdev_connect_gpio_out(dev_splitter, 0,
84 qdev_get_gpio_in_named(dev_secctl,
85 name, 0));
86 qdev_connect_gpio_out(dev_splitter, 1,
87 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
88 s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
89 qdev_init_gpio_in_named_with_opaque(iotkitdev, irq_status_forwarder,
90 s->irq_status_in[ppcnum], name, 1);
91 g_free(name);
94 static void iotkit_forward_sec_resp_cfg(IoTKit *s)
96 /* Forward the 3rd output from the splitter device as a
97 * named GPIO output of the iotkit object.
99 DeviceState *dev = DEVICE(s);
100 DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
102 qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
103 s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
104 s->sec_resp_cfg, 1);
105 qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
108 static void iotkit_init(Object *obj)
110 IoTKit *s = IOTKIT(obj);
111 int i;
113 memory_region_init(&s->container, obj, "iotkit-container", UINT64_MAX);
115 sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
116 TYPE_ARMV7M);
117 qdev_prop_set_string(DEVICE(&s->armv7m), "cpu-type",
118 ARM_CPU_TYPE_NAME("cortex-m33"));
120 sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
121 TYPE_IOTKIT_SECCTL);
122 sysbus_init_child_obj(obj, "apb-ppc0", &s->apb_ppc0, sizeof(s->apb_ppc0),
123 TYPE_TZ_PPC);
124 sysbus_init_child_obj(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
125 TYPE_TZ_PPC);
126 sysbus_init_child_obj(obj, "mpc", &s->mpc, sizeof(s->mpc), TYPE_TZ_MPC);
127 object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
128 sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
129 &error_abort, NULL);
131 for (i = 0; i < ARRAY_SIZE(s->mpc_irq_splitter); i++) {
132 char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
133 SplitIRQ *splitter = &s->mpc_irq_splitter[i];
135 object_initialize_child(obj, name, splitter, sizeof(*splitter),
136 TYPE_SPLIT_IRQ, &error_abort, NULL);
137 g_free(name);
139 sysbus_init_child_obj(obj, "timer0", &s->timer0, sizeof(s->timer0),
140 TYPE_CMSDK_APB_TIMER);
141 sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1),
142 TYPE_CMSDK_APB_TIMER);
143 sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer),
144 TYPE_CMSDK_APB_TIMER);
145 sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
146 TYPE_CMSDK_APB_DUALTIMER);
147 sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog,
148 sizeof(s->s32kwatchdog), TYPE_CMSDK_APB_WATCHDOG);
149 sysbus_init_child_obj(obj, "nswatchdog", &s->nswatchdog,
150 sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
151 sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
152 sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
153 sysbus_init_child_obj(obj, "iotkit-sysctl", &s->sysctl,
154 sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
155 sysbus_init_child_obj(obj, "iotkit-sysinfo", &s->sysinfo,
156 sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
157 object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
158 sizeof(s->nmi_orgate), TYPE_OR_IRQ,
159 &error_abort, NULL);
160 object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
161 sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ,
162 &error_abort, NULL);
163 object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
164 sizeof(s->sec_resp_splitter), TYPE_SPLIT_IRQ,
165 &error_abort, NULL);
166 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
167 char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
168 SplitIRQ *splitter = &s->ppc_irq_splitter[i];
170 object_initialize_child(obj, name, splitter, sizeof(*splitter),
171 TYPE_SPLIT_IRQ, &error_abort, NULL);
172 g_free(name);
176 static void iotkit_exp_irq(void *opaque, int n, int level)
178 IoTKit *s = IOTKIT(opaque);
180 qemu_set_irq(s->exp_irqs[n], level);
183 static void iotkit_mpcexp_status(void *opaque, int n, int level)
185 IoTKit *s = IOTKIT(opaque);
186 qemu_set_irq(s->mpcexp_status_in[n], level);
189 static void iotkit_realize(DeviceState *dev, Error **errp)
191 IoTKit *s = IOTKIT(dev);
192 int i;
193 MemoryRegion *mr;
194 Error *err = NULL;
195 SysBusDevice *sbd_apb_ppc0;
196 SysBusDevice *sbd_secctl;
197 DeviceState *dev_apb_ppc0;
198 DeviceState *dev_apb_ppc1;
199 DeviceState *dev_secctl;
200 DeviceState *dev_splitter;
202 if (!s->board_memory) {
203 error_setg(errp, "memory property was not set");
204 return;
207 if (!s->mainclk_frq) {
208 error_setg(errp, "MAINCLK property was not set");
209 return;
212 /* Handling of which devices should be available only to secure
213 * code is usually done differently for M profile than for A profile.
214 * Instead of putting some devices only into the secure address space,
215 * devices exist in both address spaces but with hard-wired security
216 * permissions that will cause the CPU to fault for non-secure accesses.
218 * The IoTKit has an IDAU (Implementation Defined Access Unit),
219 * which specifies hard-wired security permissions for different
220 * areas of the physical address space. For the IoTKit IDAU, the
221 * top 4 bits of the physical address are the IDAU region ID, and
222 * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
223 * region, otherwise it is an S region.
225 * The various devices and RAMs are generally all mapped twice,
226 * once into a region that the IDAU defines as secure and once
227 * into a non-secure region. They sit behind either a Memory
228 * Protection Controller (for RAM) or a Peripheral Protection
229 * Controller (for devices), which allow a more fine grained
230 * configuration of whether non-secure accesses are permitted.
232 * (The other place that guest software can configure security
233 * permissions is in the architected SAU (Security Attribution
234 * Unit), which is entirely inside the CPU. The IDAU can upgrade
235 * the security attributes for a region to more restrictive than
236 * the SAU specifies, but cannot downgrade them.)
238 * 0x10000000..0x1fffffff alias of 0x00000000..0x0fffffff
239 * 0x20000000..0x2007ffff 32KB FPGA block RAM
240 * 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff
241 * 0x40000000..0x4000ffff base peripheral region 1
242 * 0x40010000..0x4001ffff CPU peripherals (none for IoTKit)
243 * 0x40020000..0x4002ffff system control element peripherals
244 * 0x40080000..0x400fffff base peripheral region 2
245 * 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
248 memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
250 qdev_prop_set_uint32(DEVICE(&s->armv7m), "num-irq", s->exp_numirq + 32);
251 /* In real hardware the initial Secure VTOR is set from the INITSVTOR0
252 * register in the IoT Kit System Control Register block, and the
253 * initial value of that is in turn specifiable by the FPGA that
254 * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
255 * and simply set the CPU's init-svtor to the IoT Kit default value.
257 qdev_prop_set_uint32(DEVICE(&s->armv7m), "init-svtor", 0x10000000);
258 object_property_set_link(OBJECT(&s->armv7m), OBJECT(&s->container),
259 "memory", &err);
260 if (err) {
261 error_propagate(errp, err);
262 return;
264 object_property_set_link(OBJECT(&s->armv7m), OBJECT(s), "idau", &err);
265 if (err) {
266 error_propagate(errp, err);
267 return;
269 object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
270 if (err) {
271 error_propagate(errp, err);
272 return;
275 /* Connect our EXP_IRQ GPIOs to the NVIC's lines 32 and up. */
276 s->exp_irqs = g_new(qemu_irq, s->exp_numirq);
277 for (i = 0; i < s->exp_numirq; i++) {
278 s->exp_irqs[i] = qdev_get_gpio_in(DEVICE(&s->armv7m), i + 32);
280 qdev_init_gpio_in_named(dev, iotkit_exp_irq, "EXP_IRQ", s->exp_numirq);
282 /* Set up the big aliases first */
283 make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000);
284 make_alias(s, &s->alias2, "alias 2", 0x30000000, 0x10000000, 0x20000000);
285 /* The 0x50000000..0x5fffffff region is not a pure alias: it has
286 * a few extra devices that only appear there (generally the
287 * control interfaces for the protection controllers).
288 * We implement this by mapping those devices over the top of this
289 * alias MR at a higher priority.
291 make_alias(s, &s->alias3, "alias 3", 0x50000000, 0x10000000, 0x40000000);
294 /* Security controller */
295 object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err);
296 if (err) {
297 error_propagate(errp, err);
298 return;
300 sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
301 dev_secctl = DEVICE(&s->secctl);
302 sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
303 sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
305 s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
306 qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
308 /* The sec_resp_cfg output from the security controller must be split into
309 * multiple lines, one for each of the PPCs within the IoTKit and one
310 * that will be an output from the IoTKit to the system.
312 object_property_set_int(OBJECT(&s->sec_resp_splitter), 3,
313 "num-lines", &err);
314 if (err) {
315 error_propagate(errp, err);
316 return;
318 object_property_set_bool(OBJECT(&s->sec_resp_splitter), true,
319 "realized", &err);
320 if (err) {
321 error_propagate(errp, err);
322 return;
324 dev_splitter = DEVICE(&s->sec_resp_splitter);
325 qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
326 qdev_get_gpio_in(dev_splitter, 0));
328 /* This RAM lives behind the Memory Protection Controller */
329 memory_region_init_ram(&s->sram0, NULL, "iotkit.sram0", 0x00008000, &err);
330 if (err) {
331 error_propagate(errp, err);
332 return;
334 object_property_set_link(OBJECT(&s->mpc), OBJECT(&s->sram0),
335 "downstream", &err);
336 if (err) {
337 error_propagate(errp, err);
338 return;
340 object_property_set_bool(OBJECT(&s->mpc), true, "realized", &err);
341 if (err) {
342 error_propagate(errp, err);
343 return;
345 /* Map the upstream end of the MPC into the right place... */
346 memory_region_add_subregion(&s->container, 0x20000000,
347 sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
348 1));
349 /* ...and its register interface */
350 memory_region_add_subregion(&s->container, 0x50083000,
351 sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
352 0));
354 /* We must OR together lines from the MPC splitters to go to the NVIC */
355 object_property_set_int(OBJECT(&s->mpc_irq_orgate),
356 IOTS_NUM_EXP_MPC + IOTS_NUM_MPC, "num-lines", &err);
357 if (err) {
358 error_propagate(errp, err);
359 return;
361 object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
362 "realized", &err);
363 if (err) {
364 error_propagate(errp, err);
365 return;
367 qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
368 qdev_get_gpio_in(DEVICE(&s->armv7m), 9));
370 /* Devices behind APB PPC0:
371 * 0x40000000: timer0
372 * 0x40001000: timer1
373 * 0x40002000: dual timer
374 * We must configure and realize each downstream device and connect
375 * it to the appropriate PPC port; then we can realize the PPC and
376 * map its upstream ends to the right place in the container.
378 qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
379 object_property_set_bool(OBJECT(&s->timer0), true, "realized", &err);
380 if (err) {
381 error_propagate(errp, err);
382 return;
384 sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
385 qdev_get_gpio_in(DEVICE(&s->armv7m), 3));
386 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
387 object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err);
388 if (err) {
389 error_propagate(errp, err);
390 return;
393 qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
394 object_property_set_bool(OBJECT(&s->timer1), true, "realized", &err);
395 if (err) {
396 error_propagate(errp, err);
397 return;
399 sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
400 qdev_get_gpio_in(DEVICE(&s->armv7m), 4));
401 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
402 object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err);
403 if (err) {
404 error_propagate(errp, err);
405 return;
409 qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
410 object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err);
411 if (err) {
412 error_propagate(errp, err);
413 return;
415 sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
416 qdev_get_gpio_in(DEVICE(&s->armv7m), 5));
417 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
418 object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
419 if (err) {
420 error_propagate(errp, err);
421 return;
424 object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err);
425 if (err) {
426 error_propagate(errp, err);
427 return;
430 sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0);
431 dev_apb_ppc0 = DEVICE(&s->apb_ppc0);
433 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
434 memory_region_add_subregion(&s->container, 0x40000000, mr);
435 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1);
436 memory_region_add_subregion(&s->container, 0x40001000, mr);
437 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
438 memory_region_add_subregion(&s->container, 0x40002000, mr);
439 for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
440 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
441 qdev_get_gpio_in_named(dev_apb_ppc0,
442 "cfg_nonsec", i));
443 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
444 qdev_get_gpio_in_named(dev_apb_ppc0,
445 "cfg_ap", i));
447 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
448 qdev_get_gpio_in_named(dev_apb_ppc0,
449 "irq_enable", 0));
450 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
451 qdev_get_gpio_in_named(dev_apb_ppc0,
452 "irq_clear", 0));
453 qdev_connect_gpio_out(dev_splitter, 0,
454 qdev_get_gpio_in_named(dev_apb_ppc0,
455 "cfg_sec_resp", 0));
457 /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
458 * ones) are sent individually to the security controller, and also
459 * ORed together to give a single combined PPC interrupt to the NVIC.
461 object_property_set_int(OBJECT(&s->ppc_irq_orgate),
462 NUM_PPCS, "num-lines", &err);
463 if (err) {
464 error_propagate(errp, err);
465 return;
467 object_property_set_bool(OBJECT(&s->ppc_irq_orgate), true,
468 "realized", &err);
469 if (err) {
470 error_propagate(errp, err);
471 return;
473 qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
474 qdev_get_gpio_in(DEVICE(&s->armv7m), 10));
476 /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
478 /* 0x40020000 .. 0x4002ffff : IoTKit system control peripheral region */
479 /* Devices behind APB PPC1:
480 * 0x4002f000: S32K timer
482 qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
483 object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err);
484 if (err) {
485 error_propagate(errp, err);
486 return;
488 sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
489 qdev_get_gpio_in(DEVICE(&s->armv7m), 2));
490 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
491 object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
492 if (err) {
493 error_propagate(errp, err);
494 return;
497 object_property_set_bool(OBJECT(&s->apb_ppc1), true, "realized", &err);
498 if (err) {
499 error_propagate(errp, err);
500 return;
502 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0);
503 memory_region_add_subregion(&s->container, 0x4002f000, mr);
505 dev_apb_ppc1 = DEVICE(&s->apb_ppc1);
506 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
507 qdev_get_gpio_in_named(dev_apb_ppc1,
508 "cfg_nonsec", 0));
509 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
510 qdev_get_gpio_in_named(dev_apb_ppc1,
511 "cfg_ap", 0));
512 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
513 qdev_get_gpio_in_named(dev_apb_ppc1,
514 "irq_enable", 0));
515 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
516 qdev_get_gpio_in_named(dev_apb_ppc1,
517 "irq_clear", 0));
518 qdev_connect_gpio_out(dev_splitter, 1,
519 qdev_get_gpio_in_named(dev_apb_ppc1,
520 "cfg_sec_resp", 0));
522 object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
523 if (err) {
524 error_propagate(errp, err);
525 return;
527 /* System information registers */
528 sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
529 /* System control registers */
530 object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
531 if (err) {
532 error_propagate(errp, err);
533 return;
535 sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
537 /* This OR gate wires together outputs from the secure watchdogs to NMI */
538 object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
539 if (err) {
540 error_propagate(errp, err);
541 return;
543 object_property_set_bool(OBJECT(&s->nmi_orgate), true, "realized", &err);
544 if (err) {
545 error_propagate(errp, err);
546 return;
548 qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
549 qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
551 qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
552 object_property_set_bool(OBJECT(&s->s32kwatchdog), true, "realized", &err);
553 if (err) {
554 error_propagate(errp, err);
555 return;
557 sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0,
558 qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
559 sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
561 /* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */
563 qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
564 object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err);
565 if (err) {
566 error_propagate(errp, err);
567 return;
569 sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
570 qdev_get_gpio_in(DEVICE(&s->armv7m), 1));
571 sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
573 qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
574 object_property_set_bool(OBJECT(&s->swatchdog), true, "realized", &err);
575 if (err) {
576 error_propagate(errp, err);
577 return;
579 sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0,
580 qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1));
581 sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000);
583 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
584 Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
586 object_property_set_int(splitter, 2, "num-lines", &err);
587 if (err) {
588 error_propagate(errp, err);
589 return;
591 object_property_set_bool(splitter, true, "realized", &err);
592 if (err) {
593 error_propagate(errp, err);
594 return;
598 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
599 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
601 iotkit_forward_ppc(s, ppcname, i);
602 g_free(ppcname);
605 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
606 char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
608 iotkit_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
609 g_free(ppcname);
612 for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
613 /* Wire up IRQ splitter for internal PPCs */
614 DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
615 char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
616 i - NUM_EXTERNAL_PPCS);
617 TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1;
619 qdev_connect_gpio_out(devs, 0,
620 qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
621 qdev_connect_gpio_out(devs, 1,
622 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
623 qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
624 qdev_get_gpio_in(devs, 0));
625 g_free(gpioname);
628 /* Wire up the splitters for the MPC IRQs */
629 for (i = 0; i < IOTS_NUM_EXP_MPC + IOTS_NUM_MPC; i++) {
630 SplitIRQ *splitter = &s->mpc_irq_splitter[i];
631 DeviceState *dev_splitter = DEVICE(splitter);
633 object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
634 if (err) {
635 error_propagate(errp, err);
636 return;
638 object_property_set_bool(OBJECT(splitter), true, "realized", &err);
639 if (err) {
640 error_propagate(errp, err);
641 return;
644 if (i < IOTS_NUM_EXP_MPC) {
645 /* Splitter input is from GPIO input line */
646 s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
647 qdev_connect_gpio_out(dev_splitter, 0,
648 qdev_get_gpio_in_named(dev_secctl,
649 "mpcexp_status", i));
650 } else {
651 /* Splitter input is from our own MPC */
652 qdev_connect_gpio_out_named(DEVICE(&s->mpc), "irq", 0,
653 qdev_get_gpio_in(dev_splitter, 0));
654 qdev_connect_gpio_out(dev_splitter, 0,
655 qdev_get_gpio_in_named(dev_secctl,
656 "mpc_status", 0));
659 qdev_connect_gpio_out(dev_splitter, 1,
660 qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
662 /* Create GPIO inputs which will pass the line state for our
663 * mpcexp_irq inputs to the correct splitter devices.
665 qdev_init_gpio_in_named(dev, iotkit_mpcexp_status, "mpcexp_status",
666 IOTS_NUM_EXP_MPC);
668 iotkit_forward_sec_resp_cfg(s);
670 /* Forward the MSC related signals */
671 qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
672 qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
673 qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
674 qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
675 qdev_get_gpio_in(DEVICE(&s->armv7m), 11));
678 * Expose our container region to the board model; this corresponds
679 * to the AHB Slave Expansion ports which allow bus master devices
680 * (eg DMA controllers) in the board model to make transactions into
681 * devices in the IoTKit.
683 sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
685 system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
688 static void iotkit_idau_check(IDAUInterface *ii, uint32_t address,
689 int *iregion, bool *exempt, bool *ns, bool *nsc)
691 /* For IoTKit systems the IDAU responses are simple logical functions
692 * of the address bits. The NSC attribute is guest-adjustable via the
693 * NSCCFG register in the security controller.
695 IoTKit *s = IOTKIT(ii);
696 int region = extract32(address, 28, 4);
698 *ns = !(region & 1);
699 *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
700 /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
701 *exempt = (address & 0xeff00000) == 0xe0000000;
702 *iregion = region;
705 static const VMStateDescription iotkit_vmstate = {
706 .name = "iotkit",
707 .version_id = 1,
708 .minimum_version_id = 1,
709 .fields = (VMStateField[]) {
710 VMSTATE_UINT32(nsccfg, IoTKit),
711 VMSTATE_END_OF_LIST()
715 static Property iotkit_properties[] = {
716 DEFINE_PROP_LINK("memory", IoTKit, board_memory, TYPE_MEMORY_REGION,
717 MemoryRegion *),
718 DEFINE_PROP_UINT32("EXP_NUMIRQ", IoTKit, exp_numirq, 64),
719 DEFINE_PROP_UINT32("MAINCLK", IoTKit, mainclk_frq, 0),
720 DEFINE_PROP_END_OF_LIST()
723 static void iotkit_reset(DeviceState *dev)
725 IoTKit *s = IOTKIT(dev);
727 s->nsccfg = 0;
730 static void iotkit_class_init(ObjectClass *klass, void *data)
732 DeviceClass *dc = DEVICE_CLASS(klass);
733 IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
735 dc->realize = iotkit_realize;
736 dc->vmsd = &iotkit_vmstate;
737 dc->props = iotkit_properties;
738 dc->reset = iotkit_reset;
739 iic->check = iotkit_idau_check;
742 static const TypeInfo iotkit_info = {
743 .name = TYPE_IOTKIT,
744 .parent = TYPE_SYS_BUS_DEVICE,
745 .instance_size = sizeof(IoTKit),
746 .instance_init = iotkit_init,
747 .class_init = iotkit_class_init,
748 .interfaces = (InterfaceInfo[]) {
749 { TYPE_IDAU_INTERFACE },
754 static void iotkit_register_types(void)
756 type_register_static(&iotkit_info);
759 type_init(iotkit_register_types);