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