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"
14 #include "qapi/error.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
);
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
);
63 name
= g_strdup_printf("%s_nonsec", ppcname
);
64 qdev_pass_gpios(dev_secctl
, iotkitdev
, name
);
66 name
= g_strdup_printf("%s_ap", ppcname
);
67 qdev_pass_gpios(dev_secctl
, iotkitdev
, name
);
69 name
= g_strdup_printf("%s_irq_enable", ppcname
);
70 qdev_pass_gpios(dev_secctl
, iotkitdev
, name
);
72 name
= g_strdup_printf("%s_irq_clear", ppcname
);
73 qdev_pass_gpios(dev_secctl
, iotkitdev
, 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
,
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);
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
,
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
);
113 memory_region_init(&s
->container
, obj
, "iotkit-container", UINT64_MAX
);
115 sysbus_init_child_obj(obj
, "armv7m", &s
->armv7m
, sizeof(s
->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
),
122 sysbus_init_child_obj(obj
, "apb-ppc0", &s
->apb_ppc0
, sizeof(s
->apb_ppc0
),
124 sysbus_init_child_obj(obj
, "apb-ppc1", &s
->apb_ppc1
, sizeof(s
->apb_ppc1
),
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
,
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
);
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
,
160 object_initialize_child(obj
, "ppc-irq-orgate", &s
->ppc_irq_orgate
,
161 sizeof(s
->ppc_irq_orgate
), TYPE_OR_IRQ
,
163 object_initialize_child(obj
, "sec-resp-splitter", &s
->sec_resp_splitter
,
164 sizeof(s
->sec_resp_splitter
), TYPE_SPLIT_IRQ
,
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
);
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
);
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");
207 if (!s
->mainclk_frq
) {
208 error_setg(errp
, "MAINCLK property was not set");
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
),
261 error_propagate(errp
, err
);
264 object_property_set_link(OBJECT(&s
->armv7m
), OBJECT(s
), "idau", &err
);
266 error_propagate(errp
, err
);
269 object_property_set_bool(OBJECT(&s
->armv7m
), true, "realized", &err
);
271 error_propagate(errp
, err
);
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
);
297 error_propagate(errp
, err
);
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,
315 error_propagate(errp
, err
);
318 object_property_set_bool(OBJECT(&s
->sec_resp_splitter
), true,
321 error_propagate(errp
, err
);
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
);
331 error_propagate(errp
, err
);
334 object_property_set_link(OBJECT(&s
->mpc
), OBJECT(&s
->sram0
),
337 error_propagate(errp
, err
);
340 object_property_set_bool(OBJECT(&s
->mpc
), true, "realized", &err
);
342 error_propagate(errp
, err
);
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
),
349 /* ...and its register interface */
350 memory_region_add_subregion(&s
->container
, 0x50083000,
351 sysbus_mmio_get_region(SYS_BUS_DEVICE(&s
->mpc
),
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
);
358 error_propagate(errp
, err
);
361 object_property_set_bool(OBJECT(&s
->mpc_irq_orgate
), true,
364 error_propagate(errp
, err
);
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:
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
);
381 error_propagate(errp
, err
);
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
);
389 error_propagate(errp
, err
);
393 qdev_prop_set_uint32(DEVICE(&s
->timer1
), "pclk-frq", s
->mainclk_frq
);
394 object_property_set_bool(OBJECT(&s
->timer1
), true, "realized", &err
);
396 error_propagate(errp
, err
);
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
);
404 error_propagate(errp
, err
);
409 qdev_prop_set_uint32(DEVICE(&s
->dualtimer
), "pclk-frq", s
->mainclk_frq
);
410 object_property_set_bool(OBJECT(&s
->dualtimer
), true, "realized", &err
);
412 error_propagate(errp
, err
);
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
);
420 error_propagate(errp
, err
);
424 object_property_set_bool(OBJECT(&s
->apb_ppc0
), true, "realized", &err
);
426 error_propagate(errp
, err
);
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
,
443 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_ap", i
,
444 qdev_get_gpio_in_named(dev_apb_ppc0
,
447 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_irq_enable", 0,
448 qdev_get_gpio_in_named(dev_apb_ppc0
,
450 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_irq_clear", 0,
451 qdev_get_gpio_in_named(dev_apb_ppc0
,
453 qdev_connect_gpio_out(dev_splitter
, 0,
454 qdev_get_gpio_in_named(dev_apb_ppc0
,
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
);
464 error_propagate(errp
, err
);
467 object_property_set_bool(OBJECT(&s
->ppc_irq_orgate
), true,
470 error_propagate(errp
, err
);
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
);
485 error_propagate(errp
, err
);
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
);
493 error_propagate(errp
, err
);
497 object_property_set_bool(OBJECT(&s
->apb_ppc1
), true, "realized", &err
);
499 error_propagate(errp
, err
);
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
,
509 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_ap", 0,
510 qdev_get_gpio_in_named(dev_apb_ppc1
,
512 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_irq_enable", 0,
513 qdev_get_gpio_in_named(dev_apb_ppc1
,
515 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_irq_clear", 0,
516 qdev_get_gpio_in_named(dev_apb_ppc1
,
518 qdev_connect_gpio_out(dev_splitter
, 1,
519 qdev_get_gpio_in_named(dev_apb_ppc1
,
522 object_property_set_bool(OBJECT(&s
->sysinfo
), true, "realized", &err
);
524 error_propagate(errp
, err
);
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
);
532 error_propagate(errp
, err
);
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
);
540 error_propagate(errp
, err
);
543 object_property_set_bool(OBJECT(&s
->nmi_orgate
), true, "realized", &err
);
545 error_propagate(errp
, err
);
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
);
554 error_propagate(errp
, err
);
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
);
566 error_propagate(errp
, err
);
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
);
576 error_propagate(errp
, err
);
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
);
588 error_propagate(errp
, err
);
591 object_property_set_bool(splitter
, true, "realized", &err
);
593 error_propagate(errp
, err
);
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
);
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
);
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));
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
);
635 error_propagate(errp
, err
);
638 object_property_set_bool(OBJECT(splitter
), true, "realized", &err
);
640 error_propagate(errp
, err
);
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
));
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
,
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",
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);
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;
705 static const VMStateDescription iotkit_vmstate
= {
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
,
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
);
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
= {
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
);