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