hw/arm/armsse: Make SRAM bank size configurable
[qemu.git] / hw / arm / armsse.c
bloba2ae5d3c4b99bbb94bb5727c83c07eb143c17e4e
1 /*
2 * Arm SSE (Subsystems for Embedded): IoTKit
4 * Copyright (c) 2018 Linaro Limited
5 * Written by Peter Maydell
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.
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"
21 struct ARMSSEInfo {
22 const char *name;
23 int sram_banks;
26 static const ARMSSEInfo armsse_variants[] = {
28 .name = TYPE_IOTKIT,
29 .sram_banks = 1,
33 /* Clock frequency in HZ of the 32KHz "slow clock" */
34 #define S32KCLK (32 * 1000)
36 /* Create an alias region of @size bytes starting at @base
37 * which mirrors the memory starting at @orig.
39 static void make_alias(ARMSSE *s, MemoryRegion *mr, const char *name,
40 hwaddr base, hwaddr size, hwaddr orig)
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);
47 static void irq_status_forwarder(void *opaque, int n, int level)
49 qemu_irq destirq = opaque;
51 qemu_set_irq(destirq, level);
54 static void nsccfg_handler(void *opaque, int n, int level)
56 ARMSSE *s = ARMSSE(opaque);
58 s->nsccfg = level;
61 static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
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.
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;
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);
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.
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);
106 static void armsse_forward_sec_resp_cfg(ARMSSE *s)
108 /* Forward the 3rd output from the splitter device as a
109 * named GPIO output of the armsse object.
111 DeviceState *dev = DEVICE(s);
112 DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
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);
120 static void armsse_init(Object *obj)
122 ARMSSE *s = ARMSSE(obj);
123 ARMSSEClass *asc = ARMSSE_GET_CLASS(obj);
124 const ARMSSEInfo *info = asc->info;
125 int i;
127 assert(info->sram_banks <= MAX_SRAM_BANKS);
129 memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
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"));
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);
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);
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];
156 object_initialize_child(obj, name, splitter, sizeof(*splitter),
157 TYPE_SPLIT_IRQ, &error_abort, NULL);
158 g_free(name);
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];
191 object_initialize_child(obj, name, splitter, sizeof(*splitter),
192 TYPE_SPLIT_IRQ, &error_abort, NULL);
193 g_free(name);
197 static void armsse_exp_irq(void *opaque, int n, int level)
199 ARMSSE *s = ARMSSE(opaque);
201 qemu_set_irq(s->exp_irqs[n], level);
204 static void armsse_mpcexp_status(void *opaque, int n, int level)
206 ARMSSE *s = ARMSSE(opaque);
207 qemu_set_irq(s->mpcexp_status_in[n], level);
210 static void armsse_realize(DeviceState *dev, Error **errp)
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;
226 if (!s->board_memory) {
227 error_setg(errp, "memory property was not set");
228 return;
231 if (!s->mainclk_frq) {
232 error_setg(errp, "MAINCLK property was not set");
233 return;
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;
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.
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.
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.
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.)
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
281 memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
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.
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;
297 object_property_set_link(OBJECT(&s->armv7m), OBJECT(s), "idau", &err);
298 if (err) {
299 error_propagate(errp, err);
300 return;
302 object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
303 if (err) {
304 error_propagate(errp, err);
305 return;
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);
313 qdev_init_gpio_in_named(dev, armsse_exp_irq, "EXP_IRQ", s->exp_numirq);
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.
324 make_alias(s, &s->alias3, "alias 3", 0x50000000, 0x10000000, 0x40000000);
327 /* Security controller */
328 object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err);
329 if (err) {
330 error_propagate(errp, err);
331 return;
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);
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);
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.
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;
351 object_property_set_bool(OBJECT(&s->sec_resp_splitter), true,
352 "realized", &err);
353 if (err) {
354 error_propagate(errp, err);
355 return;
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));
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;
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;
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;
380 object_property_set_bool(OBJECT(&s->mpc[i]), true, "realized", &err);
381 if (err) {
382 error_propagate(errp, err);
383 return;
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));
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;
403 object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
404 "realized", &err);
405 if (err) {
406 error_propagate(errp, err);
407 return;
409 qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
410 qdev_get_gpio_in(DEVICE(&s->armv7m), 9));
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.
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;
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;
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;
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;
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;
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;
466 object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err);
467 if (err) {
468 error_propagate(errp, err);
469 return;
472 sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0);
473 dev_apb_ppc0 = DEVICE(&s->apb_ppc0);
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));
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));
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.
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;
509 object_property_set_bool(OBJECT(&s->ppc_irq_orgate), true,
510 "realized", &err);
511 if (err) {
512 error_propagate(errp, err);
513 return;
515 qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
516 qdev_get_gpio_in(DEVICE(&s->armv7m), 10));
518 /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
520 /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
521 /* Devices behind APB PPC1:
522 * 0x4002f000: S32K timer
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;
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;
539 object_property_set_bool(OBJECT(&s->apb_ppc1), true, "realized", &err);
540 if (err) {
541 error_propagate(errp, err);
542 return;
544 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0);
545 memory_region_add_subregion(&s->container, 0x4002f000, mr);
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));
564 object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
565 if (err) {
566 error_propagate(errp, err);
567 return;
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;
577 sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
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;
585 object_property_set_bool(OBJECT(&s->nmi_orgate), true, "realized", &err);
586 if (err) {
587 error_propagate(errp, err);
588 return;
590 qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
591 qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
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;
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);
603 /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
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;
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);
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;
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);
625 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
626 Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
628 object_property_set_int(splitter, 2, "num-lines", &err);
629 if (err) {
630 error_propagate(errp, err);
631 return;
633 object_property_set_bool(splitter, true, "realized", &err);
634 if (err) {
635 error_propagate(errp, err);
636 return;
640 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
641 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
643 armsse_forward_ppc(s, ppcname, i);
644 g_free(ppcname);
647 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
648 char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
650 armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
651 g_free(ppcname);
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;
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);
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);
675 object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
676 if (err) {
677 error_propagate(errp, err);
678 return;
680 object_property_set_bool(OBJECT(splitter), true, "realized", &err);
681 if (err) {
682 error_propagate(errp, err);
683 return;
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));
702 qdev_connect_gpio_out(dev_splitter, 1,
703 qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
705 /* Create GPIO inputs which will pass the line state for our
706 * mpcexp_irq inputs to the correct splitter devices.
708 qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
709 IOTS_NUM_EXP_MPC);
711 armsse_forward_sec_resp_cfg(s);
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));
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.
726 sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
728 system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
731 static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
732 int *iregion, bool *exempt, bool *ns, bool *nsc)
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.
739 ARMSSE *s = ARMSSE(ii);
740 int region = extract32(address, 28, 4);
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;
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()
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()
768 static void armsse_reset(DeviceState *dev)
770 ARMSSE *s = ARMSSE(dev);
772 s->nsccfg = 0;
775 static void armsse_class_init(ObjectClass *klass, void *data)
777 DeviceClass *dc = DEVICE_CLASS(klass);
778 IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
779 ARMSSEClass *asc = ARMSSE_CLASS(klass);
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;
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 },
801 static void armsse_register_types(void)
803 int i;
805 type_register_static(&armsse_info);
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],
814 type_register(&ti);
818 type_init(armsse_register_types);