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