hw/arm/armsse: Indirect irq_is_common[] through ARMSSEInfo
[qemu/ar7.git] / hw / arm / armsse.c
blobb316fe69571fcebd0e0dbf562d103600b3b7054c
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/module.h"
15 #include "qemu/bitops.h"
16 #include "qapi/error.h"
17 #include "trace.h"
18 #include "hw/sysbus.h"
19 #include "migration/vmstate.h"
20 #include "hw/registerfields.h"
21 #include "hw/arm/armsse.h"
22 #include "hw/arm/armsse-version.h"
23 #include "hw/arm/boot.h"
24 #include "hw/irq.h"
25 #include "hw/qdev-clock.h"
28 * The SSE-300 puts some devices in different places to the
29 * SSE-200 (and original IoTKit). We use an array of these structs
30 * to define how each variant lays out these devices. (Parts of the
31 * SoC that are the same for all variants aren't handled via these
32 * data structures.)
35 #define NO_IRQ -1
36 #define NO_PPC -1
38 * Special values for ARMSSEDeviceInfo::irq to indicate that this
39 * device uses one of the inputs to the OR gate that feeds into the
40 * CPU NMI input.
42 #define NMI_0 10000
43 #define NMI_1 10001
45 typedef struct ARMSSEDeviceInfo {
46 const char *name; /* name to use for the QOM object; NULL terminates list */
47 const char *type; /* QOM type name */
48 unsigned int index; /* Which of the N devices of this type is this ? */
49 hwaddr addr;
50 hwaddr size; /* only needed for TYPE_UNIMPLEMENTED_DEVICE */
51 int ppc; /* Index of APB PPC this device is wired up to, or NO_PPC */
52 int ppc_port; /* Port number of this device on the PPC */
53 int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1, or NMI_0 or NMI_1 */
54 bool slowclk; /* true if device uses the slow 32KHz clock */
55 } ARMSSEDeviceInfo;
57 struct ARMSSEInfo {
58 const char *name;
59 uint32_t sse_version;
60 int sram_banks;
61 int num_cpus;
62 uint32_t sys_version;
63 uint32_t iidr;
64 uint32_t cpuwait_rst;
65 bool has_mhus;
66 bool has_cachectrl;
67 bool has_cpusecctrl;
68 bool has_cpuid;
69 Property *props;
70 const ARMSSEDeviceInfo *devinfo;
71 const bool *irq_is_common;
74 static Property iotkit_properties[] = {
75 DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
76 MemoryRegion *),
77 DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
78 DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
79 DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
80 DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
81 DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
82 DEFINE_PROP_END_OF_LIST()
85 static Property armsse_properties[] = {
86 DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
87 MemoryRegion *),
88 DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
89 DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
90 DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
91 DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
92 DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
93 DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
94 DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
95 DEFINE_PROP_END_OF_LIST()
98 static const ARMSSEDeviceInfo iotkit_devices[] = {
100 .name = "timer0",
101 .type = TYPE_CMSDK_APB_TIMER,
102 .index = 0,
103 .addr = 0x40000000,
104 .ppc = 0,
105 .ppc_port = 0,
106 .irq = 3,
109 .name = "timer1",
110 .type = TYPE_CMSDK_APB_TIMER,
111 .index = 1,
112 .addr = 0x40001000,
113 .ppc = 0,
114 .ppc_port = 1,
115 .irq = 4,
118 .name = "s32ktimer",
119 .type = TYPE_CMSDK_APB_TIMER,
120 .index = 2,
121 .addr = 0x4002f000,
122 .ppc = 1,
123 .ppc_port = 0,
124 .irq = 2,
125 .slowclk = true,
128 .name = "dualtimer",
129 .type = TYPE_CMSDK_APB_DUALTIMER,
130 .index = 0,
131 .addr = 0x40002000,
132 .ppc = 0,
133 .ppc_port = 2,
134 .irq = 5,
137 .name = "s32kwatchdog",
138 .type = TYPE_CMSDK_APB_WATCHDOG,
139 .index = 0,
140 .addr = 0x5002e000,
141 .ppc = NO_PPC,
142 .irq = NMI_0,
143 .slowclk = true,
146 .name = "nswatchdog",
147 .type = TYPE_CMSDK_APB_WATCHDOG,
148 .index = 1,
149 .addr = 0x40081000,
150 .ppc = NO_PPC,
151 .irq = 1,
154 .name = "swatchdog",
155 .type = TYPE_CMSDK_APB_WATCHDOG,
156 .index = 2,
157 .addr = 0x50081000,
158 .ppc = NO_PPC,
159 .irq = NMI_1,
162 .name = "armsse-sysinfo",
163 .type = TYPE_IOTKIT_SYSINFO,
164 .index = 0,
165 .addr = 0x40020000,
166 .ppc = NO_PPC,
167 .irq = NO_IRQ,
170 .name = "armsse-sysctl",
171 .type = TYPE_IOTKIT_SYSCTL,
172 .index = 0,
173 .addr = 0x50021000,
174 .ppc = NO_PPC,
175 .irq = NO_IRQ,
178 .name = NULL,
182 static const ARMSSEDeviceInfo sse200_devices[] = {
184 .name = "timer0",
185 .type = TYPE_CMSDK_APB_TIMER,
186 .index = 0,
187 .addr = 0x40000000,
188 .ppc = 0,
189 .ppc_port = 0,
190 .irq = 3,
193 .name = "timer1",
194 .type = TYPE_CMSDK_APB_TIMER,
195 .index = 1,
196 .addr = 0x40001000,
197 .ppc = 0,
198 .ppc_port = 1,
199 .irq = 4,
202 .name = "s32ktimer",
203 .type = TYPE_CMSDK_APB_TIMER,
204 .index = 2,
205 .addr = 0x4002f000,
206 .ppc = 1,
207 .ppc_port = 0,
208 .irq = 2,
209 .slowclk = true,
212 .name = "dualtimer",
213 .type = TYPE_CMSDK_APB_DUALTIMER,
214 .index = 0,
215 .addr = 0x40002000,
216 .ppc = 0,
217 .ppc_port = 2,
218 .irq = 5,
221 .name = "s32kwatchdog",
222 .type = TYPE_CMSDK_APB_WATCHDOG,
223 .index = 0,
224 .addr = 0x5002e000,
225 .ppc = NO_PPC,
226 .irq = NMI_0,
227 .slowclk = true,
230 .name = "nswatchdog",
231 .type = TYPE_CMSDK_APB_WATCHDOG,
232 .index = 1,
233 .addr = 0x40081000,
234 .ppc = NO_PPC,
235 .irq = 1,
238 .name = "swatchdog",
239 .type = TYPE_CMSDK_APB_WATCHDOG,
240 .index = 2,
241 .addr = 0x50081000,
242 .ppc = NO_PPC,
243 .irq = NMI_1,
246 .name = "armsse-sysinfo",
247 .type = TYPE_IOTKIT_SYSINFO,
248 .index = 0,
249 .addr = 0x40020000,
250 .ppc = NO_PPC,
251 .irq = NO_IRQ,
254 .name = "armsse-sysctl",
255 .type = TYPE_IOTKIT_SYSCTL,
256 .index = 0,
257 .addr = 0x50021000,
258 .ppc = NO_PPC,
259 .irq = NO_IRQ,
262 .name = "CPU0CORE_PPU",
263 .type = TYPE_UNIMPLEMENTED_DEVICE,
264 .index = 0,
265 .addr = 0x50023000,
266 .size = 0x1000,
267 .ppc = NO_PPC,
268 .irq = NO_IRQ,
271 .name = "CPU1CORE_PPU",
272 .type = TYPE_UNIMPLEMENTED_DEVICE,
273 .index = 1,
274 .addr = 0x50025000,
275 .size = 0x1000,
276 .ppc = NO_PPC,
277 .irq = NO_IRQ,
280 .name = "DBG_PPU",
281 .type = TYPE_UNIMPLEMENTED_DEVICE,
282 .index = 2,
283 .addr = 0x50029000,
284 .size = 0x1000,
285 .ppc = NO_PPC,
286 .irq = NO_IRQ,
289 .name = "RAM0_PPU",
290 .type = TYPE_UNIMPLEMENTED_DEVICE,
291 .index = 3,
292 .addr = 0x5002a000,
293 .size = 0x1000,
294 .ppc = NO_PPC,
295 .irq = NO_IRQ,
298 .name = "RAM1_PPU",
299 .type = TYPE_UNIMPLEMENTED_DEVICE,
300 .index = 4,
301 .addr = 0x5002b000,
302 .size = 0x1000,
303 .ppc = NO_PPC,
304 .irq = NO_IRQ,
307 .name = "RAM2_PPU",
308 .type = TYPE_UNIMPLEMENTED_DEVICE,
309 .index = 5,
310 .addr = 0x5002c000,
311 .size = 0x1000,
312 .ppc = NO_PPC,
313 .irq = NO_IRQ,
316 .name = "RAM3_PPU",
317 .type = TYPE_UNIMPLEMENTED_DEVICE,
318 .index = 6,
319 .addr = 0x5002d000,
320 .size = 0x1000,
321 .ppc = NO_PPC,
322 .irq = NO_IRQ,
325 .name = "SYS_PPU",
326 .type = TYPE_UNIMPLEMENTED_DEVICE,
327 .index = 7,
328 .addr = 0x50022000,
329 .size = 0x1000,
330 .ppc = NO_PPC,
331 .irq = NO_IRQ,
334 .name = NULL,
338 /* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
339 static const bool sse200_irq_is_common[32] = {
340 [0 ... 5] = true,
341 /* 6, 7: per-CPU MHU interrupts */
342 [8 ... 12] = true,
343 /* 13: per-CPU icache interrupt */
344 /* 14: reserved */
345 [15 ... 20] = true,
346 /* 21: reserved */
347 [22 ... 26] = true,
348 /* 27: reserved */
349 /* 28, 29: per-CPU CTI interrupts */
350 /* 30, 31: reserved */
353 static const ARMSSEInfo armsse_variants[] = {
355 .name = TYPE_IOTKIT,
356 .sse_version = ARMSSE_IOTKIT,
357 .sram_banks = 1,
358 .num_cpus = 1,
359 .sys_version = 0x41743,
360 .iidr = 0,
361 .cpuwait_rst = 0,
362 .has_mhus = false,
363 .has_cachectrl = false,
364 .has_cpusecctrl = false,
365 .has_cpuid = false,
366 .props = iotkit_properties,
367 .devinfo = iotkit_devices,
368 .irq_is_common = sse200_irq_is_common,
371 .name = TYPE_SSE200,
372 .sse_version = ARMSSE_SSE200,
373 .sram_banks = 4,
374 .num_cpus = 2,
375 .sys_version = 0x22041743,
376 .iidr = 0,
377 .cpuwait_rst = 2,
378 .has_mhus = true,
379 .has_cachectrl = true,
380 .has_cpusecctrl = true,
381 .has_cpuid = true,
382 .props = armsse_properties,
383 .devinfo = sse200_devices,
384 .irq_is_common = sse200_irq_is_common,
388 static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
390 /* Return the SYS_CONFIG value for this SSE */
391 uint32_t sys_config;
393 switch (info->sse_version) {
394 case ARMSSE_IOTKIT:
395 sys_config = 0;
396 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
397 sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
398 break;
399 case ARMSSE_SSE200:
400 sys_config = 0;
401 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
402 sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
403 sys_config = deposit32(sys_config, 24, 4, 2);
404 if (info->num_cpus > 1) {
405 sys_config = deposit32(sys_config, 10, 1, 1);
406 sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
407 sys_config = deposit32(sys_config, 28, 4, 2);
409 break;
410 case ARMSSE_SSE300:
411 sys_config = 0;
412 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
413 sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
414 sys_config = deposit32(sys_config, 16, 3, 3); /* CPU0 = Cortex-M55 */
415 break;
416 default:
417 g_assert_not_reached();
419 return sys_config;
422 /* Clock frequency in HZ of the 32KHz "slow clock" */
423 #define S32KCLK (32 * 1000)
426 * Create an alias region in @container of @size bytes starting at @base
427 * which mirrors the memory starting at @orig.
429 static void make_alias(ARMSSE *s, MemoryRegion *mr, MemoryRegion *container,
430 const char *name, hwaddr base, hwaddr size, hwaddr orig)
432 memory_region_init_alias(mr, NULL, name, container, orig, size);
433 /* The alias is even lower priority than unimplemented_device regions */
434 memory_region_add_subregion_overlap(container, base, mr, -1500);
437 static void irq_status_forwarder(void *opaque, int n, int level)
439 qemu_irq destirq = opaque;
441 qemu_set_irq(destirq, level);
444 static void nsccfg_handler(void *opaque, int n, int level)
446 ARMSSE *s = ARM_SSE(opaque);
448 s->nsccfg = level;
451 static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
453 /* Each of the 4 AHB and 4 APB PPCs that might be present in a
454 * system using the ARMSSE has a collection of control lines which
455 * are provided by the security controller and which we want to
456 * expose as control lines on the ARMSSE device itself, so the
457 * code using the ARMSSE can wire them up to the PPCs.
459 SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
460 DeviceState *armssedev = DEVICE(s);
461 DeviceState *dev_secctl = DEVICE(&s->secctl);
462 DeviceState *dev_splitter = DEVICE(splitter);
463 char *name;
465 name = g_strdup_printf("%s_nonsec", ppcname);
466 qdev_pass_gpios(dev_secctl, armssedev, name);
467 g_free(name);
468 name = g_strdup_printf("%s_ap", ppcname);
469 qdev_pass_gpios(dev_secctl, armssedev, name);
470 g_free(name);
471 name = g_strdup_printf("%s_irq_enable", ppcname);
472 qdev_pass_gpios(dev_secctl, armssedev, name);
473 g_free(name);
474 name = g_strdup_printf("%s_irq_clear", ppcname);
475 qdev_pass_gpios(dev_secctl, armssedev, name);
476 g_free(name);
478 /* irq_status is a little more tricky, because we need to
479 * split it so we can send it both to the security controller
480 * and to our OR gate for the NVIC interrupt line.
481 * Connect up the splitter's outputs, and create a GPIO input
482 * which will pass the line state to the input splitter.
484 name = g_strdup_printf("%s_irq_status", ppcname);
485 qdev_connect_gpio_out(dev_splitter, 0,
486 qdev_get_gpio_in_named(dev_secctl,
487 name, 0));
488 qdev_connect_gpio_out(dev_splitter, 1,
489 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
490 s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
491 qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
492 s->irq_status_in[ppcnum], name, 1);
493 g_free(name);
496 static void armsse_forward_sec_resp_cfg(ARMSSE *s)
498 /* Forward the 3rd output from the splitter device as a
499 * named GPIO output of the armsse object.
501 DeviceState *dev = DEVICE(s);
502 DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
504 qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
505 s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
506 s->sec_resp_cfg, 1);
507 qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
510 static void armsse_mainclk_update(void *opaque, ClockEvent event)
512 ARMSSE *s = ARM_SSE(opaque);
515 * Set system_clock_scale from our Clock input; this is what
516 * controls the tick rate of the CPU SysTick timer.
518 system_clock_scale = clock_ticks_to_ns(s->mainclk, 1);
521 static void armsse_init(Object *obj)
523 ARMSSE *s = ARM_SSE(obj);
524 ARMSSEClass *asc = ARM_SSE_GET_CLASS(obj);
525 const ARMSSEInfo *info = asc->info;
526 const ARMSSEDeviceInfo *devinfo;
527 int i;
529 assert(info->sram_banks <= MAX_SRAM_BANKS);
530 assert(info->num_cpus <= SSE_MAX_CPUS);
532 s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
533 armsse_mainclk_update, s, ClockUpdate);
534 s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL, 0);
536 memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
538 for (i = 0; i < info->num_cpus; i++) {
540 * We put each CPU in its own cluster as they are logically
541 * distinct and may be configured differently.
543 char *name;
545 name = g_strdup_printf("cluster%d", i);
546 object_initialize_child(obj, name, &s->cluster[i], TYPE_CPU_CLUSTER);
547 qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
548 g_free(name);
550 name = g_strdup_printf("armv7m%d", i);
551 object_initialize_child(OBJECT(&s->cluster[i]), name, &s->armv7m[i],
552 TYPE_ARMV7M);
553 qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
554 ARM_CPU_TYPE_NAME("cortex-m33"));
555 g_free(name);
556 name = g_strdup_printf("arm-sse-cpu-container%d", i);
557 memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
558 g_free(name);
559 if (i > 0) {
560 name = g_strdup_printf("arm-sse-container-alias%d", i);
561 memory_region_init_alias(&s->container_alias[i - 1], obj,
562 name, &s->container, 0, UINT64_MAX);
563 g_free(name);
567 for (devinfo = info->devinfo; devinfo->name; devinfo++) {
568 assert(devinfo->ppc == NO_PPC || devinfo->ppc < ARRAY_SIZE(s->apb_ppc));
569 if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
570 assert(devinfo->index < ARRAY_SIZE(s->timer));
571 object_initialize_child(obj, devinfo->name,
572 &s->timer[devinfo->index],
573 TYPE_CMSDK_APB_TIMER);
574 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
575 assert(devinfo->index == 0);
576 object_initialize_child(obj, devinfo->name, &s->dualtimer,
577 TYPE_CMSDK_APB_DUALTIMER);
578 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
579 assert(devinfo->index < ARRAY_SIZE(s->cmsdk_watchdog));
580 object_initialize_child(obj, devinfo->name,
581 &s->cmsdk_watchdog[devinfo->index],
582 TYPE_CMSDK_APB_WATCHDOG);
583 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
584 assert(devinfo->index == 0);
585 object_initialize_child(obj, devinfo->name, &s->sysinfo,
586 TYPE_IOTKIT_SYSINFO);
587 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
588 assert(devinfo->index == 0);
589 object_initialize_child(obj, devinfo->name, &s->sysctl,
590 TYPE_IOTKIT_SYSCTL);
591 } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
592 assert(devinfo->index < ARRAY_SIZE(s->unimp));
593 object_initialize_child(obj, devinfo->name,
594 &s->unimp[devinfo->index],
595 TYPE_UNIMPLEMENTED_DEVICE);
596 } else {
597 g_assert_not_reached();
601 object_initialize_child(obj, "secctl", &s->secctl, TYPE_IOTKIT_SECCTL);
603 for (i = 0; i < ARRAY_SIZE(s->apb_ppc); i++) {
604 g_autofree char *name = g_strdup_printf("apb-ppc%d", i);
605 object_initialize_child(obj, name, &s->apb_ppc[i], TYPE_TZ_PPC);
608 for (i = 0; i < info->sram_banks; i++) {
609 char *name = g_strdup_printf("mpc%d", i);
610 object_initialize_child(obj, name, &s->mpc[i], TYPE_TZ_MPC);
611 g_free(name);
613 object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
614 TYPE_OR_IRQ);
616 for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
617 char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
618 SplitIRQ *splitter = &s->mpc_irq_splitter[i];
620 object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
621 g_free(name);
624 if (info->has_mhus) {
625 object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
626 object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
628 if (info->has_cachectrl) {
629 for (i = 0; i < info->num_cpus; i++) {
630 char *name = g_strdup_printf("cachectrl%d", i);
632 object_initialize_child(obj, name, &s->cachectrl[i],
633 TYPE_UNIMPLEMENTED_DEVICE);
634 g_free(name);
637 if (info->has_cpusecctrl) {
638 for (i = 0; i < info->num_cpus; i++) {
639 char *name = g_strdup_printf("cpusecctrl%d", i);
641 object_initialize_child(obj, name, &s->cpusecctrl[i],
642 TYPE_UNIMPLEMENTED_DEVICE);
643 g_free(name);
646 if (info->has_cpuid) {
647 for (i = 0; i < info->num_cpus; i++) {
648 char *name = g_strdup_printf("cpuid%d", i);
650 object_initialize_child(obj, name, &s->cpuid[i],
651 TYPE_ARMSSE_CPUID);
652 g_free(name);
655 object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, TYPE_OR_IRQ);
656 object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
657 TYPE_OR_IRQ);
658 object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
659 TYPE_SPLIT_IRQ);
660 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
661 char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
662 SplitIRQ *splitter = &s->ppc_irq_splitter[i];
664 object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
665 g_free(name);
667 if (info->num_cpus > 1) {
668 for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
669 if (info->irq_is_common[i]) {
670 char *name = g_strdup_printf("cpu-irq-splitter%d", i);
671 SplitIRQ *splitter = &s->cpu_irq_splitter[i];
673 object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
674 g_free(name);
680 static void armsse_exp_irq(void *opaque, int n, int level)
682 qemu_irq *irqarray = opaque;
684 qemu_set_irq(irqarray[n], level);
687 static void armsse_mpcexp_status(void *opaque, int n, int level)
689 ARMSSE *s = ARM_SSE(opaque);
690 qemu_set_irq(s->mpcexp_status_in[n], level);
693 static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
696 * Return a qemu_irq which can be used to signal IRQ n to
697 * all CPUs in the SSE.
699 ARMSSEClass *asc = ARM_SSE_GET_CLASS(s);
700 const ARMSSEInfo *info = asc->info;
702 assert(info->irq_is_common[irqno]);
704 if (info->num_cpus == 1) {
705 /* Only one CPU -- just connect directly to it */
706 return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
707 } else {
708 /* Connect to the splitter which feeds all CPUs */
709 return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
713 static void armsse_realize(DeviceState *dev, Error **errp)
715 ARMSSE *s = ARM_SSE(dev);
716 ARMSSEClass *asc = ARM_SSE_GET_CLASS(dev);
717 const ARMSSEInfo *info = asc->info;
718 const ARMSSEDeviceInfo *devinfo;
719 int i;
720 MemoryRegion *mr;
721 Error *err = NULL;
722 SysBusDevice *sbd_apb_ppc0;
723 SysBusDevice *sbd_secctl;
724 DeviceState *dev_apb_ppc0;
725 DeviceState *dev_apb_ppc1;
726 DeviceState *dev_secctl;
727 DeviceState *dev_splitter;
728 uint32_t addr_width_max;
730 if (!s->board_memory) {
731 error_setg(errp, "memory property was not set");
732 return;
735 if (!clock_has_source(s->mainclk)) {
736 error_setg(errp, "MAINCLK clock was not connected");
738 if (!clock_has_source(s->s32kclk)) {
739 error_setg(errp, "S32KCLK clock was not connected");
742 assert(info->num_cpus <= SSE_MAX_CPUS);
744 /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
745 assert(is_power_of_2(info->sram_banks));
746 addr_width_max = 24 - ctz32(info->sram_banks);
747 if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
748 error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
749 addr_width_max);
750 return;
753 /* Handling of which devices should be available only to secure
754 * code is usually done differently for M profile than for A profile.
755 * Instead of putting some devices only into the secure address space,
756 * devices exist in both address spaces but with hard-wired security
757 * permissions that will cause the CPU to fault for non-secure accesses.
759 * The ARMSSE has an IDAU (Implementation Defined Access Unit),
760 * which specifies hard-wired security permissions for different
761 * areas of the physical address space. For the ARMSSE IDAU, the
762 * top 4 bits of the physical address are the IDAU region ID, and
763 * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
764 * region, otherwise it is an S region.
766 * The various devices and RAMs are generally all mapped twice,
767 * once into a region that the IDAU defines as secure and once
768 * into a non-secure region. They sit behind either a Memory
769 * Protection Controller (for RAM) or a Peripheral Protection
770 * Controller (for devices), which allow a more fine grained
771 * configuration of whether non-secure accesses are permitted.
773 * (The other place that guest software can configure security
774 * permissions is in the architected SAU (Security Attribution
775 * Unit), which is entirely inside the CPU. The IDAU can upgrade
776 * the security attributes for a region to more restrictive than
777 * the SAU specifies, but cannot downgrade them.)
779 * 0x10000000..0x1fffffff alias of 0x00000000..0x0fffffff
780 * 0x20000000..0x2007ffff 32KB FPGA block RAM
781 * 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff
782 * 0x40000000..0x4000ffff base peripheral region 1
783 * 0x40010000..0x4001ffff CPU peripherals (none for ARMSSE)
784 * 0x40020000..0x4002ffff system control element peripherals
785 * 0x40080000..0x400fffff base peripheral region 2
786 * 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
789 memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
791 for (i = 0; i < info->num_cpus; i++) {
792 DeviceState *cpudev = DEVICE(&s->armv7m[i]);
793 Object *cpuobj = OBJECT(&s->armv7m[i]);
794 int j;
795 char *gpioname;
797 qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + NUM_SSE_IRQS);
799 * In real hardware the initial Secure VTOR is set from the INITSVTOR*
800 * registers in the IoT Kit System Control Register block. In QEMU
801 * we set the initial value here, and also the reset value of the
802 * sysctl register, from this object's QOM init-svtor property.
803 * If the guest changes the INITSVTOR* registers at runtime then the
804 * code in iotkit-sysctl.c will update the CPU init-svtor property
805 * (which will then take effect on the next CPU warm-reset).
807 * Note that typically a board using the SSE-200 will have a system
808 * control processor whose boot firmware initializes the INITSVTOR*
809 * registers before powering up the CPUs. QEMU doesn't emulate
810 * the control processor, so instead we behave in the way that the
811 * firmware does: the initial value should be set by the board code
812 * (using the init-svtor property on the ARMSSE object) to match
813 * whatever its firmware does.
815 qdev_prop_set_uint32(cpudev, "init-svtor", s->init_svtor);
817 * CPUs start powered down if the corresponding bit in the CPUWAIT
818 * register is 1. In real hardware the CPUWAIT register reset value is
819 * a configurable property of the SSE-200 (via the CPUWAIT0_RST and
820 * CPUWAIT1_RST parameters), but since all the boards we care about
821 * start CPU0 and leave CPU1 powered off, we hard-code that in
822 * info->cpuwait_rst for now. We can add QOM properties for this
823 * later if necessary.
825 if (extract32(info->cpuwait_rst, i, 1)) {
826 if (!object_property_set_bool(cpuobj, "start-powered-off", true,
827 errp)) {
828 return;
831 if (!s->cpu_fpu[i]) {
832 if (!object_property_set_bool(cpuobj, "vfp", false, errp)) {
833 return;
836 if (!s->cpu_dsp[i]) {
837 if (!object_property_set_bool(cpuobj, "dsp", false, errp)) {
838 return;
842 if (i > 0) {
843 memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
844 &s->container_alias[i - 1], -1);
845 } else {
846 memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
847 &s->container, -1);
849 object_property_set_link(cpuobj, "memory",
850 OBJECT(&s->cpu_container[i]), &error_abort);
851 object_property_set_link(cpuobj, "idau", OBJECT(s), &error_abort);
852 if (!sysbus_realize(SYS_BUS_DEVICE(cpuobj), errp)) {
853 return;
856 * The cluster must be realized after the armv7m container, as
857 * the container's CPU object is only created on realize, and the
858 * CPU must exist and have been parented into the cluster before
859 * the cluster is realized.
861 if (!qdev_realize(DEVICE(&s->cluster[i]), NULL, errp)) {
862 return;
865 /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
866 s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
867 for (j = 0; j < s->exp_numirq; j++) {
868 s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + NUM_SSE_IRQS);
870 if (i == 0) {
871 gpioname = g_strdup("EXP_IRQ");
872 } else {
873 gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
875 qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
876 s->exp_irqs[i],
877 gpioname, s->exp_numirq);
878 g_free(gpioname);
881 /* Wire up the splitters that connect common IRQs to all CPUs */
882 if (info->num_cpus > 1) {
883 for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
884 if (info->irq_is_common[i]) {
885 Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
886 DeviceState *devs = DEVICE(splitter);
887 int cpunum;
889 if (!object_property_set_int(splitter, "num-lines",
890 info->num_cpus, errp)) {
891 return;
893 if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
894 return;
896 for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
897 DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
899 qdev_connect_gpio_out(devs, cpunum,
900 qdev_get_gpio_in(cpudev, i));
906 /* Set up the big aliases first */
907 make_alias(s, &s->alias1, &s->container, "alias 1",
908 0x10000000, 0x10000000, 0x00000000);
909 make_alias(s, &s->alias2, &s->container,
910 "alias 2", 0x30000000, 0x10000000, 0x20000000);
911 /* The 0x50000000..0x5fffffff region is not a pure alias: it has
912 * a few extra devices that only appear there (generally the
913 * control interfaces for the protection controllers).
914 * We implement this by mapping those devices over the top of this
915 * alias MR at a higher priority. Some of the devices in this range
916 * are per-CPU, so we must put this alias in the per-cpu containers.
918 for (i = 0; i < info->num_cpus; i++) {
919 make_alias(s, &s->alias3[i], &s->cpu_container[i],
920 "alias 3", 0x50000000, 0x10000000, 0x40000000);
923 /* Security controller */
924 object_property_set_int(OBJECT(&s->secctl), "sse-version",
925 info->sse_version, &error_abort);
926 if (!sysbus_realize(SYS_BUS_DEVICE(&s->secctl), errp)) {
927 return;
929 sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
930 dev_secctl = DEVICE(&s->secctl);
931 sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
932 sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
934 s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
935 qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
937 /* The sec_resp_cfg output from the security controller must be split into
938 * multiple lines, one for each of the PPCs within the ARMSSE and one
939 * that will be an output from the ARMSSE to the system.
941 if (!object_property_set_int(OBJECT(&s->sec_resp_splitter),
942 "num-lines", 3, errp)) {
943 return;
945 if (!qdev_realize(DEVICE(&s->sec_resp_splitter), NULL, errp)) {
946 return;
948 dev_splitter = DEVICE(&s->sec_resp_splitter);
949 qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
950 qdev_get_gpio_in(dev_splitter, 0));
952 /* Each SRAM bank lives behind its own Memory Protection Controller */
953 for (i = 0; i < info->sram_banks; i++) {
954 char *ramname = g_strdup_printf("armsse.sram%d", i);
955 SysBusDevice *sbd_mpc;
956 uint32_t sram_bank_size = 1 << s->sram_addr_width;
958 memory_region_init_ram(&s->sram[i], NULL, ramname,
959 sram_bank_size, &err);
960 g_free(ramname);
961 if (err) {
962 error_propagate(errp, err);
963 return;
965 object_property_set_link(OBJECT(&s->mpc[i]), "downstream",
966 OBJECT(&s->sram[i]), &error_abort);
967 if (!sysbus_realize(SYS_BUS_DEVICE(&s->mpc[i]), errp)) {
968 return;
970 /* Map the upstream end of the MPC into the right place... */
971 sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
972 memory_region_add_subregion(&s->container,
973 0x20000000 + i * sram_bank_size,
974 sysbus_mmio_get_region(sbd_mpc, 1));
975 /* ...and its register interface */
976 memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
977 sysbus_mmio_get_region(sbd_mpc, 0));
980 /* We must OR together lines from the MPC splitters to go to the NVIC */
981 if (!object_property_set_int(OBJECT(&s->mpc_irq_orgate), "num-lines",
982 IOTS_NUM_EXP_MPC + info->sram_banks,
983 errp)) {
984 return;
986 if (!qdev_realize(DEVICE(&s->mpc_irq_orgate), NULL, errp)) {
987 return;
989 qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
990 armsse_get_common_irq_in(s, 9));
992 /* This OR gate wires together outputs from the secure watchdogs to NMI */
993 if (!object_property_set_int(OBJECT(&s->nmi_orgate), "num-lines", 2,
994 errp)) {
995 return;
997 if (!qdev_realize(DEVICE(&s->nmi_orgate), NULL, errp)) {
998 return;
1000 qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
1001 qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
1003 /* Devices behind APB PPC0:
1004 * 0x40000000: timer0
1005 * 0x40001000: timer1
1006 * 0x40002000: dual timer
1007 * 0x40003000: MHU0 (SSE-200 only)
1008 * 0x40004000: MHU1 (SSE-200 only)
1009 * We must configure and realize each downstream device and connect
1010 * it to the appropriate PPC port; then we can realize the PPC and
1011 * map its upstream ends to the right place in the container.
1013 for (devinfo = info->devinfo; devinfo->name; devinfo++) {
1014 SysBusDevice *sbd;
1015 qemu_irq irq;
1017 if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
1018 sbd = SYS_BUS_DEVICE(&s->timer[devinfo->index]);
1020 qdev_connect_clock_in(DEVICE(sbd), "pclk",
1021 devinfo->slowclk ? s->s32kclk : s->mainclk);
1022 if (!sysbus_realize(sbd, errp)) {
1023 return;
1025 mr = sysbus_mmio_get_region(sbd, 0);
1026 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
1027 sbd = SYS_BUS_DEVICE(&s->dualtimer);
1029 qdev_connect_clock_in(DEVICE(sbd), "TIMCLK", s->mainclk);
1030 if (!sysbus_realize(sbd, errp)) {
1031 return;
1033 mr = sysbus_mmio_get_region(sbd, 0);
1034 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
1035 sbd = SYS_BUS_DEVICE(&s->cmsdk_watchdog[devinfo->index]);
1037 qdev_connect_clock_in(DEVICE(sbd), "WDOGCLK",
1038 devinfo->slowclk ? s->s32kclk : s->mainclk);
1039 if (!sysbus_realize(sbd, errp)) {
1040 return;
1042 mr = sysbus_mmio_get_region(sbd, 0);
1043 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
1044 sbd = SYS_BUS_DEVICE(&s->sysinfo);
1046 object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
1047 info->sys_version, &error_abort);
1048 object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
1049 armsse_sys_config_value(s, info),
1050 &error_abort);
1051 object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
1052 info->sse_version, &error_abort);
1053 object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
1054 info->iidr, &error_abort);
1055 if (!sysbus_realize(sbd, errp)) {
1056 return;
1058 mr = sysbus_mmio_get_region(sbd, 0);
1059 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
1060 /* System control registers */
1061 sbd = SYS_BUS_DEVICE(&s->sysctl);
1063 object_property_set_int(OBJECT(&s->sysctl), "sse-version",
1064 info->sse_version, &error_abort);
1065 object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
1066 info->cpuwait_rst, &error_abort);
1067 object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
1068 s->init_svtor, &error_abort);
1069 object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR1_RST",
1070 s->init_svtor, &error_abort);
1071 if (!sysbus_realize(sbd, errp)) {
1072 return;
1074 mr = sysbus_mmio_get_region(sbd, 0);
1075 } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
1076 sbd = SYS_BUS_DEVICE(&s->unimp[devinfo->index]);
1078 qdev_prop_set_string(DEVICE(sbd), "name", devinfo->name);
1079 qdev_prop_set_uint64(DEVICE(sbd), "size", devinfo->size);
1080 if (!sysbus_realize(sbd, errp)) {
1081 return;
1083 mr = sysbus_mmio_get_region(sbd, 0);
1084 } else {
1085 g_assert_not_reached();
1088 switch (devinfo->irq) {
1089 case NO_IRQ:
1090 irq = NULL;
1091 break;
1092 case 0 ... NUM_SSE_IRQS - 1:
1093 irq = armsse_get_common_irq_in(s, devinfo->irq);
1094 break;
1095 case NMI_0:
1096 case NMI_1:
1097 irq = qdev_get_gpio_in(DEVICE(&s->nmi_orgate),
1098 devinfo->irq - NMI_0);
1099 break;
1100 default:
1101 g_assert_not_reached();
1104 if (irq) {
1105 sysbus_connect_irq(sbd, 0, irq);
1109 * Devices connected to a PPC are connected to the port here;
1110 * we will map the upstream end of that port to the right address
1111 * in the container later after the PPC has been realized.
1112 * Devices not connected to a PPC can be mapped immediately.
1114 if (devinfo->ppc != NO_PPC) {
1115 TZPPC *ppc = &s->apb_ppc[devinfo->ppc];
1116 g_autofree char *portname = g_strdup_printf("port[%d]",
1117 devinfo->ppc_port);
1118 object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
1119 &error_abort);
1120 } else {
1121 memory_region_add_subregion(&s->container, devinfo->addr, mr);
1125 if (info->has_mhus) {
1127 * An SSE-200 with only one CPU should have only one MHU created,
1128 * with the region where the second MHU usually is being RAZ/WI.
1129 * We don't implement that SSE-200 config; if we want to support
1130 * it then this code needs to be enhanced to handle creating the
1131 * RAZ/WI region instead of the second MHU.
1133 assert(info->num_cpus == ARRAY_SIZE(s->mhu));
1135 for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
1136 char *port;
1137 int cpunum;
1138 SysBusDevice *mhu_sbd = SYS_BUS_DEVICE(&s->mhu[i]);
1140 if (!sysbus_realize(SYS_BUS_DEVICE(&s->mhu[i]), errp)) {
1141 return;
1143 port = g_strdup_printf("port[%d]", i + 3);
1144 mr = sysbus_mmio_get_region(mhu_sbd, 0);
1145 object_property_set_link(OBJECT(&s->apb_ppc[0]), port, OBJECT(mr),
1146 &error_abort);
1147 g_free(port);
1150 * Each MHU has an irq line for each CPU:
1151 * MHU 0 irq line 0 -> CPU 0 IRQ 6
1152 * MHU 0 irq line 1 -> CPU 1 IRQ 6
1153 * MHU 1 irq line 0 -> CPU 0 IRQ 7
1154 * MHU 1 irq line 1 -> CPU 1 IRQ 7
1156 for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
1157 DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
1159 sysbus_connect_irq(mhu_sbd, cpunum,
1160 qdev_get_gpio_in(cpudev, 6 + i));
1165 if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[0]), errp)) {
1166 return;
1169 sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc[0]);
1170 dev_apb_ppc0 = DEVICE(&s->apb_ppc[0]);
1172 if (info->has_mhus) {
1173 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
1174 memory_region_add_subregion(&s->container, 0x40003000, mr);
1175 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
1176 memory_region_add_subregion(&s->container, 0x40004000, mr);
1178 for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
1179 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
1180 qdev_get_gpio_in_named(dev_apb_ppc0,
1181 "cfg_nonsec", i));
1182 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
1183 qdev_get_gpio_in_named(dev_apb_ppc0,
1184 "cfg_ap", i));
1186 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
1187 qdev_get_gpio_in_named(dev_apb_ppc0,
1188 "irq_enable", 0));
1189 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
1190 qdev_get_gpio_in_named(dev_apb_ppc0,
1191 "irq_clear", 0));
1192 qdev_connect_gpio_out(dev_splitter, 0,
1193 qdev_get_gpio_in_named(dev_apb_ppc0,
1194 "cfg_sec_resp", 0));
1196 /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
1197 * ones) are sent individually to the security controller, and also
1198 * ORed together to give a single combined PPC interrupt to the NVIC.
1200 if (!object_property_set_int(OBJECT(&s->ppc_irq_orgate),
1201 "num-lines", NUM_PPCS, errp)) {
1202 return;
1204 if (!qdev_realize(DEVICE(&s->ppc_irq_orgate), NULL, errp)) {
1205 return;
1207 qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
1208 armsse_get_common_irq_in(s, 10));
1211 * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
1212 * private per-CPU region (all these devices are SSE-200 only):
1213 * 0x50010000: L1 icache control registers
1214 * 0x50011000: CPUSECCTRL (CPU local security control registers)
1215 * 0x4001f000 and 0x5001f000: CPU_IDENTITY register block
1217 if (info->has_cachectrl) {
1218 for (i = 0; i < info->num_cpus; i++) {
1219 char *name = g_strdup_printf("cachectrl%d", i);
1220 MemoryRegion *mr;
1222 qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
1223 g_free(name);
1224 qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
1225 if (!sysbus_realize(SYS_BUS_DEVICE(&s->cachectrl[i]), errp)) {
1226 return;
1229 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
1230 memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
1233 if (info->has_cpusecctrl) {
1234 for (i = 0; i < info->num_cpus; i++) {
1235 char *name = g_strdup_printf("CPUSECCTRL%d", i);
1236 MemoryRegion *mr;
1238 qdev_prop_set_string(DEVICE(&s->cpusecctrl[i]), "name", name);
1239 g_free(name);
1240 qdev_prop_set_uint64(DEVICE(&s->cpusecctrl[i]), "size", 0x1000);
1241 if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpusecctrl[i]), errp)) {
1242 return;
1245 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpusecctrl[i]), 0);
1246 memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
1249 if (info->has_cpuid) {
1250 for (i = 0; i < info->num_cpus; i++) {
1251 MemoryRegion *mr;
1253 qdev_prop_set_uint32(DEVICE(&s->cpuid[i]), "CPUID", i);
1254 if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpuid[i]), errp)) {
1255 return;
1258 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpuid[i]), 0);
1259 memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
1263 if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[1]), errp)) {
1264 return;
1267 dev_apb_ppc1 = DEVICE(&s->apb_ppc[1]);
1268 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
1269 qdev_get_gpio_in_named(dev_apb_ppc1,
1270 "cfg_nonsec", 0));
1271 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
1272 qdev_get_gpio_in_named(dev_apb_ppc1,
1273 "cfg_ap", 0));
1274 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
1275 qdev_get_gpio_in_named(dev_apb_ppc1,
1276 "irq_enable", 0));
1277 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
1278 qdev_get_gpio_in_named(dev_apb_ppc1,
1279 "irq_clear", 0));
1280 qdev_connect_gpio_out(dev_splitter, 1,
1281 qdev_get_gpio_in_named(dev_apb_ppc1,
1282 "cfg_sec_resp", 0));
1285 * Now both PPCs are realized we can map the upstream ends of
1286 * ports which correspond to entries in the devinfo array.
1287 * The ports which are connected to non-devinfo devices have
1288 * already been mapped.
1290 for (devinfo = info->devinfo; devinfo->name; devinfo++) {
1291 SysBusDevice *ppc_sbd;
1293 if (devinfo->ppc == NO_PPC) {
1294 continue;
1296 ppc_sbd = SYS_BUS_DEVICE(&s->apb_ppc[devinfo->ppc]);
1297 mr = sysbus_mmio_get_region(ppc_sbd, devinfo->ppc_port);
1298 memory_region_add_subregion(&s->container, devinfo->addr, mr);
1301 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
1302 Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
1304 if (!object_property_set_int(splitter, "num-lines", 2, errp)) {
1305 return;
1307 if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
1308 return;
1312 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
1313 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
1315 armsse_forward_ppc(s, ppcname, i);
1316 g_free(ppcname);
1319 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
1320 char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
1322 armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
1323 g_free(ppcname);
1326 for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
1327 /* Wire up IRQ splitter for internal PPCs */
1328 DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
1329 char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
1330 i - NUM_EXTERNAL_PPCS);
1331 TZPPC *ppc = &s->apb_ppc[i - NUM_EXTERNAL_PPCS];
1333 qdev_connect_gpio_out(devs, 0,
1334 qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
1335 qdev_connect_gpio_out(devs, 1,
1336 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
1337 qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
1338 qdev_get_gpio_in(devs, 0));
1339 g_free(gpioname);
1342 /* Wire up the splitters for the MPC IRQs */
1343 for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
1344 SplitIRQ *splitter = &s->mpc_irq_splitter[i];
1345 DeviceState *dev_splitter = DEVICE(splitter);
1347 if (!object_property_set_int(OBJECT(splitter), "num-lines", 2,
1348 errp)) {
1349 return;
1351 if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
1352 return;
1355 if (i < IOTS_NUM_EXP_MPC) {
1356 /* Splitter input is from GPIO input line */
1357 s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
1358 qdev_connect_gpio_out(dev_splitter, 0,
1359 qdev_get_gpio_in_named(dev_secctl,
1360 "mpcexp_status", i));
1361 } else {
1362 /* Splitter input is from our own MPC */
1363 qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
1364 "irq", 0,
1365 qdev_get_gpio_in(dev_splitter, 0));
1366 qdev_connect_gpio_out(dev_splitter, 0,
1367 qdev_get_gpio_in_named(dev_secctl,
1368 "mpc_status",
1369 i - IOTS_NUM_EXP_MPC));
1372 qdev_connect_gpio_out(dev_splitter, 1,
1373 qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
1375 /* Create GPIO inputs which will pass the line state for our
1376 * mpcexp_irq inputs to the correct splitter devices.
1378 qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
1379 IOTS_NUM_EXP_MPC);
1381 armsse_forward_sec_resp_cfg(s);
1383 /* Forward the MSC related signals */
1384 qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
1385 qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
1386 qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
1387 qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
1388 armsse_get_common_irq_in(s, 11));
1391 * Expose our container region to the board model; this corresponds
1392 * to the AHB Slave Expansion ports which allow bus master devices
1393 * (eg DMA controllers) in the board model to make transactions into
1394 * devices in the ARMSSE.
1396 sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
1398 /* Set initial system_clock_scale from MAINCLK */
1399 armsse_mainclk_update(s, ClockUpdate);
1402 static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
1403 int *iregion, bool *exempt, bool *ns, bool *nsc)
1406 * For ARMSSE systems the IDAU responses are simple logical functions
1407 * of the address bits. The NSC attribute is guest-adjustable via the
1408 * NSCCFG register in the security controller.
1410 ARMSSE *s = ARM_SSE(ii);
1411 int region = extract32(address, 28, 4);
1413 *ns = !(region & 1);
1414 *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
1415 /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
1416 *exempt = (address & 0xeff00000) == 0xe0000000;
1417 *iregion = region;
1420 static const VMStateDescription armsse_vmstate = {
1421 .name = "iotkit",
1422 .version_id = 2,
1423 .minimum_version_id = 2,
1424 .fields = (VMStateField[]) {
1425 VMSTATE_CLOCK(mainclk, ARMSSE),
1426 VMSTATE_CLOCK(s32kclk, ARMSSE),
1427 VMSTATE_UINT32(nsccfg, ARMSSE),
1428 VMSTATE_END_OF_LIST()
1432 static void armsse_reset(DeviceState *dev)
1434 ARMSSE *s = ARM_SSE(dev);
1436 s->nsccfg = 0;
1439 static void armsse_class_init(ObjectClass *klass, void *data)
1441 DeviceClass *dc = DEVICE_CLASS(klass);
1442 IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
1443 ARMSSEClass *asc = ARM_SSE_CLASS(klass);
1444 const ARMSSEInfo *info = data;
1446 dc->realize = armsse_realize;
1447 dc->vmsd = &armsse_vmstate;
1448 device_class_set_props(dc, info->props);
1449 dc->reset = armsse_reset;
1450 iic->check = armsse_idau_check;
1451 asc->info = info;
1454 static const TypeInfo armsse_info = {
1455 .name = TYPE_ARM_SSE,
1456 .parent = TYPE_SYS_BUS_DEVICE,
1457 .instance_size = sizeof(ARMSSE),
1458 .class_size = sizeof(ARMSSEClass),
1459 .instance_init = armsse_init,
1460 .abstract = true,
1461 .interfaces = (InterfaceInfo[]) {
1462 { TYPE_IDAU_INTERFACE },
1467 static void armsse_register_types(void)
1469 int i;
1471 type_register_static(&armsse_info);
1473 for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
1474 TypeInfo ti = {
1475 .name = armsse_variants[i].name,
1476 .parent = TYPE_ARM_SSE,
1477 .class_init = armsse_class_init,
1478 .class_data = (void *)&armsse_variants[i],
1480 type_register(&ti);
1484 type_init(armsse_register_types);