xref: /qemu/hw/arm/armsse.c (revision 310b3fe9)
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 "qemu/bitops.h"
15 #include "qapi/error.h"
16 #include "trace.h"
17 #include "hw/sysbus.h"
18 #include "hw/registerfields.h"
19 #include "hw/arm/armsse.h"
20 #include "hw/arm/arm.h"
21 
22 /* Format of the System Information block SYS_CONFIG register */
23 typedef enum SysConfigFormat {
24     IoTKitFormat,
25     SSE200Format,
26 } SysConfigFormat;
27 
28 struct ARMSSEInfo {
29     const char *name;
30     int sram_banks;
31     int num_cpus;
32     uint32_t sys_version;
33     uint32_t cpuwait_rst;
34     SysConfigFormat sys_config_format;
35     bool has_mhus;
36     bool has_ppus;
37     bool has_cachectrl;
38     bool has_cpusecctrl;
39     bool has_cpuid;
40 };
41 
42 static const ARMSSEInfo armsse_variants[] = {
43     {
44         .name = TYPE_IOTKIT,
45         .sram_banks = 1,
46         .num_cpus = 1,
47         .sys_version = 0x41743,
48         .cpuwait_rst = 0,
49         .sys_config_format = IoTKitFormat,
50         .has_mhus = false,
51         .has_ppus = false,
52         .has_cachectrl = false,
53         .has_cpusecctrl = false,
54         .has_cpuid = false,
55     },
56     {
57         .name = TYPE_SSE200,
58         .sram_banks = 4,
59         .num_cpus = 2,
60         .sys_version = 0x22041743,
61         .cpuwait_rst = 2,
62         .sys_config_format = SSE200Format,
63         .has_mhus = true,
64         .has_ppus = true,
65         .has_cachectrl = true,
66         .has_cpusecctrl = true,
67         .has_cpuid = true,
68     },
69 };
70 
71 static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
72 {
73     /* Return the SYS_CONFIG value for this SSE */
74     uint32_t sys_config;
75 
76     switch (info->sys_config_format) {
77     case IoTKitFormat:
78         sys_config = 0;
79         sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
80         sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
81         break;
82     case SSE200Format:
83         sys_config = 0;
84         sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
85         sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
86         sys_config = deposit32(sys_config, 24, 4, 2);
87         if (info->num_cpus > 1) {
88             sys_config = deposit32(sys_config, 10, 1, 1);
89             sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
90             sys_config = deposit32(sys_config, 28, 4, 2);
91         }
92         break;
93     default:
94         g_assert_not_reached();
95     }
96     return sys_config;
97 }
98 
99 /* Clock frequency in HZ of the 32KHz "slow clock" */
100 #define S32KCLK (32 * 1000)
101 
102 /* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
103 static bool irq_is_common[32] = {
104     [0 ... 5] = true,
105     /* 6, 7: per-CPU MHU interrupts */
106     [8 ... 12] = true,
107     /* 13: per-CPU icache interrupt */
108     /* 14: reserved */
109     [15 ... 20] = true,
110     /* 21: reserved */
111     [22 ... 26] = true,
112     /* 27: reserved */
113     /* 28, 29: per-CPU CTI interrupts */
114     /* 30, 31: reserved */
115 };
116 
117 /*
118  * Create an alias region in @container of @size bytes starting at @base
119  * which mirrors the memory starting at @orig.
120  */
121 static void make_alias(ARMSSE *s, MemoryRegion *mr, MemoryRegion *container,
122                        const char *name, hwaddr base, hwaddr size, hwaddr orig)
123 {
124     memory_region_init_alias(mr, NULL, name, container, orig, size);
125     /* The alias is even lower priority than unimplemented_device regions */
126     memory_region_add_subregion_overlap(container, base, mr, -1500);
127 }
128 
129 static void irq_status_forwarder(void *opaque, int n, int level)
130 {
131     qemu_irq destirq = opaque;
132 
133     qemu_set_irq(destirq, level);
134 }
135 
136 static void nsccfg_handler(void *opaque, int n, int level)
137 {
138     ARMSSE *s = ARMSSE(opaque);
139 
140     s->nsccfg = level;
141 }
142 
143 static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
144 {
145     /* Each of the 4 AHB and 4 APB PPCs that might be present in a
146      * system using the ARMSSE has a collection of control lines which
147      * are provided by the security controller and which we want to
148      * expose as control lines on the ARMSSE device itself, so the
149      * code using the ARMSSE can wire them up to the PPCs.
150      */
151     SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
152     DeviceState *armssedev = DEVICE(s);
153     DeviceState *dev_secctl = DEVICE(&s->secctl);
154     DeviceState *dev_splitter = DEVICE(splitter);
155     char *name;
156 
157     name = g_strdup_printf("%s_nonsec", ppcname);
158     qdev_pass_gpios(dev_secctl, armssedev, name);
159     g_free(name);
160     name = g_strdup_printf("%s_ap", ppcname);
161     qdev_pass_gpios(dev_secctl, armssedev, name);
162     g_free(name);
163     name = g_strdup_printf("%s_irq_enable", ppcname);
164     qdev_pass_gpios(dev_secctl, armssedev, name);
165     g_free(name);
166     name = g_strdup_printf("%s_irq_clear", ppcname);
167     qdev_pass_gpios(dev_secctl, armssedev, name);
168     g_free(name);
169 
170     /* irq_status is a little more tricky, because we need to
171      * split it so we can send it both to the security controller
172      * and to our OR gate for the NVIC interrupt line.
173      * Connect up the splitter's outputs, and create a GPIO input
174      * which will pass the line state to the input splitter.
175      */
176     name = g_strdup_printf("%s_irq_status", ppcname);
177     qdev_connect_gpio_out(dev_splitter, 0,
178                           qdev_get_gpio_in_named(dev_secctl,
179                                                  name, 0));
180     qdev_connect_gpio_out(dev_splitter, 1,
181                           qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
182     s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
183     qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
184                                         s->irq_status_in[ppcnum], name, 1);
185     g_free(name);
186 }
187 
188 static void armsse_forward_sec_resp_cfg(ARMSSE *s)
189 {
190     /* Forward the 3rd output from the splitter device as a
191      * named GPIO output of the armsse object.
192      */
193     DeviceState *dev = DEVICE(s);
194     DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
195 
196     qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
197     s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
198                                            s->sec_resp_cfg, 1);
199     qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
200 }
201 
202 static void armsse_init(Object *obj)
203 {
204     ARMSSE *s = ARMSSE(obj);
205     ARMSSEClass *asc = ARMSSE_GET_CLASS(obj);
206     const ARMSSEInfo *info = asc->info;
207     int i;
208 
209     assert(info->sram_banks <= MAX_SRAM_BANKS);
210     assert(info->num_cpus <= SSE_MAX_CPUS);
211 
212     memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
213 
214     for (i = 0; i < info->num_cpus; i++) {
215         /*
216          * We put each CPU in its own cluster as they are logically
217          * distinct and may be configured differently.
218          */
219         char *name;
220 
221         name = g_strdup_printf("cluster%d", i);
222         object_initialize_child(obj, name, &s->cluster[i],
223                                 sizeof(s->cluster[i]), TYPE_CPU_CLUSTER,
224                                 &error_abort, NULL);
225         qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
226         g_free(name);
227 
228         name = g_strdup_printf("armv7m%d", i);
229         sysbus_init_child_obj(OBJECT(&s->cluster[i]), name,
230                               &s->armv7m[i], sizeof(s->armv7m), TYPE_ARMV7M);
231         qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
232                              ARM_CPU_TYPE_NAME("cortex-m33"));
233         g_free(name);
234         name = g_strdup_printf("arm-sse-cpu-container%d", i);
235         memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
236         g_free(name);
237         if (i > 0) {
238             name = g_strdup_printf("arm-sse-container-alias%d", i);
239             memory_region_init_alias(&s->container_alias[i - 1], obj,
240                                      name, &s->container, 0, UINT64_MAX);
241             g_free(name);
242         }
243     }
244 
245     sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
246                           TYPE_IOTKIT_SECCTL);
247     sysbus_init_child_obj(obj, "apb-ppc0", &s->apb_ppc0, sizeof(s->apb_ppc0),
248                           TYPE_TZ_PPC);
249     sysbus_init_child_obj(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
250                           TYPE_TZ_PPC);
251     for (i = 0; i < info->sram_banks; i++) {
252         char *name = g_strdup_printf("mpc%d", i);
253         sysbus_init_child_obj(obj, name, &s->mpc[i],
254                               sizeof(s->mpc[i]), TYPE_TZ_MPC);
255         g_free(name);
256     }
257     object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
258                             sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
259                             &error_abort, NULL);
260 
261     for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
262         char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
263         SplitIRQ *splitter = &s->mpc_irq_splitter[i];
264 
265         object_initialize_child(obj, name, splitter, sizeof(*splitter),
266                                 TYPE_SPLIT_IRQ, &error_abort, NULL);
267         g_free(name);
268     }
269     sysbus_init_child_obj(obj, "timer0", &s->timer0, sizeof(s->timer0),
270                           TYPE_CMSDK_APB_TIMER);
271     sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1),
272                           TYPE_CMSDK_APB_TIMER);
273     sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer),
274                           TYPE_CMSDK_APB_TIMER);
275     sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
276                           TYPE_CMSDK_APB_DUALTIMER);
277     sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog,
278                           sizeof(s->s32kwatchdog), TYPE_CMSDK_APB_WATCHDOG);
279     sysbus_init_child_obj(obj, "nswatchdog", &s->nswatchdog,
280                           sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
281     sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
282                           sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
283     sysbus_init_child_obj(obj, "armsse-sysctl", &s->sysctl,
284                           sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
285     sysbus_init_child_obj(obj, "armsse-sysinfo", &s->sysinfo,
286                           sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
287     if (info->has_mhus) {
288         sysbus_init_child_obj(obj, "mhu0", &s->mhu[0], sizeof(s->mhu[0]),
289                               TYPE_ARMSSE_MHU);
290         sysbus_init_child_obj(obj, "mhu1", &s->mhu[1], sizeof(s->mhu[1]),
291                               TYPE_ARMSSE_MHU);
292     }
293     if (info->has_ppus) {
294         for (i = 0; i < info->num_cpus; i++) {
295             char *name = g_strdup_printf("CPU%dCORE_PPU", i);
296             int ppuidx = CPU0CORE_PPU + i;
297 
298             sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
299                                   sizeof(s->ppu[ppuidx]),
300                                   TYPE_UNIMPLEMENTED_DEVICE);
301             g_free(name);
302         }
303         sysbus_init_child_obj(obj, "DBG_PPU", &s->ppu[DBG_PPU],
304                               sizeof(s->ppu[DBG_PPU]),
305                               TYPE_UNIMPLEMENTED_DEVICE);
306         for (i = 0; i < info->sram_banks; i++) {
307             char *name = g_strdup_printf("RAM%d_PPU", i);
308             int ppuidx = RAM0_PPU + i;
309 
310             sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
311                                   sizeof(s->ppu[ppuidx]),
312                                   TYPE_UNIMPLEMENTED_DEVICE);
313             g_free(name);
314         }
315     }
316     if (info->has_cachectrl) {
317         for (i = 0; i < info->num_cpus; i++) {
318             char *name = g_strdup_printf("cachectrl%d", i);
319 
320             sysbus_init_child_obj(obj, name, &s->cachectrl[i],
321                                   sizeof(s->cachectrl[i]),
322                                   TYPE_UNIMPLEMENTED_DEVICE);
323             g_free(name);
324         }
325     }
326     if (info->has_cpusecctrl) {
327         for (i = 0; i < info->num_cpus; i++) {
328             char *name = g_strdup_printf("cpusecctrl%d", i);
329 
330             sysbus_init_child_obj(obj, name, &s->cpusecctrl[i],
331                                   sizeof(s->cpusecctrl[i]),
332                                   TYPE_UNIMPLEMENTED_DEVICE);
333             g_free(name);
334         }
335     }
336     if (info->has_cpuid) {
337         for (i = 0; i < info->num_cpus; i++) {
338             char *name = g_strdup_printf("cpuid%d", i);
339 
340             sysbus_init_child_obj(obj, name, &s->cpuid[i],
341                                   sizeof(s->cpuid[i]),
342                                   TYPE_ARMSSE_CPUID);
343             g_free(name);
344         }
345     }
346     object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
347                             sizeof(s->nmi_orgate), TYPE_OR_IRQ,
348                             &error_abort, NULL);
349     object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
350                             sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ,
351                             &error_abort, NULL);
352     object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
353                             sizeof(s->sec_resp_splitter), TYPE_SPLIT_IRQ,
354                             &error_abort, NULL);
355     for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
356         char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
357         SplitIRQ *splitter = &s->ppc_irq_splitter[i];
358 
359         object_initialize_child(obj, name, splitter, sizeof(*splitter),
360                                 TYPE_SPLIT_IRQ, &error_abort, NULL);
361         g_free(name);
362     }
363     if (info->num_cpus > 1) {
364         for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
365             if (irq_is_common[i]) {
366                 char *name = g_strdup_printf("cpu-irq-splitter%d", i);
367                 SplitIRQ *splitter = &s->cpu_irq_splitter[i];
368 
369                 object_initialize_child(obj, name, splitter, sizeof(*splitter),
370                                         TYPE_SPLIT_IRQ, &error_abort, NULL);
371                 g_free(name);
372             }
373         }
374     }
375 }
376 
377 static void armsse_exp_irq(void *opaque, int n, int level)
378 {
379     qemu_irq *irqarray = opaque;
380 
381     qemu_set_irq(irqarray[n], level);
382 }
383 
384 static void armsse_mpcexp_status(void *opaque, int n, int level)
385 {
386     ARMSSE *s = ARMSSE(opaque);
387     qemu_set_irq(s->mpcexp_status_in[n], level);
388 }
389 
390 static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
391 {
392     /*
393      * Return a qemu_irq which can be used to signal IRQ n to
394      * all CPUs in the SSE.
395      */
396     ARMSSEClass *asc = ARMSSE_GET_CLASS(s);
397     const ARMSSEInfo *info = asc->info;
398 
399     assert(irq_is_common[irqno]);
400 
401     if (info->num_cpus == 1) {
402         /* Only one CPU -- just connect directly to it */
403         return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
404     } else {
405         /* Connect to the splitter which feeds all CPUs */
406         return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
407     }
408 }
409 
410 static void map_ppu(ARMSSE *s, int ppuidx, const char *name, hwaddr addr)
411 {
412     /* Map a PPU unimplemented device stub */
413     DeviceState *dev = DEVICE(&s->ppu[ppuidx]);
414 
415     qdev_prop_set_string(dev, "name", name);
416     qdev_prop_set_uint64(dev, "size", 0x1000);
417     qdev_init_nofail(dev);
418     sysbus_mmio_map(SYS_BUS_DEVICE(&s->ppu[ppuidx]), 0, addr);
419 }
420 
421 static void armsse_realize(DeviceState *dev, Error **errp)
422 {
423     ARMSSE *s = ARMSSE(dev);
424     ARMSSEClass *asc = ARMSSE_GET_CLASS(dev);
425     const ARMSSEInfo *info = asc->info;
426     int i;
427     MemoryRegion *mr;
428     Error *err = NULL;
429     SysBusDevice *sbd_apb_ppc0;
430     SysBusDevice *sbd_secctl;
431     DeviceState *dev_apb_ppc0;
432     DeviceState *dev_apb_ppc1;
433     DeviceState *dev_secctl;
434     DeviceState *dev_splitter;
435     uint32_t addr_width_max;
436 
437     if (!s->board_memory) {
438         error_setg(errp, "memory property was not set");
439         return;
440     }
441 
442     if (!s->mainclk_frq) {
443         error_setg(errp, "MAINCLK property was not set");
444         return;
445     }
446 
447     /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
448     assert(is_power_of_2(info->sram_banks));
449     addr_width_max = 24 - ctz32(info->sram_banks);
450     if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
451         error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
452                    addr_width_max);
453         return;
454     }
455 
456     /* Handling of which devices should be available only to secure
457      * code is usually done differently for M profile than for A profile.
458      * Instead of putting some devices only into the secure address space,
459      * devices exist in both address spaces but with hard-wired security
460      * permissions that will cause the CPU to fault for non-secure accesses.
461      *
462      * The ARMSSE has an IDAU (Implementation Defined Access Unit),
463      * which specifies hard-wired security permissions for different
464      * areas of the physical address space. For the ARMSSE IDAU, the
465      * top 4 bits of the physical address are the IDAU region ID, and
466      * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
467      * region, otherwise it is an S region.
468      *
469      * The various devices and RAMs are generally all mapped twice,
470      * once into a region that the IDAU defines as secure and once
471      * into a non-secure region. They sit behind either a Memory
472      * Protection Controller (for RAM) or a Peripheral Protection
473      * Controller (for devices), which allow a more fine grained
474      * configuration of whether non-secure accesses are permitted.
475      *
476      * (The other place that guest software can configure security
477      * permissions is in the architected SAU (Security Attribution
478      * Unit), which is entirely inside the CPU. The IDAU can upgrade
479      * the security attributes for a region to more restrictive than
480      * the SAU specifies, but cannot downgrade them.)
481      *
482      * 0x10000000..0x1fffffff  alias of 0x00000000..0x0fffffff
483      * 0x20000000..0x2007ffff  32KB FPGA block RAM
484      * 0x30000000..0x3fffffff  alias of 0x20000000..0x2fffffff
485      * 0x40000000..0x4000ffff  base peripheral region 1
486      * 0x40010000..0x4001ffff  CPU peripherals (none for ARMSSE)
487      * 0x40020000..0x4002ffff  system control element peripherals
488      * 0x40080000..0x400fffff  base peripheral region 2
489      * 0x50000000..0x5fffffff  alias of 0x40000000..0x4fffffff
490      */
491 
492     memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
493 
494     for (i = 0; i < info->num_cpus; i++) {
495         DeviceState *cpudev = DEVICE(&s->armv7m[i]);
496         Object *cpuobj = OBJECT(&s->armv7m[i]);
497         int j;
498         char *gpioname;
499 
500         qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + 32);
501         /*
502          * In real hardware the initial Secure VTOR is set from the INITSVTOR*
503          * registers in the IoT Kit System Control Register block. In QEMU
504          * we set the initial value here, and also the reset value of the
505          * sysctl register, from this object's QOM init-svtor property.
506          * If the guest changes the INITSVTOR* registers at runtime then the
507          * code in iotkit-sysctl.c will update the CPU init-svtor property
508          * (which will then take effect on the next CPU warm-reset).
509          *
510          * Note that typically a board using the SSE-200 will have a system
511          * control processor whose boot firmware initializes the INITSVTOR*
512          * registers before powering up the CPUs. QEMU doesn't emulate
513          * the control processor, so instead we behave in the way that the
514          * firmware does: the initial value should be set by the board code
515          * (using the init-svtor property on the ARMSSE object) to match
516          * whatever its firmware does.
517          */
518         qdev_prop_set_uint32(cpudev, "init-svtor", s->init_svtor);
519         /*
520          * CPUs start powered down if the corresponding bit in the CPUWAIT
521          * register is 1. In real hardware the CPUWAIT register reset value is
522          * a configurable property of the SSE-200 (via the CPUWAIT0_RST and
523          * CPUWAIT1_RST parameters), but since all the boards we care about
524          * start CPU0 and leave CPU1 powered off, we hard-code that in
525          * info->cpuwait_rst for now. We can add QOM properties for this
526          * later if necessary.
527          */
528         if (extract32(info->cpuwait_rst, i, 1)) {
529             object_property_set_bool(cpuobj, true, "start-powered-off", &err);
530             if (err) {
531                 error_propagate(errp, err);
532                 return;
533             }
534         }
535 
536         if (i > 0) {
537             memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
538                                                 &s->container_alias[i - 1], -1);
539         } else {
540             memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
541                                                 &s->container, -1);
542         }
543         object_property_set_link(cpuobj, OBJECT(&s->cpu_container[i]),
544                                  "memory", &err);
545         if (err) {
546             error_propagate(errp, err);
547             return;
548         }
549         object_property_set_link(cpuobj, OBJECT(s), "idau", &err);
550         if (err) {
551             error_propagate(errp, err);
552             return;
553         }
554         object_property_set_bool(cpuobj, true, "realized", &err);
555         if (err) {
556             error_propagate(errp, err);
557             return;
558         }
559         /*
560          * The cluster must be realized after the armv7m container, as
561          * the container's CPU object is only created on realize, and the
562          * CPU must exist and have been parented into the cluster before
563          * the cluster is realized.
564          */
565         object_property_set_bool(OBJECT(&s->cluster[i]),
566                                  true, "realized", &err);
567         if (err) {
568             error_propagate(errp, err);
569             return;
570         }
571 
572         /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
573         s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
574         for (j = 0; j < s->exp_numirq; j++) {
575             s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + 32);
576         }
577         if (i == 0) {
578             gpioname = g_strdup("EXP_IRQ");
579         } else {
580             gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
581         }
582         qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
583                                             s->exp_irqs[i],
584                                             gpioname, s->exp_numirq);
585         g_free(gpioname);
586     }
587 
588     /* Wire up the splitters that connect common IRQs to all CPUs */
589     if (info->num_cpus > 1) {
590         for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
591             if (irq_is_common[i]) {
592                 Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
593                 DeviceState *devs = DEVICE(splitter);
594                 int cpunum;
595 
596                 object_property_set_int(splitter, info->num_cpus,
597                                         "num-lines", &err);
598                 if (err) {
599                     error_propagate(errp, err);
600                     return;
601                 }
602                 object_property_set_bool(splitter, true, "realized", &err);
603                 if (err) {
604                     error_propagate(errp, err);
605                     return;
606                 }
607                 for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
608                     DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
609 
610                     qdev_connect_gpio_out(devs, cpunum,
611                                           qdev_get_gpio_in(cpudev, i));
612                 }
613             }
614         }
615     }
616 
617     /* Set up the big aliases first */
618     make_alias(s, &s->alias1, &s->container, "alias 1",
619                0x10000000, 0x10000000, 0x00000000);
620     make_alias(s, &s->alias2, &s->container,
621                "alias 2", 0x30000000, 0x10000000, 0x20000000);
622     /* The 0x50000000..0x5fffffff region is not a pure alias: it has
623      * a few extra devices that only appear there (generally the
624      * control interfaces for the protection controllers).
625      * We implement this by mapping those devices over the top of this
626      * alias MR at a higher priority. Some of the devices in this range
627      * are per-CPU, so we must put this alias in the per-cpu containers.
628      */
629     for (i = 0; i < info->num_cpus; i++) {
630         make_alias(s, &s->alias3[i], &s->cpu_container[i],
631                    "alias 3", 0x50000000, 0x10000000, 0x40000000);
632     }
633 
634     /* Security controller */
635     object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err);
636     if (err) {
637         error_propagate(errp, err);
638         return;
639     }
640     sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
641     dev_secctl = DEVICE(&s->secctl);
642     sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
643     sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
644 
645     s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
646     qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
647 
648     /* The sec_resp_cfg output from the security controller must be split into
649      * multiple lines, one for each of the PPCs within the ARMSSE and one
650      * that will be an output from the ARMSSE to the system.
651      */
652     object_property_set_int(OBJECT(&s->sec_resp_splitter), 3,
653                             "num-lines", &err);
654     if (err) {
655         error_propagate(errp, err);
656         return;
657     }
658     object_property_set_bool(OBJECT(&s->sec_resp_splitter), true,
659                              "realized", &err);
660     if (err) {
661         error_propagate(errp, err);
662         return;
663     }
664     dev_splitter = DEVICE(&s->sec_resp_splitter);
665     qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
666                                 qdev_get_gpio_in(dev_splitter, 0));
667 
668     /* Each SRAM bank lives behind its own Memory Protection Controller */
669     for (i = 0; i < info->sram_banks; i++) {
670         char *ramname = g_strdup_printf("armsse.sram%d", i);
671         SysBusDevice *sbd_mpc;
672         uint32_t sram_bank_size = 1 << s->sram_addr_width;
673 
674         memory_region_init_ram(&s->sram[i], NULL, ramname,
675                                sram_bank_size, &err);
676         g_free(ramname);
677         if (err) {
678             error_propagate(errp, err);
679             return;
680         }
681         object_property_set_link(OBJECT(&s->mpc[i]), OBJECT(&s->sram[i]),
682                                  "downstream", &err);
683         if (err) {
684             error_propagate(errp, err);
685             return;
686         }
687         object_property_set_bool(OBJECT(&s->mpc[i]), true, "realized", &err);
688         if (err) {
689             error_propagate(errp, err);
690             return;
691         }
692         /* Map the upstream end of the MPC into the right place... */
693         sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
694         memory_region_add_subregion(&s->container,
695                                     0x20000000 + i * sram_bank_size,
696                                     sysbus_mmio_get_region(sbd_mpc, 1));
697         /* ...and its register interface */
698         memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
699                                     sysbus_mmio_get_region(sbd_mpc, 0));
700     }
701 
702     /* We must OR together lines from the MPC splitters to go to the NVIC */
703     object_property_set_int(OBJECT(&s->mpc_irq_orgate),
704                             IOTS_NUM_EXP_MPC + info->sram_banks,
705                             "num-lines", &err);
706     if (err) {
707         error_propagate(errp, err);
708         return;
709     }
710     object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
711                              "realized", &err);
712     if (err) {
713         error_propagate(errp, err);
714         return;
715     }
716     qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
717                           armsse_get_common_irq_in(s, 9));
718 
719     /* Devices behind APB PPC0:
720      *   0x40000000: timer0
721      *   0x40001000: timer1
722      *   0x40002000: dual timer
723      *   0x40003000: MHU0 (SSE-200 only)
724      *   0x40004000: MHU1 (SSE-200 only)
725      * We must configure and realize each downstream device and connect
726      * it to the appropriate PPC port; then we can realize the PPC and
727      * map its upstream ends to the right place in the container.
728      */
729     qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
730     object_property_set_bool(OBJECT(&s->timer0), true, "realized", &err);
731     if (err) {
732         error_propagate(errp, err);
733         return;
734     }
735     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
736                        armsse_get_common_irq_in(s, 3));
737     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
738     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err);
739     if (err) {
740         error_propagate(errp, err);
741         return;
742     }
743 
744     qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
745     object_property_set_bool(OBJECT(&s->timer1), true, "realized", &err);
746     if (err) {
747         error_propagate(errp, err);
748         return;
749     }
750     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
751                        armsse_get_common_irq_in(s, 4));
752     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
753     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err);
754     if (err) {
755         error_propagate(errp, err);
756         return;
757     }
758 
759 
760     qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
761     object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err);
762     if (err) {
763         error_propagate(errp, err);
764         return;
765     }
766     sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
767                        armsse_get_common_irq_in(s, 5));
768     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
769     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
770     if (err) {
771         error_propagate(errp, err);
772         return;
773     }
774 
775     if (info->has_mhus) {
776         /*
777          * An SSE-200 with only one CPU should have only one MHU created,
778          * with the region where the second MHU usually is being RAZ/WI.
779          * We don't implement that SSE-200 config; if we want to support
780          * it then this code needs to be enhanced to handle creating the
781          * RAZ/WI region instead of the second MHU.
782          */
783         assert(info->num_cpus == ARRAY_SIZE(s->mhu));
784 
785         for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
786             char *port;
787             int cpunum;
788             SysBusDevice *mhu_sbd = SYS_BUS_DEVICE(&s->mhu[i]);
789 
790             object_property_set_bool(OBJECT(&s->mhu[i]), true,
791                                      "realized", &err);
792             if (err) {
793                 error_propagate(errp, err);
794                 return;
795             }
796             port = g_strdup_printf("port[%d]", i + 3);
797             mr = sysbus_mmio_get_region(mhu_sbd, 0);
798             object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr),
799                                      port, &err);
800             g_free(port);
801             if (err) {
802                 error_propagate(errp, err);
803                 return;
804             }
805 
806             /*
807              * Each MHU has an irq line for each CPU:
808              *  MHU 0 irq line 0 -> CPU 0 IRQ 6
809              *  MHU 0 irq line 1 -> CPU 1 IRQ 6
810              *  MHU 1 irq line 0 -> CPU 0 IRQ 7
811              *  MHU 1 irq line 1 -> CPU 1 IRQ 7
812              */
813             for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
814                 DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
815 
816                 sysbus_connect_irq(mhu_sbd, cpunum,
817                                    qdev_get_gpio_in(cpudev, 6 + i));
818             }
819         }
820     }
821 
822     object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err);
823     if (err) {
824         error_propagate(errp, err);
825         return;
826     }
827 
828     sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0);
829     dev_apb_ppc0 = DEVICE(&s->apb_ppc0);
830 
831     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
832     memory_region_add_subregion(&s->container, 0x40000000, mr);
833     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1);
834     memory_region_add_subregion(&s->container, 0x40001000, mr);
835     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
836     memory_region_add_subregion(&s->container, 0x40002000, mr);
837     if (info->has_mhus) {
838         mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
839         memory_region_add_subregion(&s->container, 0x40003000, mr);
840         mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
841         memory_region_add_subregion(&s->container, 0x40004000, mr);
842     }
843     for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
844         qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
845                                     qdev_get_gpio_in_named(dev_apb_ppc0,
846                                                            "cfg_nonsec", i));
847         qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
848                                     qdev_get_gpio_in_named(dev_apb_ppc0,
849                                                            "cfg_ap", i));
850     }
851     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
852                                 qdev_get_gpio_in_named(dev_apb_ppc0,
853                                                        "irq_enable", 0));
854     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
855                                 qdev_get_gpio_in_named(dev_apb_ppc0,
856                                                        "irq_clear", 0));
857     qdev_connect_gpio_out(dev_splitter, 0,
858                           qdev_get_gpio_in_named(dev_apb_ppc0,
859                                                  "cfg_sec_resp", 0));
860 
861     /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
862      * ones) are sent individually to the security controller, and also
863      * ORed together to give a single combined PPC interrupt to the NVIC.
864      */
865     object_property_set_int(OBJECT(&s->ppc_irq_orgate),
866                             NUM_PPCS, "num-lines", &err);
867     if (err) {
868         error_propagate(errp, err);
869         return;
870     }
871     object_property_set_bool(OBJECT(&s->ppc_irq_orgate), true,
872                              "realized", &err);
873     if (err) {
874         error_propagate(errp, err);
875         return;
876     }
877     qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
878                           armsse_get_common_irq_in(s, 10));
879 
880     /*
881      * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
882      * private per-CPU region (all these devices are SSE-200 only):
883      *  0x50010000: L1 icache control registers
884      *  0x50011000: CPUSECCTRL (CPU local security control registers)
885      *  0x4001f000 and 0x5001f000: CPU_IDENTITY register block
886      */
887     if (info->has_cachectrl) {
888         for (i = 0; i < info->num_cpus; i++) {
889             char *name = g_strdup_printf("cachectrl%d", i);
890             MemoryRegion *mr;
891 
892             qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
893             g_free(name);
894             qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
895             object_property_set_bool(OBJECT(&s->cachectrl[i]), true,
896                                      "realized", &err);
897             if (err) {
898                 error_propagate(errp, err);
899                 return;
900             }
901 
902             mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
903             memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
904         }
905     }
906     if (info->has_cpusecctrl) {
907         for (i = 0; i < info->num_cpus; i++) {
908             char *name = g_strdup_printf("CPUSECCTRL%d", i);
909             MemoryRegion *mr;
910 
911             qdev_prop_set_string(DEVICE(&s->cpusecctrl[i]), "name", name);
912             g_free(name);
913             qdev_prop_set_uint64(DEVICE(&s->cpusecctrl[i]), "size", 0x1000);
914             object_property_set_bool(OBJECT(&s->cpusecctrl[i]), true,
915                                      "realized", &err);
916             if (err) {
917                 error_propagate(errp, err);
918                 return;
919             }
920 
921             mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpusecctrl[i]), 0);
922             memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
923         }
924     }
925     if (info->has_cpuid) {
926         for (i = 0; i < info->num_cpus; i++) {
927             MemoryRegion *mr;
928 
929             qdev_prop_set_uint32(DEVICE(&s->cpuid[i]), "CPUID", i);
930             object_property_set_bool(OBJECT(&s->cpuid[i]), true,
931                                      "realized", &err);
932             if (err) {
933                 error_propagate(errp, err);
934                 return;
935             }
936 
937             mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpuid[i]), 0);
938             memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
939         }
940     }
941 
942     /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
943     /* Devices behind APB PPC1:
944      *   0x4002f000: S32K timer
945      */
946     qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
947     object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err);
948     if (err) {
949         error_propagate(errp, err);
950         return;
951     }
952     sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
953                        armsse_get_common_irq_in(s, 2));
954     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
955     object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
956     if (err) {
957         error_propagate(errp, err);
958         return;
959     }
960 
961     object_property_set_bool(OBJECT(&s->apb_ppc1), true, "realized", &err);
962     if (err) {
963         error_propagate(errp, err);
964         return;
965     }
966     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0);
967     memory_region_add_subregion(&s->container, 0x4002f000, mr);
968 
969     dev_apb_ppc1 = DEVICE(&s->apb_ppc1);
970     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
971                                 qdev_get_gpio_in_named(dev_apb_ppc1,
972                                                        "cfg_nonsec", 0));
973     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
974                                 qdev_get_gpio_in_named(dev_apb_ppc1,
975                                                        "cfg_ap", 0));
976     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
977                                 qdev_get_gpio_in_named(dev_apb_ppc1,
978                                                        "irq_enable", 0));
979     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
980                                 qdev_get_gpio_in_named(dev_apb_ppc1,
981                                                        "irq_clear", 0));
982     qdev_connect_gpio_out(dev_splitter, 1,
983                           qdev_get_gpio_in_named(dev_apb_ppc1,
984                                                  "cfg_sec_resp", 0));
985 
986     object_property_set_int(OBJECT(&s->sysinfo), info->sys_version,
987                             "SYS_VERSION", &err);
988     if (err) {
989         error_propagate(errp, err);
990         return;
991     }
992     object_property_set_int(OBJECT(&s->sysinfo),
993                             armsse_sys_config_value(s, info),
994                             "SYS_CONFIG", &err);
995     if (err) {
996         error_propagate(errp, err);
997         return;
998     }
999     object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
1000     if (err) {
1001         error_propagate(errp, err);
1002         return;
1003     }
1004     /* System information registers */
1005     sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
1006     /* System control registers */
1007     object_property_set_int(OBJECT(&s->sysctl), info->sys_version,
1008                             "SYS_VERSION", &err);
1009     object_property_set_int(OBJECT(&s->sysctl), info->cpuwait_rst,
1010                             "CPUWAIT_RST", &err);
1011     object_property_set_int(OBJECT(&s->sysctl), s->init_svtor,
1012                             "INITSVTOR0_RST", &err);
1013     object_property_set_int(OBJECT(&s->sysctl), s->init_svtor,
1014                             "INITSVTOR1_RST", &err);
1015     object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
1016     if (err) {
1017         error_propagate(errp, err);
1018         return;
1019     }
1020     sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
1021 
1022     if (info->has_ppus) {
1023         /* CPUnCORE_PPU for each CPU */
1024         for (i = 0; i < info->num_cpus; i++) {
1025             char *name = g_strdup_printf("CPU%dCORE_PPU", i);
1026 
1027             map_ppu(s, CPU0CORE_PPU + i, name, 0x50023000 + i * 0x2000);
1028             /*
1029              * We don't support CPU debug so don't create the
1030              * CPU0DEBUG_PPU at 0x50024000 and 0x50026000.
1031              */
1032             g_free(name);
1033         }
1034         map_ppu(s, DBG_PPU, "DBG_PPU", 0x50029000);
1035 
1036         for (i = 0; i < info->sram_banks; i++) {
1037             char *name = g_strdup_printf("RAM%d_PPU", i);
1038 
1039             map_ppu(s, RAM0_PPU + i, name, 0x5002a000 + i * 0x1000);
1040             g_free(name);
1041         }
1042     }
1043 
1044     /* This OR gate wires together outputs from the secure watchdogs to NMI */
1045     object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
1046     if (err) {
1047         error_propagate(errp, err);
1048         return;
1049     }
1050     object_property_set_bool(OBJECT(&s->nmi_orgate), true, "realized", &err);
1051     if (err) {
1052         error_propagate(errp, err);
1053         return;
1054     }
1055     qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
1056                           qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
1057 
1058     qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
1059     object_property_set_bool(OBJECT(&s->s32kwatchdog), true, "realized", &err);
1060     if (err) {
1061         error_propagate(errp, err);
1062         return;
1063     }
1064     sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0,
1065                        qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
1066     sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
1067 
1068     /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
1069 
1070     qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
1071     object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err);
1072     if (err) {
1073         error_propagate(errp, err);
1074         return;
1075     }
1076     sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
1077                        armsse_get_common_irq_in(s, 1));
1078     sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
1079 
1080     qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
1081     object_property_set_bool(OBJECT(&s->swatchdog), true, "realized", &err);
1082     if (err) {
1083         error_propagate(errp, err);
1084         return;
1085     }
1086     sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0,
1087                        qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1));
1088     sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000);
1089 
1090     for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
1091         Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
1092 
1093         object_property_set_int(splitter, 2, "num-lines", &err);
1094         if (err) {
1095             error_propagate(errp, err);
1096             return;
1097         }
1098         object_property_set_bool(splitter, true, "realized", &err);
1099         if (err) {
1100             error_propagate(errp, err);
1101             return;
1102         }
1103     }
1104 
1105     for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
1106         char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
1107 
1108         armsse_forward_ppc(s, ppcname, i);
1109         g_free(ppcname);
1110     }
1111 
1112     for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
1113         char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
1114 
1115         armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
1116         g_free(ppcname);
1117     }
1118 
1119     for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
1120         /* Wire up IRQ splitter for internal PPCs */
1121         DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
1122         char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
1123                                          i - NUM_EXTERNAL_PPCS);
1124         TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1;
1125 
1126         qdev_connect_gpio_out(devs, 0,
1127                               qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
1128         qdev_connect_gpio_out(devs, 1,
1129                               qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
1130         qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
1131                                     qdev_get_gpio_in(devs, 0));
1132         g_free(gpioname);
1133     }
1134 
1135     /* Wire up the splitters for the MPC IRQs */
1136     for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
1137         SplitIRQ *splitter = &s->mpc_irq_splitter[i];
1138         DeviceState *dev_splitter = DEVICE(splitter);
1139 
1140         object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
1141         if (err) {
1142             error_propagate(errp, err);
1143             return;
1144         }
1145         object_property_set_bool(OBJECT(splitter), true, "realized", &err);
1146         if (err) {
1147             error_propagate(errp, err);
1148             return;
1149         }
1150 
1151         if (i < IOTS_NUM_EXP_MPC) {
1152             /* Splitter input is from GPIO input line */
1153             s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
1154             qdev_connect_gpio_out(dev_splitter, 0,
1155                                   qdev_get_gpio_in_named(dev_secctl,
1156                                                          "mpcexp_status", i));
1157         } else {
1158             /* Splitter input is from our own MPC */
1159             qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
1160                                         "irq", 0,
1161                                         qdev_get_gpio_in(dev_splitter, 0));
1162             qdev_connect_gpio_out(dev_splitter, 0,
1163                                   qdev_get_gpio_in_named(dev_secctl,
1164                                                          "mpc_status", 0));
1165         }
1166 
1167         qdev_connect_gpio_out(dev_splitter, 1,
1168                               qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
1169     }
1170     /* Create GPIO inputs which will pass the line state for our
1171      * mpcexp_irq inputs to the correct splitter devices.
1172      */
1173     qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
1174                             IOTS_NUM_EXP_MPC);
1175 
1176     armsse_forward_sec_resp_cfg(s);
1177 
1178     /* Forward the MSC related signals */
1179     qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
1180     qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
1181     qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
1182     qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
1183                                 armsse_get_common_irq_in(s, 11));
1184 
1185     /*
1186      * Expose our container region to the board model; this corresponds
1187      * to the AHB Slave Expansion ports which allow bus master devices
1188      * (eg DMA controllers) in the board model to make transactions into
1189      * devices in the ARMSSE.
1190      */
1191     sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
1192 
1193     system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
1194 }
1195 
1196 static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
1197                               int *iregion, bool *exempt, bool *ns, bool *nsc)
1198 {
1199     /*
1200      * For ARMSSE systems the IDAU responses are simple logical functions
1201      * of the address bits. The NSC attribute is guest-adjustable via the
1202      * NSCCFG register in the security controller.
1203      */
1204     ARMSSE *s = ARMSSE(ii);
1205     int region = extract32(address, 28, 4);
1206 
1207     *ns = !(region & 1);
1208     *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
1209     /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
1210     *exempt = (address & 0xeff00000) == 0xe0000000;
1211     *iregion = region;
1212 }
1213 
1214 static const VMStateDescription armsse_vmstate = {
1215     .name = "iotkit",
1216     .version_id = 1,
1217     .minimum_version_id = 1,
1218     .fields = (VMStateField[]) {
1219         VMSTATE_UINT32(nsccfg, ARMSSE),
1220         VMSTATE_END_OF_LIST()
1221     }
1222 };
1223 
1224 static Property armsse_properties[] = {
1225     DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
1226                      MemoryRegion *),
1227     DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
1228     DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
1229     DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
1230     DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
1231     DEFINE_PROP_END_OF_LIST()
1232 };
1233 
1234 static void armsse_reset(DeviceState *dev)
1235 {
1236     ARMSSE *s = ARMSSE(dev);
1237 
1238     s->nsccfg = 0;
1239 }
1240 
1241 static void armsse_class_init(ObjectClass *klass, void *data)
1242 {
1243     DeviceClass *dc = DEVICE_CLASS(klass);
1244     IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
1245     ARMSSEClass *asc = ARMSSE_CLASS(klass);
1246 
1247     dc->realize = armsse_realize;
1248     dc->vmsd = &armsse_vmstate;
1249     dc->props = armsse_properties;
1250     dc->reset = armsse_reset;
1251     iic->check = armsse_idau_check;
1252     asc->info = data;
1253 }
1254 
1255 static const TypeInfo armsse_info = {
1256     .name = TYPE_ARMSSE,
1257     .parent = TYPE_SYS_BUS_DEVICE,
1258     .instance_size = sizeof(ARMSSE),
1259     .instance_init = armsse_init,
1260     .abstract = true,
1261     .interfaces = (InterfaceInfo[]) {
1262         { TYPE_IDAU_INTERFACE },
1263         { }
1264     }
1265 };
1266 
1267 static void armsse_register_types(void)
1268 {
1269     int i;
1270 
1271     type_register_static(&armsse_info);
1272 
1273     for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
1274         TypeInfo ti = {
1275             .name = armsse_variants[i].name,
1276             .parent = TYPE_ARMSSE,
1277             .class_init = armsse_class_init,
1278             .class_data = (void *)&armsse_variants[i],
1279         };
1280         type_register(&ti);
1281     }
1282 }
1283 
1284 type_init(armsse_register_types);
1285