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"
14 #include "qemu/module.h"
15 #include "qemu/bitops.h"
16 #include "qapi/error.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"
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
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
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 ? */
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 */
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
,
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
,
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
[] = {
101 .type
= TYPE_CMSDK_APB_TIMER
,
110 .type
= TYPE_CMSDK_APB_TIMER
,
119 .type
= TYPE_CMSDK_APB_TIMER
,
129 .type
= TYPE_CMSDK_APB_DUALTIMER
,
137 .name
= "s32kwatchdog",
138 .type
= TYPE_CMSDK_APB_WATCHDOG
,
146 .name
= "nswatchdog",
147 .type
= TYPE_CMSDK_APB_WATCHDOG
,
155 .type
= TYPE_CMSDK_APB_WATCHDOG
,
162 .name
= "armsse-sysinfo",
163 .type
= TYPE_IOTKIT_SYSINFO
,
170 .name
= "armsse-sysctl",
171 .type
= TYPE_IOTKIT_SYSCTL
,
182 static const ARMSSEDeviceInfo sse200_devices
[] = {
185 .type
= TYPE_CMSDK_APB_TIMER
,
194 .type
= TYPE_CMSDK_APB_TIMER
,
203 .type
= TYPE_CMSDK_APB_TIMER
,
213 .type
= TYPE_CMSDK_APB_DUALTIMER
,
221 .name
= "s32kwatchdog",
222 .type
= TYPE_CMSDK_APB_WATCHDOG
,
230 .name
= "nswatchdog",
231 .type
= TYPE_CMSDK_APB_WATCHDOG
,
239 .type
= TYPE_CMSDK_APB_WATCHDOG
,
246 .name
= "armsse-sysinfo",
247 .type
= TYPE_IOTKIT_SYSINFO
,
254 .name
= "armsse-sysctl",
255 .type
= TYPE_IOTKIT_SYSCTL
,
262 .name
= "CPU0CORE_PPU",
263 .type
= TYPE_UNIMPLEMENTED_DEVICE
,
271 .name
= "CPU1CORE_PPU",
272 .type
= TYPE_UNIMPLEMENTED_DEVICE
,
281 .type
= TYPE_UNIMPLEMENTED_DEVICE
,
290 .type
= TYPE_UNIMPLEMENTED_DEVICE
,
299 .type
= TYPE_UNIMPLEMENTED_DEVICE
,
308 .type
= TYPE_UNIMPLEMENTED_DEVICE
,
317 .type
= TYPE_UNIMPLEMENTED_DEVICE
,
326 .type
= TYPE_UNIMPLEMENTED_DEVICE
,
338 /* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
339 static const bool sse200_irq_is_common
[32] = {
341 /* 6, 7: per-CPU MHU interrupts */
343 /* 13: per-CPU icache interrupt */
349 /* 28, 29: per-CPU CTI interrupts */
350 /* 30, 31: reserved */
353 static const ARMSSEInfo armsse_variants
[] = {
356 .sse_version
= ARMSSE_IOTKIT
,
359 .sys_version
= 0x41743,
363 .has_cachectrl
= false,
364 .has_cpusecctrl
= false,
366 .props
= iotkit_properties
,
367 .devinfo
= iotkit_devices
,
368 .irq_is_common
= sse200_irq_is_common
,
372 .sse_version
= ARMSSE_SSE200
,
375 .sys_version
= 0x22041743,
379 .has_cachectrl
= true,
380 .has_cpusecctrl
= 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 */
393 switch (info
->sse_version
) {
396 sys_config
= deposit32(sys_config
, 0, 4, info
->sram_banks
);
397 sys_config
= deposit32(sys_config
, 4, 4, s
->sram_addr_width
- 12);
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);
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 */
417 g_assert_not_reached();
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
);
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
);
465 name
= g_strdup_printf("%s_nonsec", ppcname
);
466 qdev_pass_gpios(dev_secctl
, armssedev
, name
);
468 name
= g_strdup_printf("%s_ap", ppcname
);
469 qdev_pass_gpios(dev_secctl
, armssedev
, name
);
471 name
= g_strdup_printf("%s_irq_enable", ppcname
);
472 qdev_pass_gpios(dev_secctl
, armssedev
, name
);
474 name
= g_strdup_printf("%s_irq_clear", ppcname
);
475 qdev_pass_gpios(dev_secctl
, armssedev
, 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
,
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);
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
,
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
;
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.
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
);
550 name
= g_strdup_printf("armv7m%d", i
);
551 object_initialize_child(OBJECT(&s
->cluster
[i
]), name
, &s
->armv7m
[i
],
553 qdev_prop_set_string(DEVICE(&s
->armv7m
[i
]), "cpu-type",
554 ARM_CPU_TYPE_NAME("cortex-m33"));
556 name
= g_strdup_printf("arm-sse-cpu-container%d", i
);
557 memory_region_init(&s
->cpu_container
[i
], obj
, name
, UINT64_MAX
);
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
);
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
,
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
);
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
);
613 object_initialize_child(obj
, "mpc-irq-orgate", &s
->mpc_irq_orgate
,
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
);
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
);
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
);
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
],
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
,
658 object_initialize_child(obj
, "sec-resp-splitter", &s
->sec_resp_splitter
,
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
);
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
);
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
);
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
;
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");
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",
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
]);
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,
831 if (!s
->cpu_fpu
[i
]) {
832 if (!object_property_set_bool(cpuobj
, "vfp", false, errp
)) {
836 if (!s
->cpu_dsp
[i
]) {
837 if (!object_property_set_bool(cpuobj
, "dsp", false, errp
)) {
843 memory_region_add_subregion_overlap(&s
->cpu_container
[i
], 0,
844 &s
->container_alias
[i
- 1], -1);
846 memory_region_add_subregion_overlap(&s
->cpu_container
[i
], 0,
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
)) {
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
)) {
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
);
871 gpioname
= g_strdup("EXP_IRQ");
873 gpioname
= g_strdup_printf("EXP_CPU%d_IRQ", i
);
875 qdev_init_gpio_in_named_with_opaque(dev
, armsse_exp_irq
,
877 gpioname
, s
->exp_numirq
);
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
);
889 if (!object_property_set_int(splitter
, "num-lines",
890 info
->num_cpus
, errp
)) {
893 if (!qdev_realize(DEVICE(splitter
), NULL
, errp
)) {
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
)) {
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
)) {
945 if (!qdev_realize(DEVICE(&s
->sec_resp_splitter
), NULL
, errp
)) {
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
);
962 error_propagate(errp
, err
);
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
)) {
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
,
986 if (!qdev_realize(DEVICE(&s
->mpc_irq_orgate
), NULL
, errp
)) {
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,
997 if (!qdev_realize(DEVICE(&s
->nmi_orgate
), NULL
, errp
)) {
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
++) {
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
)) {
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
)) {
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
)) {
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
),
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
)) {
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
)) {
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
)) {
1083 mr
= sysbus_mmio_get_region(sbd
, 0);
1085 g_assert_not_reached();
1088 switch (devinfo
->irq
) {
1092 case 0 ... NUM_SSE_IRQS
- 1:
1093 irq
= armsse_get_common_irq_in(s
, devinfo
->irq
);
1097 irq
= qdev_get_gpio_in(DEVICE(&s
->nmi_orgate
),
1098 devinfo
->irq
- NMI_0
);
1101 g_assert_not_reached();
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]",
1118 object_property_set_link(OBJECT(ppc
), portname
, OBJECT(mr
),
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
++) {
1138 SysBusDevice
*mhu_sbd
= SYS_BUS_DEVICE(&s
->mhu
[i
]);
1140 if (!sysbus_realize(SYS_BUS_DEVICE(&s
->mhu
[i
]), errp
)) {
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
),
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
)) {
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
,
1182 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_ap", i
,
1183 qdev_get_gpio_in_named(dev_apb_ppc0
,
1186 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_irq_enable", 0,
1187 qdev_get_gpio_in_named(dev_apb_ppc0
,
1189 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_irq_clear", 0,
1190 qdev_get_gpio_in_named(dev_apb_ppc0
,
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
)) {
1204 if (!qdev_realize(DEVICE(&s
->ppc_irq_orgate
), NULL
, errp
)) {
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
);
1222 qdev_prop_set_string(DEVICE(&s
->cachectrl
[i
]), "name", name
);
1224 qdev_prop_set_uint64(DEVICE(&s
->cachectrl
[i
]), "size", 0x1000);
1225 if (!sysbus_realize(SYS_BUS_DEVICE(&s
->cachectrl
[i
]), errp
)) {
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
);
1238 qdev_prop_set_string(DEVICE(&s
->cpusecctrl
[i
]), "name", name
);
1240 qdev_prop_set_uint64(DEVICE(&s
->cpusecctrl
[i
]), "size", 0x1000);
1241 if (!sysbus_realize(SYS_BUS_DEVICE(&s
->cpusecctrl
[i
]), errp
)) {
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
++) {
1253 qdev_prop_set_uint32(DEVICE(&s
->cpuid
[i
]), "CPUID", i
);
1254 if (!sysbus_realize(SYS_BUS_DEVICE(&s
->cpuid
[i
]), errp
)) {
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
)) {
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
,
1271 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_ap", 0,
1272 qdev_get_gpio_in_named(dev_apb_ppc1
,
1274 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_irq_enable", 0,
1275 qdev_get_gpio_in_named(dev_apb_ppc1
,
1277 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_irq_clear", 0,
1278 qdev_get_gpio_in_named(dev_apb_ppc1
,
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
) {
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
)) {
1307 if (!qdev_realize(DEVICE(splitter
), NULL
, errp
)) {
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
);
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
);
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));
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,
1351 if (!qdev_realize(DEVICE(splitter
), NULL
, errp
)) {
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
));
1362 /* Splitter input is from our own MPC */
1363 qdev_connect_gpio_out_named(DEVICE(&s
->mpc
[i
- IOTS_NUM_EXP_MPC
]),
1365 qdev_get_gpio_in(dev_splitter
, 0));
1366 qdev_connect_gpio_out(dev_splitter
, 0,
1367 qdev_get_gpio_in_named(dev_secctl
,
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",
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;
1420 static const VMStateDescription armsse_vmstate
= {
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
);
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
;
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
,
1461 .interfaces
= (InterfaceInfo
[]) {
1462 { TYPE_IDAU_INTERFACE
},
1467 static void armsse_register_types(void)
1471 type_register_static(&armsse_info
);
1473 for (i
= 0; i
< ARRAY_SIZE(armsse_variants
); i
++) {
1475 .name
= armsse_variants
[i
].name
,
1476 .parent
= TYPE_ARM_SSE
,
1477 .class_init
= armsse_class_init
,
1478 .class_data
= (void *)&armsse_variants
[i
],
1484 type_init(armsse_register_types
);