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