hw/arm/armsse: Add support for TYPE_SSE_TIMER in ARMSSEDeviceInfo
[qemu/ar7.git] / hw / arm / armsse.c
blobec9c30e099633a1b9620ab37b53ac6b24377cb98
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 bool has_sse_counter;
70 Property *props;
71 const ARMSSEDeviceInfo *devinfo;
72 const bool *irq_is_common;
75 static Property iotkit_properties[] = {
76 DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
77 MemoryRegion *),
78 DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
79 DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
80 DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
81 DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
82 DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
83 DEFINE_PROP_END_OF_LIST()
86 static Property armsse_properties[] = {
87 DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
88 MemoryRegion *),
89 DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
90 DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
91 DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
92 DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
93 DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
94 DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
95 DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
96 DEFINE_PROP_END_OF_LIST()
99 static const ARMSSEDeviceInfo iotkit_devices[] = {
101 .name = "timer0",
102 .type = TYPE_CMSDK_APB_TIMER,
103 .index = 0,
104 .addr = 0x40000000,
105 .ppc = 0,
106 .ppc_port = 0,
107 .irq = 3,
110 .name = "timer1",
111 .type = TYPE_CMSDK_APB_TIMER,
112 .index = 1,
113 .addr = 0x40001000,
114 .ppc = 0,
115 .ppc_port = 1,
116 .irq = 4,
119 .name = "s32ktimer",
120 .type = TYPE_CMSDK_APB_TIMER,
121 .index = 2,
122 .addr = 0x4002f000,
123 .ppc = 1,
124 .ppc_port = 0,
125 .irq = 2,
126 .slowclk = true,
129 .name = "dualtimer",
130 .type = TYPE_CMSDK_APB_DUALTIMER,
131 .index = 0,
132 .addr = 0x40002000,
133 .ppc = 0,
134 .ppc_port = 2,
135 .irq = 5,
138 .name = "s32kwatchdog",
139 .type = TYPE_CMSDK_APB_WATCHDOG,
140 .index = 0,
141 .addr = 0x5002e000,
142 .ppc = NO_PPC,
143 .irq = NMI_0,
144 .slowclk = true,
147 .name = "nswatchdog",
148 .type = TYPE_CMSDK_APB_WATCHDOG,
149 .index = 1,
150 .addr = 0x40081000,
151 .ppc = NO_PPC,
152 .irq = 1,
155 .name = "swatchdog",
156 .type = TYPE_CMSDK_APB_WATCHDOG,
157 .index = 2,
158 .addr = 0x50081000,
159 .ppc = NO_PPC,
160 .irq = NMI_1,
163 .name = "armsse-sysinfo",
164 .type = TYPE_IOTKIT_SYSINFO,
165 .index = 0,
166 .addr = 0x40020000,
167 .ppc = NO_PPC,
168 .irq = NO_IRQ,
171 .name = "armsse-sysctl",
172 .type = TYPE_IOTKIT_SYSCTL,
173 .index = 0,
174 .addr = 0x50021000,
175 .ppc = NO_PPC,
176 .irq = NO_IRQ,
179 .name = NULL,
183 static const ARMSSEDeviceInfo sse200_devices[] = {
185 .name = "timer0",
186 .type = TYPE_CMSDK_APB_TIMER,
187 .index = 0,
188 .addr = 0x40000000,
189 .ppc = 0,
190 .ppc_port = 0,
191 .irq = 3,
194 .name = "timer1",
195 .type = TYPE_CMSDK_APB_TIMER,
196 .index = 1,
197 .addr = 0x40001000,
198 .ppc = 0,
199 .ppc_port = 1,
200 .irq = 4,
203 .name = "s32ktimer",
204 .type = TYPE_CMSDK_APB_TIMER,
205 .index = 2,
206 .addr = 0x4002f000,
207 .ppc = 1,
208 .ppc_port = 0,
209 .irq = 2,
210 .slowclk = true,
213 .name = "dualtimer",
214 .type = TYPE_CMSDK_APB_DUALTIMER,
215 .index = 0,
216 .addr = 0x40002000,
217 .ppc = 0,
218 .ppc_port = 2,
219 .irq = 5,
222 .name = "s32kwatchdog",
223 .type = TYPE_CMSDK_APB_WATCHDOG,
224 .index = 0,
225 .addr = 0x5002e000,
226 .ppc = NO_PPC,
227 .irq = NMI_0,
228 .slowclk = true,
231 .name = "nswatchdog",
232 .type = TYPE_CMSDK_APB_WATCHDOG,
233 .index = 1,
234 .addr = 0x40081000,
235 .ppc = NO_PPC,
236 .irq = 1,
239 .name = "swatchdog",
240 .type = TYPE_CMSDK_APB_WATCHDOG,
241 .index = 2,
242 .addr = 0x50081000,
243 .ppc = NO_PPC,
244 .irq = NMI_1,
247 .name = "armsse-sysinfo",
248 .type = TYPE_IOTKIT_SYSINFO,
249 .index = 0,
250 .addr = 0x40020000,
251 .ppc = NO_PPC,
252 .irq = NO_IRQ,
255 .name = "armsse-sysctl",
256 .type = TYPE_IOTKIT_SYSCTL,
257 .index = 0,
258 .addr = 0x50021000,
259 .ppc = NO_PPC,
260 .irq = NO_IRQ,
263 .name = "CPU0CORE_PPU",
264 .type = TYPE_UNIMPLEMENTED_DEVICE,
265 .index = 0,
266 .addr = 0x50023000,
267 .size = 0x1000,
268 .ppc = NO_PPC,
269 .irq = NO_IRQ,
272 .name = "CPU1CORE_PPU",
273 .type = TYPE_UNIMPLEMENTED_DEVICE,
274 .index = 1,
275 .addr = 0x50025000,
276 .size = 0x1000,
277 .ppc = NO_PPC,
278 .irq = NO_IRQ,
281 .name = "DBG_PPU",
282 .type = TYPE_UNIMPLEMENTED_DEVICE,
283 .index = 2,
284 .addr = 0x50029000,
285 .size = 0x1000,
286 .ppc = NO_PPC,
287 .irq = NO_IRQ,
290 .name = "RAM0_PPU",
291 .type = TYPE_UNIMPLEMENTED_DEVICE,
292 .index = 3,
293 .addr = 0x5002a000,
294 .size = 0x1000,
295 .ppc = NO_PPC,
296 .irq = NO_IRQ,
299 .name = "RAM1_PPU",
300 .type = TYPE_UNIMPLEMENTED_DEVICE,
301 .index = 4,
302 .addr = 0x5002b000,
303 .size = 0x1000,
304 .ppc = NO_PPC,
305 .irq = NO_IRQ,
308 .name = "RAM2_PPU",
309 .type = TYPE_UNIMPLEMENTED_DEVICE,
310 .index = 5,
311 .addr = 0x5002c000,
312 .size = 0x1000,
313 .ppc = NO_PPC,
314 .irq = NO_IRQ,
317 .name = "RAM3_PPU",
318 .type = TYPE_UNIMPLEMENTED_DEVICE,
319 .index = 6,
320 .addr = 0x5002d000,
321 .size = 0x1000,
322 .ppc = NO_PPC,
323 .irq = NO_IRQ,
326 .name = "SYS_PPU",
327 .type = TYPE_UNIMPLEMENTED_DEVICE,
328 .index = 7,
329 .addr = 0x50022000,
330 .size = 0x1000,
331 .ppc = NO_PPC,
332 .irq = NO_IRQ,
335 .name = NULL,
339 /* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
340 static const bool sse200_irq_is_common[32] = {
341 [0 ... 5] = true,
342 /* 6, 7: per-CPU MHU interrupts */
343 [8 ... 12] = true,
344 /* 13: per-CPU icache interrupt */
345 /* 14: reserved */
346 [15 ... 20] = true,
347 /* 21: reserved */
348 [22 ... 26] = true,
349 /* 27: reserved */
350 /* 28, 29: per-CPU CTI interrupts */
351 /* 30, 31: reserved */
354 static const ARMSSEInfo armsse_variants[] = {
356 .name = TYPE_IOTKIT,
357 .sse_version = ARMSSE_IOTKIT,
358 .sram_banks = 1,
359 .num_cpus = 1,
360 .sys_version = 0x41743,
361 .iidr = 0,
362 .cpuwait_rst = 0,
363 .has_mhus = false,
364 .has_cachectrl = false,
365 .has_cpusecctrl = false,
366 .has_cpuid = false,
367 .has_sse_counter = false,
368 .props = iotkit_properties,
369 .devinfo = iotkit_devices,
370 .irq_is_common = sse200_irq_is_common,
373 .name = TYPE_SSE200,
374 .sse_version = ARMSSE_SSE200,
375 .sram_banks = 4,
376 .num_cpus = 2,
377 .sys_version = 0x22041743,
378 .iidr = 0,
379 .cpuwait_rst = 2,
380 .has_mhus = true,
381 .has_cachectrl = true,
382 .has_cpusecctrl = true,
383 .has_cpuid = true,
384 .has_sse_counter = false,
385 .props = armsse_properties,
386 .devinfo = sse200_devices,
387 .irq_is_common = sse200_irq_is_common,
391 static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
393 /* Return the SYS_CONFIG value for this SSE */
394 uint32_t sys_config;
396 switch (info->sse_version) {
397 case ARMSSE_IOTKIT:
398 sys_config = 0;
399 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
400 sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
401 break;
402 case ARMSSE_SSE200:
403 sys_config = 0;
404 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
405 sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
406 sys_config = deposit32(sys_config, 24, 4, 2);
407 if (info->num_cpus > 1) {
408 sys_config = deposit32(sys_config, 10, 1, 1);
409 sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
410 sys_config = deposit32(sys_config, 28, 4, 2);
412 break;
413 case ARMSSE_SSE300:
414 sys_config = 0;
415 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
416 sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
417 sys_config = deposit32(sys_config, 16, 3, 3); /* CPU0 = Cortex-M55 */
418 break;
419 default:
420 g_assert_not_reached();
422 return sys_config;
425 /* Clock frequency in HZ of the 32KHz "slow clock" */
426 #define S32KCLK (32 * 1000)
429 * Create an alias region in @container of @size bytes starting at @base
430 * which mirrors the memory starting at @orig.
432 static void make_alias(ARMSSE *s, MemoryRegion *mr, MemoryRegion *container,
433 const char *name, hwaddr base, hwaddr size, hwaddr orig)
435 memory_region_init_alias(mr, NULL, name, container, orig, size);
436 /* The alias is even lower priority than unimplemented_device regions */
437 memory_region_add_subregion_overlap(container, base, mr, -1500);
440 static void irq_status_forwarder(void *opaque, int n, int level)
442 qemu_irq destirq = opaque;
444 qemu_set_irq(destirq, level);
447 static void nsccfg_handler(void *opaque, int n, int level)
449 ARMSSE *s = ARM_SSE(opaque);
451 s->nsccfg = level;
454 static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
456 /* Each of the 4 AHB and 4 APB PPCs that might be present in a
457 * system using the ARMSSE has a collection of control lines which
458 * are provided by the security controller and which we want to
459 * expose as control lines on the ARMSSE device itself, so the
460 * code using the ARMSSE can wire them up to the PPCs.
462 SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
463 DeviceState *armssedev = DEVICE(s);
464 DeviceState *dev_secctl = DEVICE(&s->secctl);
465 DeviceState *dev_splitter = DEVICE(splitter);
466 char *name;
468 name = g_strdup_printf("%s_nonsec", ppcname);
469 qdev_pass_gpios(dev_secctl, armssedev, name);
470 g_free(name);
471 name = g_strdup_printf("%s_ap", ppcname);
472 qdev_pass_gpios(dev_secctl, armssedev, name);
473 g_free(name);
474 name = g_strdup_printf("%s_irq_enable", ppcname);
475 qdev_pass_gpios(dev_secctl, armssedev, name);
476 g_free(name);
477 name = g_strdup_printf("%s_irq_clear", ppcname);
478 qdev_pass_gpios(dev_secctl, armssedev, name);
479 g_free(name);
481 /* irq_status is a little more tricky, because we need to
482 * split it so we can send it both to the security controller
483 * and to our OR gate for the NVIC interrupt line.
484 * Connect up the splitter's outputs, and create a GPIO input
485 * which will pass the line state to the input splitter.
487 name = g_strdup_printf("%s_irq_status", ppcname);
488 qdev_connect_gpio_out(dev_splitter, 0,
489 qdev_get_gpio_in_named(dev_secctl,
490 name, 0));
491 qdev_connect_gpio_out(dev_splitter, 1,
492 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
493 s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
494 qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
495 s->irq_status_in[ppcnum], name, 1);
496 g_free(name);
499 static void armsse_forward_sec_resp_cfg(ARMSSE *s)
501 /* Forward the 3rd output from the splitter device as a
502 * named GPIO output of the armsse object.
504 DeviceState *dev = DEVICE(s);
505 DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
507 qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
508 s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
509 s->sec_resp_cfg, 1);
510 qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
513 static void armsse_mainclk_update(void *opaque, ClockEvent event)
515 ARMSSE *s = ARM_SSE(opaque);
518 * Set system_clock_scale from our Clock input; this is what
519 * controls the tick rate of the CPU SysTick timer.
521 system_clock_scale = clock_ticks_to_ns(s->mainclk, 1);
524 static void armsse_init(Object *obj)
526 ARMSSE *s = ARM_SSE(obj);
527 ARMSSEClass *asc = ARM_SSE_GET_CLASS(obj);
528 const ARMSSEInfo *info = asc->info;
529 const ARMSSEDeviceInfo *devinfo;
530 int i;
532 assert(info->sram_banks <= MAX_SRAM_BANKS);
533 assert(info->num_cpus <= SSE_MAX_CPUS);
535 s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
536 armsse_mainclk_update, s, ClockUpdate);
537 s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL, 0);
539 memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
541 for (i = 0; i < info->num_cpus; i++) {
543 * We put each CPU in its own cluster as they are logically
544 * distinct and may be configured differently.
546 char *name;
548 name = g_strdup_printf("cluster%d", i);
549 object_initialize_child(obj, name, &s->cluster[i], TYPE_CPU_CLUSTER);
550 qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
551 g_free(name);
553 name = g_strdup_printf("armv7m%d", i);
554 object_initialize_child(OBJECT(&s->cluster[i]), name, &s->armv7m[i],
555 TYPE_ARMV7M);
556 qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
557 ARM_CPU_TYPE_NAME("cortex-m33"));
558 g_free(name);
559 name = g_strdup_printf("arm-sse-cpu-container%d", i);
560 memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
561 g_free(name);
562 if (i > 0) {
563 name = g_strdup_printf("arm-sse-container-alias%d", i);
564 memory_region_init_alias(&s->container_alias[i - 1], obj,
565 name, &s->container, 0, UINT64_MAX);
566 g_free(name);
570 for (devinfo = info->devinfo; devinfo->name; devinfo++) {
571 assert(devinfo->ppc == NO_PPC || devinfo->ppc < ARRAY_SIZE(s->apb_ppc));
572 if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
573 assert(devinfo->index < ARRAY_SIZE(s->timer));
574 object_initialize_child(obj, devinfo->name,
575 &s->timer[devinfo->index],
576 TYPE_CMSDK_APB_TIMER);
577 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
578 assert(devinfo->index == 0);
579 object_initialize_child(obj, devinfo->name, &s->dualtimer,
580 TYPE_CMSDK_APB_DUALTIMER);
581 } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
582 assert(devinfo->index < ARRAY_SIZE(s->sse_timer));
583 object_initialize_child(obj, devinfo->name,
584 &s->sse_timer[devinfo->index],
585 TYPE_SSE_TIMER);
586 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
587 assert(devinfo->index < ARRAY_SIZE(s->cmsdk_watchdog));
588 object_initialize_child(obj, devinfo->name,
589 &s->cmsdk_watchdog[devinfo->index],
590 TYPE_CMSDK_APB_WATCHDOG);
591 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
592 assert(devinfo->index == 0);
593 object_initialize_child(obj, devinfo->name, &s->sysinfo,
594 TYPE_IOTKIT_SYSINFO);
595 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
596 assert(devinfo->index == 0);
597 object_initialize_child(obj, devinfo->name, &s->sysctl,
598 TYPE_IOTKIT_SYSCTL);
599 } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
600 assert(devinfo->index < ARRAY_SIZE(s->unimp));
601 object_initialize_child(obj, devinfo->name,
602 &s->unimp[devinfo->index],
603 TYPE_UNIMPLEMENTED_DEVICE);
604 } else {
605 g_assert_not_reached();
609 object_initialize_child(obj, "secctl", &s->secctl, TYPE_IOTKIT_SECCTL);
611 for (i = 0; i < ARRAY_SIZE(s->apb_ppc); i++) {
612 g_autofree char *name = g_strdup_printf("apb-ppc%d", i);
613 object_initialize_child(obj, name, &s->apb_ppc[i], TYPE_TZ_PPC);
616 for (i = 0; i < info->sram_banks; i++) {
617 char *name = g_strdup_printf("mpc%d", i);
618 object_initialize_child(obj, name, &s->mpc[i], TYPE_TZ_MPC);
619 g_free(name);
621 object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
622 TYPE_OR_IRQ);
624 for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
625 char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
626 SplitIRQ *splitter = &s->mpc_irq_splitter[i];
628 object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
629 g_free(name);
632 if (info->has_mhus) {
633 object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
634 object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
636 if (info->has_cachectrl) {
637 for (i = 0; i < info->num_cpus; i++) {
638 char *name = g_strdup_printf("cachectrl%d", i);
640 object_initialize_child(obj, name, &s->cachectrl[i],
641 TYPE_UNIMPLEMENTED_DEVICE);
642 g_free(name);
645 if (info->has_cpusecctrl) {
646 for (i = 0; i < info->num_cpus; i++) {
647 char *name = g_strdup_printf("cpusecctrl%d", i);
649 object_initialize_child(obj, name, &s->cpusecctrl[i],
650 TYPE_UNIMPLEMENTED_DEVICE);
651 g_free(name);
654 if (info->has_cpuid) {
655 for (i = 0; i < info->num_cpus; i++) {
656 char *name = g_strdup_printf("cpuid%d", i);
658 object_initialize_child(obj, name, &s->cpuid[i],
659 TYPE_ARMSSE_CPUID);
660 g_free(name);
663 if (info->has_sse_counter) {
664 object_initialize_child(obj, "sse-counter", &s->sse_counter,
665 TYPE_SSE_COUNTER);
668 object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, TYPE_OR_IRQ);
669 object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
670 TYPE_OR_IRQ);
671 object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
672 TYPE_SPLIT_IRQ);
673 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
674 char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
675 SplitIRQ *splitter = &s->ppc_irq_splitter[i];
677 object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
678 g_free(name);
680 if (info->num_cpus > 1) {
681 for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
682 if (info->irq_is_common[i]) {
683 char *name = g_strdup_printf("cpu-irq-splitter%d", i);
684 SplitIRQ *splitter = &s->cpu_irq_splitter[i];
686 object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
687 g_free(name);
693 static void armsse_exp_irq(void *opaque, int n, int level)
695 qemu_irq *irqarray = opaque;
697 qemu_set_irq(irqarray[n], level);
700 static void armsse_mpcexp_status(void *opaque, int n, int level)
702 ARMSSE *s = ARM_SSE(opaque);
703 qemu_set_irq(s->mpcexp_status_in[n], level);
706 static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
709 * Return a qemu_irq which can be used to signal IRQ n to
710 * all CPUs in the SSE.
712 ARMSSEClass *asc = ARM_SSE_GET_CLASS(s);
713 const ARMSSEInfo *info = asc->info;
715 assert(info->irq_is_common[irqno]);
717 if (info->num_cpus == 1) {
718 /* Only one CPU -- just connect directly to it */
719 return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
720 } else {
721 /* Connect to the splitter which feeds all CPUs */
722 return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
726 static void armsse_realize(DeviceState *dev, Error **errp)
728 ARMSSE *s = ARM_SSE(dev);
729 ARMSSEClass *asc = ARM_SSE_GET_CLASS(dev);
730 const ARMSSEInfo *info = asc->info;
731 const ARMSSEDeviceInfo *devinfo;
732 int i;
733 MemoryRegion *mr;
734 Error *err = NULL;
735 SysBusDevice *sbd_apb_ppc0;
736 SysBusDevice *sbd_secctl;
737 DeviceState *dev_apb_ppc0;
738 DeviceState *dev_apb_ppc1;
739 DeviceState *dev_secctl;
740 DeviceState *dev_splitter;
741 uint32_t addr_width_max;
743 if (!s->board_memory) {
744 error_setg(errp, "memory property was not set");
745 return;
748 if (!clock_has_source(s->mainclk)) {
749 error_setg(errp, "MAINCLK clock was not connected");
751 if (!clock_has_source(s->s32kclk)) {
752 error_setg(errp, "S32KCLK clock was not connected");
755 assert(info->num_cpus <= SSE_MAX_CPUS);
757 /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
758 assert(is_power_of_2(info->sram_banks));
759 addr_width_max = 24 - ctz32(info->sram_banks);
760 if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
761 error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
762 addr_width_max);
763 return;
766 /* Handling of which devices should be available only to secure
767 * code is usually done differently for M profile than for A profile.
768 * Instead of putting some devices only into the secure address space,
769 * devices exist in both address spaces but with hard-wired security
770 * permissions that will cause the CPU to fault for non-secure accesses.
772 * The ARMSSE has an IDAU (Implementation Defined Access Unit),
773 * which specifies hard-wired security permissions for different
774 * areas of the physical address space. For the ARMSSE IDAU, the
775 * top 4 bits of the physical address are the IDAU region ID, and
776 * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
777 * region, otherwise it is an S region.
779 * The various devices and RAMs are generally all mapped twice,
780 * once into a region that the IDAU defines as secure and once
781 * into a non-secure region. They sit behind either a Memory
782 * Protection Controller (for RAM) or a Peripheral Protection
783 * Controller (for devices), which allow a more fine grained
784 * configuration of whether non-secure accesses are permitted.
786 * (The other place that guest software can configure security
787 * permissions is in the architected SAU (Security Attribution
788 * Unit), which is entirely inside the CPU. The IDAU can upgrade
789 * the security attributes for a region to more restrictive than
790 * the SAU specifies, but cannot downgrade them.)
792 * 0x10000000..0x1fffffff alias of 0x00000000..0x0fffffff
793 * 0x20000000..0x2007ffff 32KB FPGA block RAM
794 * 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff
795 * 0x40000000..0x4000ffff base peripheral region 1
796 * 0x40010000..0x4001ffff CPU peripherals (none for ARMSSE)
797 * 0x40020000..0x4002ffff system control element peripherals
798 * 0x40080000..0x400fffff base peripheral region 2
799 * 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
802 memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
804 for (i = 0; i < info->num_cpus; i++) {
805 DeviceState *cpudev = DEVICE(&s->armv7m[i]);
806 Object *cpuobj = OBJECT(&s->armv7m[i]);
807 int j;
808 char *gpioname;
810 qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + NUM_SSE_IRQS);
812 * In real hardware the initial Secure VTOR is set from the INITSVTOR*
813 * registers in the IoT Kit System Control Register block. In QEMU
814 * we set the initial value here, and also the reset value of the
815 * sysctl register, from this object's QOM init-svtor property.
816 * If the guest changes the INITSVTOR* registers at runtime then the
817 * code in iotkit-sysctl.c will update the CPU init-svtor property
818 * (which will then take effect on the next CPU warm-reset).
820 * Note that typically a board using the SSE-200 will have a system
821 * control processor whose boot firmware initializes the INITSVTOR*
822 * registers before powering up the CPUs. QEMU doesn't emulate
823 * the control processor, so instead we behave in the way that the
824 * firmware does: the initial value should be set by the board code
825 * (using the init-svtor property on the ARMSSE object) to match
826 * whatever its firmware does.
828 qdev_prop_set_uint32(cpudev, "init-svtor", s->init_svtor);
830 * CPUs start powered down if the corresponding bit in the CPUWAIT
831 * register is 1. In real hardware the CPUWAIT register reset value is
832 * a configurable property of the SSE-200 (via the CPUWAIT0_RST and
833 * CPUWAIT1_RST parameters), but since all the boards we care about
834 * start CPU0 and leave CPU1 powered off, we hard-code that in
835 * info->cpuwait_rst for now. We can add QOM properties for this
836 * later if necessary.
838 if (extract32(info->cpuwait_rst, i, 1)) {
839 if (!object_property_set_bool(cpuobj, "start-powered-off", true,
840 errp)) {
841 return;
844 if (!s->cpu_fpu[i]) {
845 if (!object_property_set_bool(cpuobj, "vfp", false, errp)) {
846 return;
849 if (!s->cpu_dsp[i]) {
850 if (!object_property_set_bool(cpuobj, "dsp", false, errp)) {
851 return;
855 if (i > 0) {
856 memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
857 &s->container_alias[i - 1], -1);
858 } else {
859 memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
860 &s->container, -1);
862 object_property_set_link(cpuobj, "memory",
863 OBJECT(&s->cpu_container[i]), &error_abort);
864 object_property_set_link(cpuobj, "idau", OBJECT(s), &error_abort);
865 if (!sysbus_realize(SYS_BUS_DEVICE(cpuobj), errp)) {
866 return;
869 * The cluster must be realized after the armv7m container, as
870 * the container's CPU object is only created on realize, and the
871 * CPU must exist and have been parented into the cluster before
872 * the cluster is realized.
874 if (!qdev_realize(DEVICE(&s->cluster[i]), NULL, errp)) {
875 return;
878 /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
879 s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
880 for (j = 0; j < s->exp_numirq; j++) {
881 s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + NUM_SSE_IRQS);
883 if (i == 0) {
884 gpioname = g_strdup("EXP_IRQ");
885 } else {
886 gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
888 qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
889 s->exp_irqs[i],
890 gpioname, s->exp_numirq);
891 g_free(gpioname);
894 /* Wire up the splitters that connect common IRQs to all CPUs */
895 if (info->num_cpus > 1) {
896 for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
897 if (info->irq_is_common[i]) {
898 Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
899 DeviceState *devs = DEVICE(splitter);
900 int cpunum;
902 if (!object_property_set_int(splitter, "num-lines",
903 info->num_cpus, errp)) {
904 return;
906 if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
907 return;
909 for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
910 DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
912 qdev_connect_gpio_out(devs, cpunum,
913 qdev_get_gpio_in(cpudev, i));
919 /* Set up the big aliases first */
920 make_alias(s, &s->alias1, &s->container, "alias 1",
921 0x10000000, 0x10000000, 0x00000000);
922 make_alias(s, &s->alias2, &s->container,
923 "alias 2", 0x30000000, 0x10000000, 0x20000000);
924 /* The 0x50000000..0x5fffffff region is not a pure alias: it has
925 * a few extra devices that only appear there (generally the
926 * control interfaces for the protection controllers).
927 * We implement this by mapping those devices over the top of this
928 * alias MR at a higher priority. Some of the devices in this range
929 * are per-CPU, so we must put this alias in the per-cpu containers.
931 for (i = 0; i < info->num_cpus; i++) {
932 make_alias(s, &s->alias3[i], &s->cpu_container[i],
933 "alias 3", 0x50000000, 0x10000000, 0x40000000);
936 /* Security controller */
937 object_property_set_int(OBJECT(&s->secctl), "sse-version",
938 info->sse_version, &error_abort);
939 if (!sysbus_realize(SYS_BUS_DEVICE(&s->secctl), errp)) {
940 return;
942 sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
943 dev_secctl = DEVICE(&s->secctl);
944 sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
945 sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
947 s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
948 qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
950 /* The sec_resp_cfg output from the security controller must be split into
951 * multiple lines, one for each of the PPCs within the ARMSSE and one
952 * that will be an output from the ARMSSE to the system.
954 if (!object_property_set_int(OBJECT(&s->sec_resp_splitter),
955 "num-lines", 3, errp)) {
956 return;
958 if (!qdev_realize(DEVICE(&s->sec_resp_splitter), NULL, errp)) {
959 return;
961 dev_splitter = DEVICE(&s->sec_resp_splitter);
962 qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
963 qdev_get_gpio_in(dev_splitter, 0));
965 /* Each SRAM bank lives behind its own Memory Protection Controller */
966 for (i = 0; i < info->sram_banks; i++) {
967 char *ramname = g_strdup_printf("armsse.sram%d", i);
968 SysBusDevice *sbd_mpc;
969 uint32_t sram_bank_size = 1 << s->sram_addr_width;
971 memory_region_init_ram(&s->sram[i], NULL, ramname,
972 sram_bank_size, &err);
973 g_free(ramname);
974 if (err) {
975 error_propagate(errp, err);
976 return;
978 object_property_set_link(OBJECT(&s->mpc[i]), "downstream",
979 OBJECT(&s->sram[i]), &error_abort);
980 if (!sysbus_realize(SYS_BUS_DEVICE(&s->mpc[i]), errp)) {
981 return;
983 /* Map the upstream end of the MPC into the right place... */
984 sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
985 memory_region_add_subregion(&s->container,
986 0x20000000 + i * sram_bank_size,
987 sysbus_mmio_get_region(sbd_mpc, 1));
988 /* ...and its register interface */
989 memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
990 sysbus_mmio_get_region(sbd_mpc, 0));
993 /* We must OR together lines from the MPC splitters to go to the NVIC */
994 if (!object_property_set_int(OBJECT(&s->mpc_irq_orgate), "num-lines",
995 IOTS_NUM_EXP_MPC + info->sram_banks,
996 errp)) {
997 return;
999 if (!qdev_realize(DEVICE(&s->mpc_irq_orgate), NULL, errp)) {
1000 return;
1002 qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
1003 armsse_get_common_irq_in(s, 9));
1005 /* This OR gate wires together outputs from the secure watchdogs to NMI */
1006 if (!object_property_set_int(OBJECT(&s->nmi_orgate), "num-lines", 2,
1007 errp)) {
1008 return;
1010 if (!qdev_realize(DEVICE(&s->nmi_orgate), NULL, errp)) {
1011 return;
1013 qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
1014 qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
1016 /* The SSE-300 has a System Counter / System Timestamp Generator */
1017 if (info->has_sse_counter) {
1018 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->sse_counter);
1020 qdev_connect_clock_in(DEVICE(sbd), "CLK", s->mainclk);
1021 if (!sysbus_realize(sbd, errp)) {
1022 return;
1025 * The control frame is only in the Secure region;
1026 * the status frame is in the NS region (and visible in the
1027 * S region via the alias mapping).
1029 memory_region_add_subregion(&s->container, 0x58100000,
1030 sysbus_mmio_get_region(sbd, 0));
1031 memory_region_add_subregion(&s->container, 0x48101000,
1032 sysbus_mmio_get_region(sbd, 1));
1035 /* Devices behind APB PPC0:
1036 * 0x40000000: timer0
1037 * 0x40001000: timer1
1038 * 0x40002000: dual timer
1039 * 0x40003000: MHU0 (SSE-200 only)
1040 * 0x40004000: MHU1 (SSE-200 only)
1041 * We must configure and realize each downstream device and connect
1042 * it to the appropriate PPC port; then we can realize the PPC and
1043 * map its upstream ends to the right place in the container.
1045 for (devinfo = info->devinfo; devinfo->name; devinfo++) {
1046 SysBusDevice *sbd;
1047 qemu_irq irq;
1049 if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
1050 sbd = SYS_BUS_DEVICE(&s->timer[devinfo->index]);
1052 qdev_connect_clock_in(DEVICE(sbd), "pclk",
1053 devinfo->slowclk ? s->s32kclk : s->mainclk);
1054 if (!sysbus_realize(sbd, errp)) {
1055 return;
1057 mr = sysbus_mmio_get_region(sbd, 0);
1058 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
1059 sbd = SYS_BUS_DEVICE(&s->dualtimer);
1061 qdev_connect_clock_in(DEVICE(sbd), "TIMCLK", s->mainclk);
1062 if (!sysbus_realize(sbd, errp)) {
1063 return;
1065 mr = sysbus_mmio_get_region(sbd, 0);
1066 } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
1067 sbd = SYS_BUS_DEVICE(&s->sse_timer[devinfo->index]);
1069 assert(info->has_sse_counter);
1070 object_property_set_link(OBJECT(sbd), "counter",
1071 OBJECT(&s->sse_counter), &error_abort);
1072 if (!sysbus_realize(sbd, errp)) {
1073 return;
1075 mr = sysbus_mmio_get_region(sbd, 0);
1076 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
1077 sbd = SYS_BUS_DEVICE(&s->cmsdk_watchdog[devinfo->index]);
1079 qdev_connect_clock_in(DEVICE(sbd), "WDOGCLK",
1080 devinfo->slowclk ? s->s32kclk : s->mainclk);
1081 if (!sysbus_realize(sbd, errp)) {
1082 return;
1084 mr = sysbus_mmio_get_region(sbd, 0);
1085 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
1086 sbd = SYS_BUS_DEVICE(&s->sysinfo);
1088 object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
1089 info->sys_version, &error_abort);
1090 object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
1091 armsse_sys_config_value(s, info),
1092 &error_abort);
1093 object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
1094 info->sse_version, &error_abort);
1095 object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
1096 info->iidr, &error_abort);
1097 if (!sysbus_realize(sbd, errp)) {
1098 return;
1100 mr = sysbus_mmio_get_region(sbd, 0);
1101 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
1102 /* System control registers */
1103 sbd = SYS_BUS_DEVICE(&s->sysctl);
1105 object_property_set_int(OBJECT(&s->sysctl), "sse-version",
1106 info->sse_version, &error_abort);
1107 object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
1108 info->cpuwait_rst, &error_abort);
1109 object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
1110 s->init_svtor, &error_abort);
1111 object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR1_RST",
1112 s->init_svtor, &error_abort);
1113 if (!sysbus_realize(sbd, errp)) {
1114 return;
1116 mr = sysbus_mmio_get_region(sbd, 0);
1117 } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
1118 sbd = SYS_BUS_DEVICE(&s->unimp[devinfo->index]);
1120 qdev_prop_set_string(DEVICE(sbd), "name", devinfo->name);
1121 qdev_prop_set_uint64(DEVICE(sbd), "size", devinfo->size);
1122 if (!sysbus_realize(sbd, errp)) {
1123 return;
1125 mr = sysbus_mmio_get_region(sbd, 0);
1126 } else {
1127 g_assert_not_reached();
1130 switch (devinfo->irq) {
1131 case NO_IRQ:
1132 irq = NULL;
1133 break;
1134 case 0 ... NUM_SSE_IRQS - 1:
1135 irq = armsse_get_common_irq_in(s, devinfo->irq);
1136 break;
1137 case NMI_0:
1138 case NMI_1:
1139 irq = qdev_get_gpio_in(DEVICE(&s->nmi_orgate),
1140 devinfo->irq - NMI_0);
1141 break;
1142 default:
1143 g_assert_not_reached();
1146 if (irq) {
1147 sysbus_connect_irq(sbd, 0, irq);
1151 * Devices connected to a PPC are connected to the port here;
1152 * we will map the upstream end of that port to the right address
1153 * in the container later after the PPC has been realized.
1154 * Devices not connected to a PPC can be mapped immediately.
1156 if (devinfo->ppc != NO_PPC) {
1157 TZPPC *ppc = &s->apb_ppc[devinfo->ppc];
1158 g_autofree char *portname = g_strdup_printf("port[%d]",
1159 devinfo->ppc_port);
1160 object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
1161 &error_abort);
1162 } else {
1163 memory_region_add_subregion(&s->container, devinfo->addr, mr);
1167 if (info->has_mhus) {
1169 * An SSE-200 with only one CPU should have only one MHU created,
1170 * with the region where the second MHU usually is being RAZ/WI.
1171 * We don't implement that SSE-200 config; if we want to support
1172 * it then this code needs to be enhanced to handle creating the
1173 * RAZ/WI region instead of the second MHU.
1175 assert(info->num_cpus == ARRAY_SIZE(s->mhu));
1177 for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
1178 char *port;
1179 int cpunum;
1180 SysBusDevice *mhu_sbd = SYS_BUS_DEVICE(&s->mhu[i]);
1182 if (!sysbus_realize(SYS_BUS_DEVICE(&s->mhu[i]), errp)) {
1183 return;
1185 port = g_strdup_printf("port[%d]", i + 3);
1186 mr = sysbus_mmio_get_region(mhu_sbd, 0);
1187 object_property_set_link(OBJECT(&s->apb_ppc[0]), port, OBJECT(mr),
1188 &error_abort);
1189 g_free(port);
1192 * Each MHU has an irq line for each CPU:
1193 * MHU 0 irq line 0 -> CPU 0 IRQ 6
1194 * MHU 0 irq line 1 -> CPU 1 IRQ 6
1195 * MHU 1 irq line 0 -> CPU 0 IRQ 7
1196 * MHU 1 irq line 1 -> CPU 1 IRQ 7
1198 for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
1199 DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
1201 sysbus_connect_irq(mhu_sbd, cpunum,
1202 qdev_get_gpio_in(cpudev, 6 + i));
1207 if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[0]), errp)) {
1208 return;
1211 sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc[0]);
1212 dev_apb_ppc0 = DEVICE(&s->apb_ppc[0]);
1214 if (info->has_mhus) {
1215 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
1216 memory_region_add_subregion(&s->container, 0x40003000, mr);
1217 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
1218 memory_region_add_subregion(&s->container, 0x40004000, mr);
1220 for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
1221 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
1222 qdev_get_gpio_in_named(dev_apb_ppc0,
1223 "cfg_nonsec", i));
1224 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
1225 qdev_get_gpio_in_named(dev_apb_ppc0,
1226 "cfg_ap", i));
1228 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
1229 qdev_get_gpio_in_named(dev_apb_ppc0,
1230 "irq_enable", 0));
1231 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
1232 qdev_get_gpio_in_named(dev_apb_ppc0,
1233 "irq_clear", 0));
1234 qdev_connect_gpio_out(dev_splitter, 0,
1235 qdev_get_gpio_in_named(dev_apb_ppc0,
1236 "cfg_sec_resp", 0));
1238 /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
1239 * ones) are sent individually to the security controller, and also
1240 * ORed together to give a single combined PPC interrupt to the NVIC.
1242 if (!object_property_set_int(OBJECT(&s->ppc_irq_orgate),
1243 "num-lines", NUM_PPCS, errp)) {
1244 return;
1246 if (!qdev_realize(DEVICE(&s->ppc_irq_orgate), NULL, errp)) {
1247 return;
1249 qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
1250 armsse_get_common_irq_in(s, 10));
1253 * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
1254 * private per-CPU region (all these devices are SSE-200 only):
1255 * 0x50010000: L1 icache control registers
1256 * 0x50011000: CPUSECCTRL (CPU local security control registers)
1257 * 0x4001f000 and 0x5001f000: CPU_IDENTITY register block
1259 if (info->has_cachectrl) {
1260 for (i = 0; i < info->num_cpus; i++) {
1261 char *name = g_strdup_printf("cachectrl%d", i);
1262 MemoryRegion *mr;
1264 qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
1265 g_free(name);
1266 qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
1267 if (!sysbus_realize(SYS_BUS_DEVICE(&s->cachectrl[i]), errp)) {
1268 return;
1271 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
1272 memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
1275 if (info->has_cpusecctrl) {
1276 for (i = 0; i < info->num_cpus; i++) {
1277 char *name = g_strdup_printf("CPUSECCTRL%d", i);
1278 MemoryRegion *mr;
1280 qdev_prop_set_string(DEVICE(&s->cpusecctrl[i]), "name", name);
1281 g_free(name);
1282 qdev_prop_set_uint64(DEVICE(&s->cpusecctrl[i]), "size", 0x1000);
1283 if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpusecctrl[i]), errp)) {
1284 return;
1287 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpusecctrl[i]), 0);
1288 memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
1291 if (info->has_cpuid) {
1292 for (i = 0; i < info->num_cpus; i++) {
1293 MemoryRegion *mr;
1295 qdev_prop_set_uint32(DEVICE(&s->cpuid[i]), "CPUID", i);
1296 if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpuid[i]), errp)) {
1297 return;
1300 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpuid[i]), 0);
1301 memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
1305 if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[1]), errp)) {
1306 return;
1309 dev_apb_ppc1 = DEVICE(&s->apb_ppc[1]);
1310 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
1311 qdev_get_gpio_in_named(dev_apb_ppc1,
1312 "cfg_nonsec", 0));
1313 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
1314 qdev_get_gpio_in_named(dev_apb_ppc1,
1315 "cfg_ap", 0));
1316 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
1317 qdev_get_gpio_in_named(dev_apb_ppc1,
1318 "irq_enable", 0));
1319 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
1320 qdev_get_gpio_in_named(dev_apb_ppc1,
1321 "irq_clear", 0));
1322 qdev_connect_gpio_out(dev_splitter, 1,
1323 qdev_get_gpio_in_named(dev_apb_ppc1,
1324 "cfg_sec_resp", 0));
1327 * Now both PPCs are realized we can map the upstream ends of
1328 * ports which correspond to entries in the devinfo array.
1329 * The ports which are connected to non-devinfo devices have
1330 * already been mapped.
1332 for (devinfo = info->devinfo; devinfo->name; devinfo++) {
1333 SysBusDevice *ppc_sbd;
1335 if (devinfo->ppc == NO_PPC) {
1336 continue;
1338 ppc_sbd = SYS_BUS_DEVICE(&s->apb_ppc[devinfo->ppc]);
1339 mr = sysbus_mmio_get_region(ppc_sbd, devinfo->ppc_port);
1340 memory_region_add_subregion(&s->container, devinfo->addr, mr);
1343 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
1344 Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
1346 if (!object_property_set_int(splitter, "num-lines", 2, errp)) {
1347 return;
1349 if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
1350 return;
1354 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
1355 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
1357 armsse_forward_ppc(s, ppcname, i);
1358 g_free(ppcname);
1361 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
1362 char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
1364 armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
1365 g_free(ppcname);
1368 for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
1369 /* Wire up IRQ splitter for internal PPCs */
1370 DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
1371 char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
1372 i - NUM_EXTERNAL_PPCS);
1373 TZPPC *ppc = &s->apb_ppc[i - NUM_EXTERNAL_PPCS];
1375 qdev_connect_gpio_out(devs, 0,
1376 qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
1377 qdev_connect_gpio_out(devs, 1,
1378 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
1379 qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
1380 qdev_get_gpio_in(devs, 0));
1381 g_free(gpioname);
1384 /* Wire up the splitters for the MPC IRQs */
1385 for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
1386 SplitIRQ *splitter = &s->mpc_irq_splitter[i];
1387 DeviceState *dev_splitter = DEVICE(splitter);
1389 if (!object_property_set_int(OBJECT(splitter), "num-lines", 2,
1390 errp)) {
1391 return;
1393 if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
1394 return;
1397 if (i < IOTS_NUM_EXP_MPC) {
1398 /* Splitter input is from GPIO input line */
1399 s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
1400 qdev_connect_gpio_out(dev_splitter, 0,
1401 qdev_get_gpio_in_named(dev_secctl,
1402 "mpcexp_status", i));
1403 } else {
1404 /* Splitter input is from our own MPC */
1405 qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
1406 "irq", 0,
1407 qdev_get_gpio_in(dev_splitter, 0));
1408 qdev_connect_gpio_out(dev_splitter, 0,
1409 qdev_get_gpio_in_named(dev_secctl,
1410 "mpc_status",
1411 i - IOTS_NUM_EXP_MPC));
1414 qdev_connect_gpio_out(dev_splitter, 1,
1415 qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
1417 /* Create GPIO inputs which will pass the line state for our
1418 * mpcexp_irq inputs to the correct splitter devices.
1420 qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
1421 IOTS_NUM_EXP_MPC);
1423 armsse_forward_sec_resp_cfg(s);
1425 /* Forward the MSC related signals */
1426 qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
1427 qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
1428 qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
1429 qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
1430 armsse_get_common_irq_in(s, 11));
1433 * Expose our container region to the board model; this corresponds
1434 * to the AHB Slave Expansion ports which allow bus master devices
1435 * (eg DMA controllers) in the board model to make transactions into
1436 * devices in the ARMSSE.
1438 sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
1440 /* Set initial system_clock_scale from MAINCLK */
1441 armsse_mainclk_update(s, ClockUpdate);
1444 static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
1445 int *iregion, bool *exempt, bool *ns, bool *nsc)
1448 * For ARMSSE systems the IDAU responses are simple logical functions
1449 * of the address bits. The NSC attribute is guest-adjustable via the
1450 * NSCCFG register in the security controller.
1452 ARMSSE *s = ARM_SSE(ii);
1453 int region = extract32(address, 28, 4);
1455 *ns = !(region & 1);
1456 *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
1457 /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
1458 *exempt = (address & 0xeff00000) == 0xe0000000;
1459 *iregion = region;
1462 static const VMStateDescription armsse_vmstate = {
1463 .name = "iotkit",
1464 .version_id = 2,
1465 .minimum_version_id = 2,
1466 .fields = (VMStateField[]) {
1467 VMSTATE_CLOCK(mainclk, ARMSSE),
1468 VMSTATE_CLOCK(s32kclk, ARMSSE),
1469 VMSTATE_UINT32(nsccfg, ARMSSE),
1470 VMSTATE_END_OF_LIST()
1474 static void armsse_reset(DeviceState *dev)
1476 ARMSSE *s = ARM_SSE(dev);
1478 s->nsccfg = 0;
1481 static void armsse_class_init(ObjectClass *klass, void *data)
1483 DeviceClass *dc = DEVICE_CLASS(klass);
1484 IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
1485 ARMSSEClass *asc = ARM_SSE_CLASS(klass);
1486 const ARMSSEInfo *info = data;
1488 dc->realize = armsse_realize;
1489 dc->vmsd = &armsse_vmstate;
1490 device_class_set_props(dc, info->props);
1491 dc->reset = armsse_reset;
1492 iic->check = armsse_idau_check;
1493 asc->info = info;
1496 static const TypeInfo armsse_info = {
1497 .name = TYPE_ARM_SSE,
1498 .parent = TYPE_SYS_BUS_DEVICE,
1499 .instance_size = sizeof(ARMSSE),
1500 .class_size = sizeof(ARMSSEClass),
1501 .instance_init = armsse_init,
1502 .abstract = true,
1503 .interfaces = (InterfaceInfo[]) {
1504 { TYPE_IDAU_INTERFACE },
1509 static void armsse_register_types(void)
1511 int i;
1513 type_register_static(&armsse_info);
1515 for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
1516 TypeInfo ti = {
1517 .name = armsse_variants[i].name,
1518 .parent = TYPE_ARM_SSE,
1519 .class_init = armsse_class_init,
1520 .class_data = (void *)&armsse_variants[i],
1522 type_register(&ti);
1526 type_init(armsse_register_types);