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