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