xref: /qemu/hw/arm/armsse.c (revision d847ca5128351ea3be3a92be74d7bac74e59f048)
1 /*
2  * Arm SSE (Subsystems for Embedded): IoTKit
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/armsse.h"
19 #include "hw/arm/arm.h"
20 
21 struct ARMSSEInfo {
22     const char *name;
23     int sram_banks;
24     int num_cpus;
25 };
26 
27 static const ARMSSEInfo armsse_variants[] = {
28     {
29         .name = TYPE_IOTKIT,
30         .sram_banks = 1,
31         .num_cpus = 1,
32     },
33 };
34 
35 /* Clock frequency in HZ of the 32KHz "slow clock" */
36 #define S32KCLK (32 * 1000)
37 
38 /* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
39 static bool irq_is_common[32] = {
40     [0 ... 5] = true,
41     /* 6, 7: per-CPU MHU interrupts */
42     [8 ... 12] = true,
43     /* 13: per-CPU icache interrupt */
44     /* 14: reserved */
45     [15 ... 20] = true,
46     /* 21: reserved */
47     [22 ... 26] = true,
48     /* 27: reserved */
49     /* 28, 29: per-CPU CTI interrupts */
50     /* 30, 31: reserved */
51 };
52 
53 /* Create an alias region of @size bytes starting at @base
54  * which mirrors the memory starting at @orig.
55  */
56 static void make_alias(ARMSSE *s, MemoryRegion *mr, const char *name,
57                        hwaddr base, hwaddr size, hwaddr orig)
58 {
59     memory_region_init_alias(mr, NULL, name, &s->container, orig, size);
60     /* The alias is even lower priority than unimplemented_device regions */
61     memory_region_add_subregion_overlap(&s->container, base, mr, -1500);
62 }
63 
64 static void irq_status_forwarder(void *opaque, int n, int level)
65 {
66     qemu_irq destirq = opaque;
67 
68     qemu_set_irq(destirq, level);
69 }
70 
71 static void nsccfg_handler(void *opaque, int n, int level)
72 {
73     ARMSSE *s = ARMSSE(opaque);
74 
75     s->nsccfg = level;
76 }
77 
78 static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
79 {
80     /* Each of the 4 AHB and 4 APB PPCs that might be present in a
81      * system using the ARMSSE has a collection of control lines which
82      * are provided by the security controller and which we want to
83      * expose as control lines on the ARMSSE device itself, so the
84      * code using the ARMSSE can wire them up to the PPCs.
85      */
86     SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
87     DeviceState *armssedev = DEVICE(s);
88     DeviceState *dev_secctl = DEVICE(&s->secctl);
89     DeviceState *dev_splitter = DEVICE(splitter);
90     char *name;
91 
92     name = g_strdup_printf("%s_nonsec", ppcname);
93     qdev_pass_gpios(dev_secctl, armssedev, name);
94     g_free(name);
95     name = g_strdup_printf("%s_ap", ppcname);
96     qdev_pass_gpios(dev_secctl, armssedev, name);
97     g_free(name);
98     name = g_strdup_printf("%s_irq_enable", ppcname);
99     qdev_pass_gpios(dev_secctl, armssedev, name);
100     g_free(name);
101     name = g_strdup_printf("%s_irq_clear", ppcname);
102     qdev_pass_gpios(dev_secctl, armssedev, name);
103     g_free(name);
104 
105     /* irq_status is a little more tricky, because we need to
106      * split it so we can send it both to the security controller
107      * and to our OR gate for the NVIC interrupt line.
108      * Connect up the splitter's outputs, and create a GPIO input
109      * which will pass the line state to the input splitter.
110      */
111     name = g_strdup_printf("%s_irq_status", ppcname);
112     qdev_connect_gpio_out(dev_splitter, 0,
113                           qdev_get_gpio_in_named(dev_secctl,
114                                                  name, 0));
115     qdev_connect_gpio_out(dev_splitter, 1,
116                           qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
117     s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
118     qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
119                                         s->irq_status_in[ppcnum], name, 1);
120     g_free(name);
121 }
122 
123 static void armsse_forward_sec_resp_cfg(ARMSSE *s)
124 {
125     /* Forward the 3rd output from the splitter device as a
126      * named GPIO output of the armsse object.
127      */
128     DeviceState *dev = DEVICE(s);
129     DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
130 
131     qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
132     s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
133                                            s->sec_resp_cfg, 1);
134     qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
135 }
136 
137 static void armsse_init(Object *obj)
138 {
139     ARMSSE *s = ARMSSE(obj);
140     ARMSSEClass *asc = ARMSSE_GET_CLASS(obj);
141     const ARMSSEInfo *info = asc->info;
142     int i;
143 
144     assert(info->sram_banks <= MAX_SRAM_BANKS);
145     assert(info->num_cpus <= SSE_MAX_CPUS);
146 
147     memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
148 
149     for (i = 0; i < info->num_cpus; i++) {
150         char *name = g_strdup_printf("armv7m%d", i);
151         sysbus_init_child_obj(obj, name, &s->armv7m[i], sizeof(s->armv7m),
152                               TYPE_ARMV7M);
153         qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
154                              ARM_CPU_TYPE_NAME("cortex-m33"));
155         g_free(name);
156         name = g_strdup_printf("arm-sse-cpu-container%d", i);
157         memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
158         g_free(name);
159         if (i > 0) {
160             name = g_strdup_printf("arm-sse-container-alias%d", i);
161             memory_region_init_alias(&s->container_alias[i - 1], obj,
162                                      name, &s->container, 0, UINT64_MAX);
163             g_free(name);
164         }
165     }
166 
167     sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
168                           TYPE_IOTKIT_SECCTL);
169     sysbus_init_child_obj(obj, "apb-ppc0", &s->apb_ppc0, sizeof(s->apb_ppc0),
170                           TYPE_TZ_PPC);
171     sysbus_init_child_obj(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
172                           TYPE_TZ_PPC);
173     for (i = 0; i < info->sram_banks; i++) {
174         char *name = g_strdup_printf("mpc%d", i);
175         sysbus_init_child_obj(obj, name, &s->mpc[i],
176                               sizeof(s->mpc[i]), TYPE_TZ_MPC);
177         g_free(name);
178     }
179     object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
180                             sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
181                             &error_abort, NULL);
182 
183     for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
184         char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
185         SplitIRQ *splitter = &s->mpc_irq_splitter[i];
186 
187         object_initialize_child(obj, name, splitter, sizeof(*splitter),
188                                 TYPE_SPLIT_IRQ, &error_abort, NULL);
189         g_free(name);
190     }
191     sysbus_init_child_obj(obj, "timer0", &s->timer0, sizeof(s->timer0),
192                           TYPE_CMSDK_APB_TIMER);
193     sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1),
194                           TYPE_CMSDK_APB_TIMER);
195     sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer),
196                           TYPE_CMSDK_APB_TIMER);
197     sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
198                           TYPE_CMSDK_APB_DUALTIMER);
199     sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog,
200                           sizeof(s->s32kwatchdog), TYPE_CMSDK_APB_WATCHDOG);
201     sysbus_init_child_obj(obj, "nswatchdog", &s->nswatchdog,
202                           sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
203     sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
204                           sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
205     sysbus_init_child_obj(obj, "armsse-sysctl", &s->sysctl,
206                           sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
207     sysbus_init_child_obj(obj, "armsse-sysinfo", &s->sysinfo,
208                           sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
209     object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
210                             sizeof(s->nmi_orgate), TYPE_OR_IRQ,
211                             &error_abort, NULL);
212     object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
213                             sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ,
214                             &error_abort, NULL);
215     object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
216                             sizeof(s->sec_resp_splitter), TYPE_SPLIT_IRQ,
217                             &error_abort, NULL);
218     for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
219         char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
220         SplitIRQ *splitter = &s->ppc_irq_splitter[i];
221 
222         object_initialize_child(obj, name, splitter, sizeof(*splitter),
223                                 TYPE_SPLIT_IRQ, &error_abort, NULL);
224         g_free(name);
225     }
226     if (info->num_cpus > 1) {
227         for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
228             if (irq_is_common[i]) {
229                 char *name = g_strdup_printf("cpu-irq-splitter%d", i);
230                 SplitIRQ *splitter = &s->cpu_irq_splitter[i];
231 
232                 object_initialize_child(obj, name, splitter, sizeof(*splitter),
233                                         TYPE_SPLIT_IRQ, &error_abort, NULL);
234                 g_free(name);
235             }
236         }
237     }
238 }
239 
240 static void armsse_exp_irq(void *opaque, int n, int level)
241 {
242     qemu_irq *irqarray = opaque;
243 
244     qemu_set_irq(irqarray[n], level);
245 }
246 
247 static void armsse_mpcexp_status(void *opaque, int n, int level)
248 {
249     ARMSSE *s = ARMSSE(opaque);
250     qemu_set_irq(s->mpcexp_status_in[n], level);
251 }
252 
253 static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
254 {
255     /*
256      * Return a qemu_irq which can be used to signal IRQ n to
257      * all CPUs in the SSE.
258      */
259     ARMSSEClass *asc = ARMSSE_GET_CLASS(s);
260     const ARMSSEInfo *info = asc->info;
261 
262     assert(irq_is_common[irqno]);
263 
264     if (info->num_cpus == 1) {
265         /* Only one CPU -- just connect directly to it */
266         return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
267     } else {
268         /* Connect to the splitter which feeds all CPUs */
269         return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
270     }
271 }
272 
273 static void armsse_realize(DeviceState *dev, Error **errp)
274 {
275     ARMSSE *s = ARMSSE(dev);
276     ARMSSEClass *asc = ARMSSE_GET_CLASS(dev);
277     const ARMSSEInfo *info = asc->info;
278     int i;
279     MemoryRegion *mr;
280     Error *err = NULL;
281     SysBusDevice *sbd_apb_ppc0;
282     SysBusDevice *sbd_secctl;
283     DeviceState *dev_apb_ppc0;
284     DeviceState *dev_apb_ppc1;
285     DeviceState *dev_secctl;
286     DeviceState *dev_splitter;
287     uint32_t addr_width_max;
288 
289     if (!s->board_memory) {
290         error_setg(errp, "memory property was not set");
291         return;
292     }
293 
294     if (!s->mainclk_frq) {
295         error_setg(errp, "MAINCLK property was not set");
296         return;
297     }
298 
299     /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
300     assert(is_power_of_2(info->sram_banks));
301     addr_width_max = 24 - ctz32(info->sram_banks);
302     if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
303         error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
304                    addr_width_max);
305         return;
306     }
307 
308     /* Handling of which devices should be available only to secure
309      * code is usually done differently for M profile than for A profile.
310      * Instead of putting some devices only into the secure address space,
311      * devices exist in both address spaces but with hard-wired security
312      * permissions that will cause the CPU to fault for non-secure accesses.
313      *
314      * The ARMSSE has an IDAU (Implementation Defined Access Unit),
315      * which specifies hard-wired security permissions for different
316      * areas of the physical address space. For the ARMSSE IDAU, the
317      * top 4 bits of the physical address are the IDAU region ID, and
318      * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
319      * region, otherwise it is an S region.
320      *
321      * The various devices and RAMs are generally all mapped twice,
322      * once into a region that the IDAU defines as secure and once
323      * into a non-secure region. They sit behind either a Memory
324      * Protection Controller (for RAM) or a Peripheral Protection
325      * Controller (for devices), which allow a more fine grained
326      * configuration of whether non-secure accesses are permitted.
327      *
328      * (The other place that guest software can configure security
329      * permissions is in the architected SAU (Security Attribution
330      * Unit), which is entirely inside the CPU. The IDAU can upgrade
331      * the security attributes for a region to more restrictive than
332      * the SAU specifies, but cannot downgrade them.)
333      *
334      * 0x10000000..0x1fffffff  alias of 0x00000000..0x0fffffff
335      * 0x20000000..0x2007ffff  32KB FPGA block RAM
336      * 0x30000000..0x3fffffff  alias of 0x20000000..0x2fffffff
337      * 0x40000000..0x4000ffff  base peripheral region 1
338      * 0x40010000..0x4001ffff  CPU peripherals (none for ARMSSE)
339      * 0x40020000..0x4002ffff  system control element peripherals
340      * 0x40080000..0x400fffff  base peripheral region 2
341      * 0x50000000..0x5fffffff  alias of 0x40000000..0x4fffffff
342      */
343 
344     memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
345 
346     for (i = 0; i < info->num_cpus; i++) {
347         DeviceState *cpudev = DEVICE(&s->armv7m[i]);
348         Object *cpuobj = OBJECT(&s->armv7m[i]);
349         int j;
350         char *gpioname;
351 
352         qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + 32);
353         /*
354          * In real hardware the initial Secure VTOR is set from the INITSVTOR0
355          * register in the IoT Kit System Control Register block, and the
356          * initial value of that is in turn specifiable by the FPGA that
357          * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
358          * and simply set the CPU's init-svtor to the IoT Kit default value.
359          * In SSE-200 the situation is similar, except that the default value
360          * is a reset-time signal input. Typically a board using the SSE-200
361          * will have a system control processor whose boot firmware initializes
362          * the INITSVTOR* registers before powering up the CPUs in any case,
363          * so the hardware's default value doesn't matter. QEMU doesn't emulate
364          * the control processor, so instead we behave in the way that the
365          * firmware does. All boards currently known about have firmware that
366          * sets the INITSVTOR0 and INITSVTOR1 registers to 0x10000000, like the
367          * IoTKit default. We can make this more configurable if necessary.
368          */
369         qdev_prop_set_uint32(cpudev, "init-svtor", 0x10000000);
370         /*
371          * Start all CPUs except CPU0 powered down. In real hardware it is
372          * a configurable property of the SSE-200 which CPUs start powered up
373          * (via the CPUWAIT0_RST and CPUWAIT1_RST parameters), but since all
374          * the boards we care about start CPU0 and leave CPU1 powered off,
375          * we hard-code that for now. We can add QOM properties for this
376          * later if necessary.
377          */
378         if (i > 0) {
379             object_property_set_bool(cpuobj, true, "start-powered-off", &err);
380             if (err) {
381                 error_propagate(errp, err);
382                 return;
383             }
384         }
385 
386         if (i > 0) {
387             memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
388                                                 &s->container_alias[i - 1], -1);
389         } else {
390             memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
391                                                 &s->container, -1);
392         }
393         object_property_set_link(cpuobj, OBJECT(&s->cpu_container[i]),
394                                  "memory", &err);
395         if (err) {
396             error_propagate(errp, err);
397             return;
398         }
399         object_property_set_link(cpuobj, OBJECT(s), "idau", &err);
400         if (err) {
401             error_propagate(errp, err);
402             return;
403         }
404         object_property_set_bool(cpuobj, true, "realized", &err);
405         if (err) {
406             error_propagate(errp, err);
407             return;
408         }
409 
410         /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
411         s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
412         for (j = 0; j < s->exp_numirq; j++) {
413             s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, i + 32);
414         }
415         if (i == 0) {
416             gpioname = g_strdup("EXP_IRQ");
417         } else {
418             gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
419         }
420         qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
421                                             s->exp_irqs[i],
422                                             gpioname, s->exp_numirq);
423         g_free(gpioname);
424     }
425 
426     /* Wire up the splitters that connect common IRQs to all CPUs */
427     if (info->num_cpus > 1) {
428         for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
429             if (irq_is_common[i]) {
430                 Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
431                 DeviceState *devs = DEVICE(splitter);
432                 int cpunum;
433 
434                 object_property_set_int(splitter, info->num_cpus,
435                                         "num-lines", &err);
436                 if (err) {
437                     error_propagate(errp, err);
438                     return;
439                 }
440                 object_property_set_bool(splitter, true, "realized", &err);
441                 if (err) {
442                     error_propagate(errp, err);
443                     return;
444                 }
445                 for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
446                     DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
447 
448                     qdev_connect_gpio_out(devs, cpunum,
449                                           qdev_get_gpio_in(cpudev, i));
450                 }
451             }
452         }
453     }
454 
455     /* Set up the big aliases first */
456     make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000);
457     make_alias(s, &s->alias2, "alias 2", 0x30000000, 0x10000000, 0x20000000);
458     /* The 0x50000000..0x5fffffff region is not a pure alias: it has
459      * a few extra devices that only appear there (generally the
460      * control interfaces for the protection controllers).
461      * We implement this by mapping those devices over the top of this
462      * alias MR at a higher priority.
463      */
464     make_alias(s, &s->alias3, "alias 3", 0x50000000, 0x10000000, 0x40000000);
465 
466 
467     /* Security controller */
468     object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err);
469     if (err) {
470         error_propagate(errp, err);
471         return;
472     }
473     sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
474     dev_secctl = DEVICE(&s->secctl);
475     sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
476     sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
477 
478     s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
479     qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
480 
481     /* The sec_resp_cfg output from the security controller must be split into
482      * multiple lines, one for each of the PPCs within the ARMSSE and one
483      * that will be an output from the ARMSSE to the system.
484      */
485     object_property_set_int(OBJECT(&s->sec_resp_splitter), 3,
486                             "num-lines", &err);
487     if (err) {
488         error_propagate(errp, err);
489         return;
490     }
491     object_property_set_bool(OBJECT(&s->sec_resp_splitter), true,
492                              "realized", &err);
493     if (err) {
494         error_propagate(errp, err);
495         return;
496     }
497     dev_splitter = DEVICE(&s->sec_resp_splitter);
498     qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
499                                 qdev_get_gpio_in(dev_splitter, 0));
500 
501     /* Each SRAM bank lives behind its own Memory Protection Controller */
502     for (i = 0; i < info->sram_banks; i++) {
503         char *ramname = g_strdup_printf("armsse.sram%d", i);
504         SysBusDevice *sbd_mpc;
505         uint32_t sram_bank_size = 1 << s->sram_addr_width;
506 
507         memory_region_init_ram(&s->sram[i], NULL, ramname,
508                                sram_bank_size, &err);
509         g_free(ramname);
510         if (err) {
511             error_propagate(errp, err);
512             return;
513         }
514         object_property_set_link(OBJECT(&s->mpc[i]), OBJECT(&s->sram[i]),
515                                  "downstream", &err);
516         if (err) {
517             error_propagate(errp, err);
518             return;
519         }
520         object_property_set_bool(OBJECT(&s->mpc[i]), true, "realized", &err);
521         if (err) {
522             error_propagate(errp, err);
523             return;
524         }
525         /* Map the upstream end of the MPC into the right place... */
526         sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
527         memory_region_add_subregion(&s->container,
528                                     0x20000000 + i * sram_bank_size,
529                                     sysbus_mmio_get_region(sbd_mpc, 1));
530         /* ...and its register interface */
531         memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
532                                     sysbus_mmio_get_region(sbd_mpc, 0));
533     }
534 
535     /* We must OR together lines from the MPC splitters to go to the NVIC */
536     object_property_set_int(OBJECT(&s->mpc_irq_orgate),
537                             IOTS_NUM_EXP_MPC + info->sram_banks,
538                             "num-lines", &err);
539     if (err) {
540         error_propagate(errp, err);
541         return;
542     }
543     object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
544                              "realized", &err);
545     if (err) {
546         error_propagate(errp, err);
547         return;
548     }
549     qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
550                           armsse_get_common_irq_in(s, 9));
551 
552     /* Devices behind APB PPC0:
553      *   0x40000000: timer0
554      *   0x40001000: timer1
555      *   0x40002000: dual timer
556      * We must configure and realize each downstream device and connect
557      * it to the appropriate PPC port; then we can realize the PPC and
558      * map its upstream ends to the right place in the container.
559      */
560     qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
561     object_property_set_bool(OBJECT(&s->timer0), true, "realized", &err);
562     if (err) {
563         error_propagate(errp, err);
564         return;
565     }
566     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
567                        armsse_get_common_irq_in(s, 3));
568     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
569     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err);
570     if (err) {
571         error_propagate(errp, err);
572         return;
573     }
574 
575     qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
576     object_property_set_bool(OBJECT(&s->timer1), true, "realized", &err);
577     if (err) {
578         error_propagate(errp, err);
579         return;
580     }
581     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
582                        armsse_get_common_irq_in(s, 4));
583     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
584     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err);
585     if (err) {
586         error_propagate(errp, err);
587         return;
588     }
589 
590 
591     qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
592     object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err);
593     if (err) {
594         error_propagate(errp, err);
595         return;
596     }
597     sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
598                        armsse_get_common_irq_in(s, 5));
599     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
600     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
601     if (err) {
602         error_propagate(errp, err);
603         return;
604     }
605 
606     object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err);
607     if (err) {
608         error_propagate(errp, err);
609         return;
610     }
611 
612     sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0);
613     dev_apb_ppc0 = DEVICE(&s->apb_ppc0);
614 
615     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
616     memory_region_add_subregion(&s->container, 0x40000000, mr);
617     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1);
618     memory_region_add_subregion(&s->container, 0x40001000, mr);
619     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
620     memory_region_add_subregion(&s->container, 0x40002000, mr);
621     for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
622         qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
623                                     qdev_get_gpio_in_named(dev_apb_ppc0,
624                                                            "cfg_nonsec", i));
625         qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
626                                     qdev_get_gpio_in_named(dev_apb_ppc0,
627                                                            "cfg_ap", i));
628     }
629     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
630                                 qdev_get_gpio_in_named(dev_apb_ppc0,
631                                                        "irq_enable", 0));
632     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
633                                 qdev_get_gpio_in_named(dev_apb_ppc0,
634                                                        "irq_clear", 0));
635     qdev_connect_gpio_out(dev_splitter, 0,
636                           qdev_get_gpio_in_named(dev_apb_ppc0,
637                                                  "cfg_sec_resp", 0));
638 
639     /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
640      * ones) are sent individually to the security controller, and also
641      * ORed together to give a single combined PPC interrupt to the NVIC.
642      */
643     object_property_set_int(OBJECT(&s->ppc_irq_orgate),
644                             NUM_PPCS, "num-lines", &err);
645     if (err) {
646         error_propagate(errp, err);
647         return;
648     }
649     object_property_set_bool(OBJECT(&s->ppc_irq_orgate), true,
650                              "realized", &err);
651     if (err) {
652         error_propagate(errp, err);
653         return;
654     }
655     qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
656                           armsse_get_common_irq_in(s, 10));
657 
658     /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
659 
660     /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
661     /* Devices behind APB PPC1:
662      *   0x4002f000: S32K timer
663      */
664     qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
665     object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err);
666     if (err) {
667         error_propagate(errp, err);
668         return;
669     }
670     sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
671                        armsse_get_common_irq_in(s, 2));
672     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
673     object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
674     if (err) {
675         error_propagate(errp, err);
676         return;
677     }
678 
679     object_property_set_bool(OBJECT(&s->apb_ppc1), true, "realized", &err);
680     if (err) {
681         error_propagate(errp, err);
682         return;
683     }
684     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0);
685     memory_region_add_subregion(&s->container, 0x4002f000, mr);
686 
687     dev_apb_ppc1 = DEVICE(&s->apb_ppc1);
688     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
689                                 qdev_get_gpio_in_named(dev_apb_ppc1,
690                                                        "cfg_nonsec", 0));
691     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
692                                 qdev_get_gpio_in_named(dev_apb_ppc1,
693                                                        "cfg_ap", 0));
694     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
695                                 qdev_get_gpio_in_named(dev_apb_ppc1,
696                                                        "irq_enable", 0));
697     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
698                                 qdev_get_gpio_in_named(dev_apb_ppc1,
699                                                        "irq_clear", 0));
700     qdev_connect_gpio_out(dev_splitter, 1,
701                           qdev_get_gpio_in_named(dev_apb_ppc1,
702                                                  "cfg_sec_resp", 0));
703 
704     object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
705     if (err) {
706         error_propagate(errp, err);
707         return;
708     }
709     /* System information registers */
710     sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
711     /* System control registers */
712     object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
713     if (err) {
714         error_propagate(errp, err);
715         return;
716     }
717     sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
718 
719     /* This OR gate wires together outputs from the secure watchdogs to NMI */
720     object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
721     if (err) {
722         error_propagate(errp, err);
723         return;
724     }
725     object_property_set_bool(OBJECT(&s->nmi_orgate), true, "realized", &err);
726     if (err) {
727         error_propagate(errp, err);
728         return;
729     }
730     qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
731                           qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
732 
733     qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
734     object_property_set_bool(OBJECT(&s->s32kwatchdog), true, "realized", &err);
735     if (err) {
736         error_propagate(errp, err);
737         return;
738     }
739     sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0,
740                        qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
741     sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
742 
743     /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
744 
745     qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
746     object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err);
747     if (err) {
748         error_propagate(errp, err);
749         return;
750     }
751     sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
752                        armsse_get_common_irq_in(s, 1));
753     sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
754 
755     qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
756     object_property_set_bool(OBJECT(&s->swatchdog), true, "realized", &err);
757     if (err) {
758         error_propagate(errp, err);
759         return;
760     }
761     sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0,
762                        qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1));
763     sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000);
764 
765     for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
766         Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
767 
768         object_property_set_int(splitter, 2, "num-lines", &err);
769         if (err) {
770             error_propagate(errp, err);
771             return;
772         }
773         object_property_set_bool(splitter, true, "realized", &err);
774         if (err) {
775             error_propagate(errp, err);
776             return;
777         }
778     }
779 
780     for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
781         char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
782 
783         armsse_forward_ppc(s, ppcname, i);
784         g_free(ppcname);
785     }
786 
787     for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
788         char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
789 
790         armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
791         g_free(ppcname);
792     }
793 
794     for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
795         /* Wire up IRQ splitter for internal PPCs */
796         DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
797         char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
798                                          i - NUM_EXTERNAL_PPCS);
799         TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1;
800 
801         qdev_connect_gpio_out(devs, 0,
802                               qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
803         qdev_connect_gpio_out(devs, 1,
804                               qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
805         qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
806                                     qdev_get_gpio_in(devs, 0));
807         g_free(gpioname);
808     }
809 
810     /* Wire up the splitters for the MPC IRQs */
811     for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
812         SplitIRQ *splitter = &s->mpc_irq_splitter[i];
813         DeviceState *dev_splitter = DEVICE(splitter);
814 
815         object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
816         if (err) {
817             error_propagate(errp, err);
818             return;
819         }
820         object_property_set_bool(OBJECT(splitter), true, "realized", &err);
821         if (err) {
822             error_propagate(errp, err);
823             return;
824         }
825 
826         if (i < IOTS_NUM_EXP_MPC) {
827             /* Splitter input is from GPIO input line */
828             s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
829             qdev_connect_gpio_out(dev_splitter, 0,
830                                   qdev_get_gpio_in_named(dev_secctl,
831                                                          "mpcexp_status", i));
832         } else {
833             /* Splitter input is from our own MPC */
834             qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
835                                         "irq", 0,
836                                         qdev_get_gpio_in(dev_splitter, 0));
837             qdev_connect_gpio_out(dev_splitter, 0,
838                                   qdev_get_gpio_in_named(dev_secctl,
839                                                          "mpc_status", 0));
840         }
841 
842         qdev_connect_gpio_out(dev_splitter, 1,
843                               qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
844     }
845     /* Create GPIO inputs which will pass the line state for our
846      * mpcexp_irq inputs to the correct splitter devices.
847      */
848     qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
849                             IOTS_NUM_EXP_MPC);
850 
851     armsse_forward_sec_resp_cfg(s);
852 
853     /* Forward the MSC related signals */
854     qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
855     qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
856     qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
857     qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
858                                 armsse_get_common_irq_in(s, 11));
859 
860     /*
861      * Expose our container region to the board model; this corresponds
862      * to the AHB Slave Expansion ports which allow bus master devices
863      * (eg DMA controllers) in the board model to make transactions into
864      * devices in the ARMSSE.
865      */
866     sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
867 
868     system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
869 }
870 
871 static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
872                               int *iregion, bool *exempt, bool *ns, bool *nsc)
873 {
874     /*
875      * For ARMSSE systems the IDAU responses are simple logical functions
876      * of the address bits. The NSC attribute is guest-adjustable via the
877      * NSCCFG register in the security controller.
878      */
879     ARMSSE *s = ARMSSE(ii);
880     int region = extract32(address, 28, 4);
881 
882     *ns = !(region & 1);
883     *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
884     /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
885     *exempt = (address & 0xeff00000) == 0xe0000000;
886     *iregion = region;
887 }
888 
889 static const VMStateDescription armsse_vmstate = {
890     .name = "iotkit",
891     .version_id = 1,
892     .minimum_version_id = 1,
893     .fields = (VMStateField[]) {
894         VMSTATE_UINT32(nsccfg, ARMSSE),
895         VMSTATE_END_OF_LIST()
896     }
897 };
898 
899 static Property armsse_properties[] = {
900     DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
901                      MemoryRegion *),
902     DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
903     DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
904     DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
905     DEFINE_PROP_END_OF_LIST()
906 };
907 
908 static void armsse_reset(DeviceState *dev)
909 {
910     ARMSSE *s = ARMSSE(dev);
911 
912     s->nsccfg = 0;
913 }
914 
915 static void armsse_class_init(ObjectClass *klass, void *data)
916 {
917     DeviceClass *dc = DEVICE_CLASS(klass);
918     IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
919     ARMSSEClass *asc = ARMSSE_CLASS(klass);
920 
921     dc->realize = armsse_realize;
922     dc->vmsd = &armsse_vmstate;
923     dc->props = armsse_properties;
924     dc->reset = armsse_reset;
925     iic->check = armsse_idau_check;
926     asc->info = data;
927 }
928 
929 static const TypeInfo armsse_info = {
930     .name = TYPE_ARMSSE,
931     .parent = TYPE_SYS_BUS_DEVICE,
932     .instance_size = sizeof(ARMSSE),
933     .instance_init = armsse_init,
934     .abstract = true,
935     .interfaces = (InterfaceInfo[]) {
936         { TYPE_IDAU_INTERFACE },
937         { }
938     }
939 };
940 
941 static void armsse_register_types(void)
942 {
943     int i;
944 
945     type_register_static(&armsse_info);
946 
947     for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
948         TypeInfo ti = {
949             .name = armsse_variants[i].name,
950             .parent = TYPE_ARMSSE,
951             .class_init = armsse_class_init,
952             .class_data = (void *)&armsse_variants[i],
953         };
954         type_register(&ti);
955     }
956 }
957 
958 type_init(armsse_register_types);
959