xref: /qemu/hw/arm/armsse.c (revision 4b635cf7a95e5012113570a87e134962a0271a27)
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     uint32_t addr_width_max;
225 
226     if (!s->board_memory) {
227         error_setg(errp, "memory property was not set");
228         return;
229     }
230 
231     if (!s->mainclk_frq) {
232         error_setg(errp, "MAINCLK property was not set");
233         return;
234     }
235 
236     /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
237     assert(is_power_of_2(info->sram_banks));
238     addr_width_max = 24 - ctz32(info->sram_banks);
239     if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
240         error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
241                    addr_width_max);
242         return;
243     }
244 
245     /* Handling of which devices should be available only to secure
246      * code is usually done differently for M profile than for A profile.
247      * Instead of putting some devices only into the secure address space,
248      * devices exist in both address spaces but with hard-wired security
249      * permissions that will cause the CPU to fault for non-secure accesses.
250      *
251      * The ARMSSE has an IDAU (Implementation Defined Access Unit),
252      * which specifies hard-wired security permissions for different
253      * areas of the physical address space. For the ARMSSE IDAU, the
254      * top 4 bits of the physical address are the IDAU region ID, and
255      * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
256      * region, otherwise it is an S region.
257      *
258      * The various devices and RAMs are generally all mapped twice,
259      * once into a region that the IDAU defines as secure and once
260      * into a non-secure region. They sit behind either a Memory
261      * Protection Controller (for RAM) or a Peripheral Protection
262      * Controller (for devices), which allow a more fine grained
263      * configuration of whether non-secure accesses are permitted.
264      *
265      * (The other place that guest software can configure security
266      * permissions is in the architected SAU (Security Attribution
267      * Unit), which is entirely inside the CPU. The IDAU can upgrade
268      * the security attributes for a region to more restrictive than
269      * the SAU specifies, but cannot downgrade them.)
270      *
271      * 0x10000000..0x1fffffff  alias of 0x00000000..0x0fffffff
272      * 0x20000000..0x2007ffff  32KB FPGA block RAM
273      * 0x30000000..0x3fffffff  alias of 0x20000000..0x2fffffff
274      * 0x40000000..0x4000ffff  base peripheral region 1
275      * 0x40010000..0x4001ffff  CPU peripherals (none for ARMSSE)
276      * 0x40020000..0x4002ffff  system control element peripherals
277      * 0x40080000..0x400fffff  base peripheral region 2
278      * 0x50000000..0x5fffffff  alias of 0x40000000..0x4fffffff
279      */
280 
281     memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
282 
283     qdev_prop_set_uint32(DEVICE(&s->armv7m), "num-irq", s->exp_numirq + 32);
284     /* In real hardware the initial Secure VTOR is set from the INITSVTOR0
285      * register in the IoT Kit System Control Register block, and the
286      * initial value of that is in turn specifiable by the FPGA that
287      * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
288      * and simply set the CPU's init-svtor to the IoT Kit default value.
289      */
290     qdev_prop_set_uint32(DEVICE(&s->armv7m), "init-svtor", 0x10000000);
291     object_property_set_link(OBJECT(&s->armv7m), OBJECT(&s->container),
292                              "memory", &err);
293     if (err) {
294         error_propagate(errp, err);
295         return;
296     }
297     object_property_set_link(OBJECT(&s->armv7m), OBJECT(s), "idau", &err);
298     if (err) {
299         error_propagate(errp, err);
300         return;
301     }
302     object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
303     if (err) {
304         error_propagate(errp, err);
305         return;
306     }
307 
308     /* Connect our EXP_IRQ GPIOs to the NVIC's lines 32 and up. */
309     s->exp_irqs = g_new(qemu_irq, s->exp_numirq);
310     for (i = 0; i < s->exp_numirq; i++) {
311         s->exp_irqs[i] = qdev_get_gpio_in(DEVICE(&s->armv7m), i + 32);
312     }
313     qdev_init_gpio_in_named(dev, armsse_exp_irq, "EXP_IRQ", s->exp_numirq);
314 
315     /* Set up the big aliases first */
316     make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000);
317     make_alias(s, &s->alias2, "alias 2", 0x30000000, 0x10000000, 0x20000000);
318     /* The 0x50000000..0x5fffffff region is not a pure alias: it has
319      * a few extra devices that only appear there (generally the
320      * control interfaces for the protection controllers).
321      * We implement this by mapping those devices over the top of this
322      * alias MR at a higher priority.
323      */
324     make_alias(s, &s->alias3, "alias 3", 0x50000000, 0x10000000, 0x40000000);
325 
326 
327     /* Security controller */
328     object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err);
329     if (err) {
330         error_propagate(errp, err);
331         return;
332     }
333     sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
334     dev_secctl = DEVICE(&s->secctl);
335     sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
336     sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
337 
338     s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
339     qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
340 
341     /* The sec_resp_cfg output from the security controller must be split into
342      * multiple lines, one for each of the PPCs within the ARMSSE and one
343      * that will be an output from the ARMSSE to the system.
344      */
345     object_property_set_int(OBJECT(&s->sec_resp_splitter), 3,
346                             "num-lines", &err);
347     if (err) {
348         error_propagate(errp, err);
349         return;
350     }
351     object_property_set_bool(OBJECT(&s->sec_resp_splitter), true,
352                              "realized", &err);
353     if (err) {
354         error_propagate(errp, err);
355         return;
356     }
357     dev_splitter = DEVICE(&s->sec_resp_splitter);
358     qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
359                                 qdev_get_gpio_in(dev_splitter, 0));
360 
361     /* Each SRAM bank lives behind its own Memory Protection Controller */
362     for (i = 0; i < info->sram_banks; i++) {
363         char *ramname = g_strdup_printf("armsse.sram%d", i);
364         SysBusDevice *sbd_mpc;
365         uint32_t sram_bank_size = 1 << s->sram_addr_width;
366 
367         memory_region_init_ram(&s->sram[i], NULL, ramname,
368                                sram_bank_size, &err);
369         g_free(ramname);
370         if (err) {
371             error_propagate(errp, err);
372             return;
373         }
374         object_property_set_link(OBJECT(&s->mpc[i]), OBJECT(&s->sram[i]),
375                                  "downstream", &err);
376         if (err) {
377             error_propagate(errp, err);
378             return;
379         }
380         object_property_set_bool(OBJECT(&s->mpc[i]), true, "realized", &err);
381         if (err) {
382             error_propagate(errp, err);
383             return;
384         }
385         /* Map the upstream end of the MPC into the right place... */
386         sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
387         memory_region_add_subregion(&s->container,
388                                     0x20000000 + i * sram_bank_size,
389                                     sysbus_mmio_get_region(sbd_mpc, 1));
390         /* ...and its register interface */
391         memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
392                                     sysbus_mmio_get_region(sbd_mpc, 0));
393     }
394 
395     /* We must OR together lines from the MPC splitters to go to the NVIC */
396     object_property_set_int(OBJECT(&s->mpc_irq_orgate),
397                             IOTS_NUM_EXP_MPC + info->sram_banks,
398                             "num-lines", &err);
399     if (err) {
400         error_propagate(errp, err);
401         return;
402     }
403     object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
404                              "realized", &err);
405     if (err) {
406         error_propagate(errp, err);
407         return;
408     }
409     qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
410                           qdev_get_gpio_in(DEVICE(&s->armv7m), 9));
411 
412     /* Devices behind APB PPC0:
413      *   0x40000000: timer0
414      *   0x40001000: timer1
415      *   0x40002000: dual timer
416      * We must configure and realize each downstream device and connect
417      * it to the appropriate PPC port; then we can realize the PPC and
418      * map its upstream ends to the right place in the container.
419      */
420     qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
421     object_property_set_bool(OBJECT(&s->timer0), true, "realized", &err);
422     if (err) {
423         error_propagate(errp, err);
424         return;
425     }
426     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
427                        qdev_get_gpio_in(DEVICE(&s->armv7m), 3));
428     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
429     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err);
430     if (err) {
431         error_propagate(errp, err);
432         return;
433     }
434 
435     qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
436     object_property_set_bool(OBJECT(&s->timer1), true, "realized", &err);
437     if (err) {
438         error_propagate(errp, err);
439         return;
440     }
441     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
442                        qdev_get_gpio_in(DEVICE(&s->armv7m), 4));
443     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
444     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err);
445     if (err) {
446         error_propagate(errp, err);
447         return;
448     }
449 
450 
451     qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
452     object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err);
453     if (err) {
454         error_propagate(errp, err);
455         return;
456     }
457     sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
458                        qdev_get_gpio_in(DEVICE(&s->armv7m), 5));
459     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
460     object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
461     if (err) {
462         error_propagate(errp, err);
463         return;
464     }
465 
466     object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err);
467     if (err) {
468         error_propagate(errp, err);
469         return;
470     }
471 
472     sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0);
473     dev_apb_ppc0 = DEVICE(&s->apb_ppc0);
474 
475     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
476     memory_region_add_subregion(&s->container, 0x40000000, mr);
477     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1);
478     memory_region_add_subregion(&s->container, 0x40001000, mr);
479     mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
480     memory_region_add_subregion(&s->container, 0x40002000, mr);
481     for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
482         qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
483                                     qdev_get_gpio_in_named(dev_apb_ppc0,
484                                                            "cfg_nonsec", i));
485         qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
486                                     qdev_get_gpio_in_named(dev_apb_ppc0,
487                                                            "cfg_ap", i));
488     }
489     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
490                                 qdev_get_gpio_in_named(dev_apb_ppc0,
491                                                        "irq_enable", 0));
492     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
493                                 qdev_get_gpio_in_named(dev_apb_ppc0,
494                                                        "irq_clear", 0));
495     qdev_connect_gpio_out(dev_splitter, 0,
496                           qdev_get_gpio_in_named(dev_apb_ppc0,
497                                                  "cfg_sec_resp", 0));
498 
499     /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
500      * ones) are sent individually to the security controller, and also
501      * ORed together to give a single combined PPC interrupt to the NVIC.
502      */
503     object_property_set_int(OBJECT(&s->ppc_irq_orgate),
504                             NUM_PPCS, "num-lines", &err);
505     if (err) {
506         error_propagate(errp, err);
507         return;
508     }
509     object_property_set_bool(OBJECT(&s->ppc_irq_orgate), true,
510                              "realized", &err);
511     if (err) {
512         error_propagate(errp, err);
513         return;
514     }
515     qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
516                           qdev_get_gpio_in(DEVICE(&s->armv7m), 10));
517 
518     /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
519 
520     /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
521     /* Devices behind APB PPC1:
522      *   0x4002f000: S32K timer
523      */
524     qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
525     object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err);
526     if (err) {
527         error_propagate(errp, err);
528         return;
529     }
530     sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
531                        qdev_get_gpio_in(DEVICE(&s->armv7m), 2));
532     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
533     object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
534     if (err) {
535         error_propagate(errp, err);
536         return;
537     }
538 
539     object_property_set_bool(OBJECT(&s->apb_ppc1), true, "realized", &err);
540     if (err) {
541         error_propagate(errp, err);
542         return;
543     }
544     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0);
545     memory_region_add_subregion(&s->container, 0x4002f000, mr);
546 
547     dev_apb_ppc1 = DEVICE(&s->apb_ppc1);
548     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
549                                 qdev_get_gpio_in_named(dev_apb_ppc1,
550                                                        "cfg_nonsec", 0));
551     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
552                                 qdev_get_gpio_in_named(dev_apb_ppc1,
553                                                        "cfg_ap", 0));
554     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
555                                 qdev_get_gpio_in_named(dev_apb_ppc1,
556                                                        "irq_enable", 0));
557     qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
558                                 qdev_get_gpio_in_named(dev_apb_ppc1,
559                                                        "irq_clear", 0));
560     qdev_connect_gpio_out(dev_splitter, 1,
561                           qdev_get_gpio_in_named(dev_apb_ppc1,
562                                                  "cfg_sec_resp", 0));
563 
564     object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
565     if (err) {
566         error_propagate(errp, err);
567         return;
568     }
569     /* System information registers */
570     sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
571     /* System control registers */
572     object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
573     if (err) {
574         error_propagate(errp, err);
575         return;
576     }
577     sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
578 
579     /* This OR gate wires together outputs from the secure watchdogs to NMI */
580     object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
581     if (err) {
582         error_propagate(errp, err);
583         return;
584     }
585     object_property_set_bool(OBJECT(&s->nmi_orgate), true, "realized", &err);
586     if (err) {
587         error_propagate(errp, err);
588         return;
589     }
590     qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
591                           qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
592 
593     qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
594     object_property_set_bool(OBJECT(&s->s32kwatchdog), true, "realized", &err);
595     if (err) {
596         error_propagate(errp, err);
597         return;
598     }
599     sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0,
600                        qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
601     sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
602 
603     /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
604 
605     qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
606     object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err);
607     if (err) {
608         error_propagate(errp, err);
609         return;
610     }
611     sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
612                        qdev_get_gpio_in(DEVICE(&s->armv7m), 1));
613     sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
614 
615     qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
616     object_property_set_bool(OBJECT(&s->swatchdog), true, "realized", &err);
617     if (err) {
618         error_propagate(errp, err);
619         return;
620     }
621     sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0,
622                        qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1));
623     sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000);
624 
625     for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
626         Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
627 
628         object_property_set_int(splitter, 2, "num-lines", &err);
629         if (err) {
630             error_propagate(errp, err);
631             return;
632         }
633         object_property_set_bool(splitter, true, "realized", &err);
634         if (err) {
635             error_propagate(errp, err);
636             return;
637         }
638     }
639 
640     for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
641         char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
642 
643         armsse_forward_ppc(s, ppcname, i);
644         g_free(ppcname);
645     }
646 
647     for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
648         char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
649 
650         armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
651         g_free(ppcname);
652     }
653 
654     for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
655         /* Wire up IRQ splitter for internal PPCs */
656         DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
657         char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
658                                          i - NUM_EXTERNAL_PPCS);
659         TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1;
660 
661         qdev_connect_gpio_out(devs, 0,
662                               qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
663         qdev_connect_gpio_out(devs, 1,
664                               qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
665         qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
666                                     qdev_get_gpio_in(devs, 0));
667         g_free(gpioname);
668     }
669 
670     /* Wire up the splitters for the MPC IRQs */
671     for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
672         SplitIRQ *splitter = &s->mpc_irq_splitter[i];
673         DeviceState *dev_splitter = DEVICE(splitter);
674 
675         object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
676         if (err) {
677             error_propagate(errp, err);
678             return;
679         }
680         object_property_set_bool(OBJECT(splitter), true, "realized", &err);
681         if (err) {
682             error_propagate(errp, err);
683             return;
684         }
685 
686         if (i < IOTS_NUM_EXP_MPC) {
687             /* Splitter input is from GPIO input line */
688             s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
689             qdev_connect_gpio_out(dev_splitter, 0,
690                                   qdev_get_gpio_in_named(dev_secctl,
691                                                          "mpcexp_status", i));
692         } else {
693             /* Splitter input is from our own MPC */
694             qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
695                                         "irq", 0,
696                                         qdev_get_gpio_in(dev_splitter, 0));
697             qdev_connect_gpio_out(dev_splitter, 0,
698                                   qdev_get_gpio_in_named(dev_secctl,
699                                                          "mpc_status", 0));
700         }
701 
702         qdev_connect_gpio_out(dev_splitter, 1,
703                               qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
704     }
705     /* Create GPIO inputs which will pass the line state for our
706      * mpcexp_irq inputs to the correct splitter devices.
707      */
708     qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
709                             IOTS_NUM_EXP_MPC);
710 
711     armsse_forward_sec_resp_cfg(s);
712 
713     /* Forward the MSC related signals */
714     qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
715     qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
716     qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
717     qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
718                                 qdev_get_gpio_in(DEVICE(&s->armv7m), 11));
719 
720     /*
721      * Expose our container region to the board model; this corresponds
722      * to the AHB Slave Expansion ports which allow bus master devices
723      * (eg DMA controllers) in the board model to make transactions into
724      * devices in the ARMSSE.
725      */
726     sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
727 
728     system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
729 }
730 
731 static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
732                               int *iregion, bool *exempt, bool *ns, bool *nsc)
733 {
734     /*
735      * For ARMSSE systems the IDAU responses are simple logical functions
736      * of the address bits. The NSC attribute is guest-adjustable via the
737      * NSCCFG register in the security controller.
738      */
739     ARMSSE *s = ARMSSE(ii);
740     int region = extract32(address, 28, 4);
741 
742     *ns = !(region & 1);
743     *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
744     /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
745     *exempt = (address & 0xeff00000) == 0xe0000000;
746     *iregion = region;
747 }
748 
749 static const VMStateDescription armsse_vmstate = {
750     .name = "iotkit",
751     .version_id = 1,
752     .minimum_version_id = 1,
753     .fields = (VMStateField[]) {
754         VMSTATE_UINT32(nsccfg, ARMSSE),
755         VMSTATE_END_OF_LIST()
756     }
757 };
758 
759 static Property armsse_properties[] = {
760     DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
761                      MemoryRegion *),
762     DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
763     DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
764     DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
765     DEFINE_PROP_END_OF_LIST()
766 };
767 
768 static void armsse_reset(DeviceState *dev)
769 {
770     ARMSSE *s = ARMSSE(dev);
771 
772     s->nsccfg = 0;
773 }
774 
775 static void armsse_class_init(ObjectClass *klass, void *data)
776 {
777     DeviceClass *dc = DEVICE_CLASS(klass);
778     IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
779     ARMSSEClass *asc = ARMSSE_CLASS(klass);
780 
781     dc->realize = armsse_realize;
782     dc->vmsd = &armsse_vmstate;
783     dc->props = armsse_properties;
784     dc->reset = armsse_reset;
785     iic->check = armsse_idau_check;
786     asc->info = data;
787 }
788 
789 static const TypeInfo armsse_info = {
790     .name = TYPE_ARMSSE,
791     .parent = TYPE_SYS_BUS_DEVICE,
792     .instance_size = sizeof(ARMSSE),
793     .instance_init = armsse_init,
794     .abstract = true,
795     .interfaces = (InterfaceInfo[]) {
796         { TYPE_IDAU_INTERFACE },
797         { }
798     }
799 };
800 
801 static void armsse_register_types(void)
802 {
803     int i;
804 
805     type_register_static(&armsse_info);
806 
807     for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
808         TypeInfo ti = {
809             .name = armsse_variants[i].name,
810             .parent = TYPE_ARMSSE,
811             .class_init = armsse_class_init,
812             .class_data = (void *)&armsse_variants[i],
813         };
814         type_register(&ti);
815     }
816 }
817 
818 type_init(armsse_register_types);
819