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 "qapi/error.h"
16 #include "hw/sysbus.h"
17 #include "hw/registerfields.h"
18 #include "hw/arm/armsse.h"
19 #include "hw/arm/arm.h"
27 static const ARMSSEInfo armsse_variants
[] = {
35 /* Clock frequency in HZ of the 32KHz "slow clock" */
36 #define S32KCLK (32 * 1000)
38 /* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
39 static bool irq_is_common
[32] = {
41 /* 6, 7: per-CPU MHU interrupts */
43 /* 13: per-CPU icache interrupt */
49 /* 28, 29: per-CPU CTI interrupts */
50 /* 30, 31: reserved */
53 /* Create an alias region of @size bytes starting at @base
54 * which mirrors the memory starting at @orig.
56 static void make_alias(ARMSSE
*s
, MemoryRegion
*mr
, const char *name
,
57 hwaddr base
, hwaddr size
, hwaddr orig
)
59 memory_region_init_alias(mr
, NULL
, name
, &s
->container
, orig
, size
);
60 /* The alias is even lower priority than unimplemented_device regions */
61 memory_region_add_subregion_overlap(&s
->container
, base
, mr
, -1500);
64 static void irq_status_forwarder(void *opaque
, int n
, int level
)
66 qemu_irq destirq
= opaque
;
68 qemu_set_irq(destirq
, level
);
71 static void nsccfg_handler(void *opaque
, int n
, int level
)
73 ARMSSE
*s
= ARMSSE(opaque
);
78 static void armsse_forward_ppc(ARMSSE
*s
, const char *ppcname
, int ppcnum
)
80 /* Each of the 4 AHB and 4 APB PPCs that might be present in a
81 * system using the ARMSSE has a collection of control lines which
82 * are provided by the security controller and which we want to
83 * expose as control lines on the ARMSSE device itself, so the
84 * code using the ARMSSE can wire them up to the PPCs.
86 SplitIRQ
*splitter
= &s
->ppc_irq_splitter
[ppcnum
];
87 DeviceState
*armssedev
= DEVICE(s
);
88 DeviceState
*dev_secctl
= DEVICE(&s
->secctl
);
89 DeviceState
*dev_splitter
= DEVICE(splitter
);
92 name
= g_strdup_printf("%s_nonsec", ppcname
);
93 qdev_pass_gpios(dev_secctl
, armssedev
, name
);
95 name
= g_strdup_printf("%s_ap", ppcname
);
96 qdev_pass_gpios(dev_secctl
, armssedev
, name
);
98 name
= g_strdup_printf("%s_irq_enable", ppcname
);
99 qdev_pass_gpios(dev_secctl
, armssedev
, name
);
101 name
= g_strdup_printf("%s_irq_clear", ppcname
);
102 qdev_pass_gpios(dev_secctl
, armssedev
, name
);
105 /* irq_status is a little more tricky, because we need to
106 * split it so we can send it both to the security controller
107 * and to our OR gate for the NVIC interrupt line.
108 * Connect up the splitter's outputs, and create a GPIO input
109 * which will pass the line state to the input splitter.
111 name
= g_strdup_printf("%s_irq_status", ppcname
);
112 qdev_connect_gpio_out(dev_splitter
, 0,
113 qdev_get_gpio_in_named(dev_secctl
,
115 qdev_connect_gpio_out(dev_splitter
, 1,
116 qdev_get_gpio_in(DEVICE(&s
->ppc_irq_orgate
), ppcnum
));
117 s
->irq_status_in
[ppcnum
] = qdev_get_gpio_in(dev_splitter
, 0);
118 qdev_init_gpio_in_named_with_opaque(armssedev
, irq_status_forwarder
,
119 s
->irq_status_in
[ppcnum
], name
, 1);
123 static void armsse_forward_sec_resp_cfg(ARMSSE
*s
)
125 /* Forward the 3rd output from the splitter device as a
126 * named GPIO output of the armsse object.
128 DeviceState
*dev
= DEVICE(s
);
129 DeviceState
*dev_splitter
= DEVICE(&s
->sec_resp_splitter
);
131 qdev_init_gpio_out_named(dev
, &s
->sec_resp_cfg
, "sec_resp_cfg", 1);
132 s
->sec_resp_cfg_in
= qemu_allocate_irq(irq_status_forwarder
,
134 qdev_connect_gpio_out(dev_splitter
, 2, s
->sec_resp_cfg_in
);
137 static void armsse_init(Object
*obj
)
139 ARMSSE
*s
= ARMSSE(obj
);
140 ARMSSEClass
*asc
= ARMSSE_GET_CLASS(obj
);
141 const ARMSSEInfo
*info
= asc
->info
;
144 assert(info
->sram_banks
<= MAX_SRAM_BANKS
);
145 assert(info
->num_cpus
<= SSE_MAX_CPUS
);
147 memory_region_init(&s
->container
, obj
, "armsse-container", UINT64_MAX
);
149 for (i
= 0; i
< info
->num_cpus
; i
++) {
150 char *name
= g_strdup_printf("armv7m%d", i
);
151 sysbus_init_child_obj(obj
, name
, &s
->armv7m
[i
], sizeof(s
->armv7m
),
153 qdev_prop_set_string(DEVICE(&s
->armv7m
[i
]), "cpu-type",
154 ARM_CPU_TYPE_NAME("cortex-m33"));
156 name
= g_strdup_printf("arm-sse-cpu-container%d", i
);
157 memory_region_init(&s
->cpu_container
[i
], obj
, name
, UINT64_MAX
);
160 name
= g_strdup_printf("arm-sse-container-alias%d", i
);
161 memory_region_init_alias(&s
->container_alias
[i
- 1], obj
,
162 name
, &s
->container
, 0, UINT64_MAX
);
167 sysbus_init_child_obj(obj
, "secctl", &s
->secctl
, sizeof(s
->secctl
),
169 sysbus_init_child_obj(obj
, "apb-ppc0", &s
->apb_ppc0
, sizeof(s
->apb_ppc0
),
171 sysbus_init_child_obj(obj
, "apb-ppc1", &s
->apb_ppc1
, sizeof(s
->apb_ppc1
),
173 for (i
= 0; i
< info
->sram_banks
; i
++) {
174 char *name
= g_strdup_printf("mpc%d", i
);
175 sysbus_init_child_obj(obj
, name
, &s
->mpc
[i
],
176 sizeof(s
->mpc
[i
]), TYPE_TZ_MPC
);
179 object_initialize_child(obj
, "mpc-irq-orgate", &s
->mpc_irq_orgate
,
180 sizeof(s
->mpc_irq_orgate
), TYPE_OR_IRQ
,
183 for (i
= 0; i
< IOTS_NUM_EXP_MPC
+ info
->sram_banks
; i
++) {
184 char *name
= g_strdup_printf("mpc-irq-splitter-%d", i
);
185 SplitIRQ
*splitter
= &s
->mpc_irq_splitter
[i
];
187 object_initialize_child(obj
, name
, splitter
, sizeof(*splitter
),
188 TYPE_SPLIT_IRQ
, &error_abort
, NULL
);
191 sysbus_init_child_obj(obj
, "timer0", &s
->timer0
, sizeof(s
->timer0
),
192 TYPE_CMSDK_APB_TIMER
);
193 sysbus_init_child_obj(obj
, "timer1", &s
->timer1
, sizeof(s
->timer1
),
194 TYPE_CMSDK_APB_TIMER
);
195 sysbus_init_child_obj(obj
, "s32ktimer", &s
->s32ktimer
, sizeof(s
->s32ktimer
),
196 TYPE_CMSDK_APB_TIMER
);
197 sysbus_init_child_obj(obj
, "dualtimer", &s
->dualtimer
, sizeof(s
->dualtimer
),
198 TYPE_CMSDK_APB_DUALTIMER
);
199 sysbus_init_child_obj(obj
, "s32kwatchdog", &s
->s32kwatchdog
,
200 sizeof(s
->s32kwatchdog
), TYPE_CMSDK_APB_WATCHDOG
);
201 sysbus_init_child_obj(obj
, "nswatchdog", &s
->nswatchdog
,
202 sizeof(s
->nswatchdog
), TYPE_CMSDK_APB_WATCHDOG
);
203 sysbus_init_child_obj(obj
, "swatchdog", &s
->swatchdog
,
204 sizeof(s
->swatchdog
), TYPE_CMSDK_APB_WATCHDOG
);
205 sysbus_init_child_obj(obj
, "armsse-sysctl", &s
->sysctl
,
206 sizeof(s
->sysctl
), TYPE_IOTKIT_SYSCTL
);
207 sysbus_init_child_obj(obj
, "armsse-sysinfo", &s
->sysinfo
,
208 sizeof(s
->sysinfo
), TYPE_IOTKIT_SYSINFO
);
209 object_initialize_child(obj
, "nmi-orgate", &s
->nmi_orgate
,
210 sizeof(s
->nmi_orgate
), TYPE_OR_IRQ
,
212 object_initialize_child(obj
, "ppc-irq-orgate", &s
->ppc_irq_orgate
,
213 sizeof(s
->ppc_irq_orgate
), TYPE_OR_IRQ
,
215 object_initialize_child(obj
, "sec-resp-splitter", &s
->sec_resp_splitter
,
216 sizeof(s
->sec_resp_splitter
), TYPE_SPLIT_IRQ
,
218 for (i
= 0; i
< ARRAY_SIZE(s
->ppc_irq_splitter
); i
++) {
219 char *name
= g_strdup_printf("ppc-irq-splitter-%d", i
);
220 SplitIRQ
*splitter
= &s
->ppc_irq_splitter
[i
];
222 object_initialize_child(obj
, name
, splitter
, sizeof(*splitter
),
223 TYPE_SPLIT_IRQ
, &error_abort
, NULL
);
226 if (info
->num_cpus
> 1) {
227 for (i
= 0; i
< ARRAY_SIZE(s
->cpu_irq_splitter
); i
++) {
228 if (irq_is_common
[i
]) {
229 char *name
= g_strdup_printf("cpu-irq-splitter%d", i
);
230 SplitIRQ
*splitter
= &s
->cpu_irq_splitter
[i
];
232 object_initialize_child(obj
, name
, splitter
, sizeof(*splitter
),
233 TYPE_SPLIT_IRQ
, &error_abort
, NULL
);
240 static void armsse_exp_irq(void *opaque
, int n
, int level
)
242 qemu_irq
*irqarray
= opaque
;
244 qemu_set_irq(irqarray
[n
], level
);
247 static void armsse_mpcexp_status(void *opaque
, int n
, int level
)
249 ARMSSE
*s
= ARMSSE(opaque
);
250 qemu_set_irq(s
->mpcexp_status_in
[n
], level
);
253 static qemu_irq
armsse_get_common_irq_in(ARMSSE
*s
, int irqno
)
256 * Return a qemu_irq which can be used to signal IRQ n to
257 * all CPUs in the SSE.
259 ARMSSEClass
*asc
= ARMSSE_GET_CLASS(s
);
260 const ARMSSEInfo
*info
= asc
->info
;
262 assert(irq_is_common
[irqno
]);
264 if (info
->num_cpus
== 1) {
265 /* Only one CPU -- just connect directly to it */
266 return qdev_get_gpio_in(DEVICE(&s
->armv7m
[0]), irqno
);
268 /* Connect to the splitter which feeds all CPUs */
269 return qdev_get_gpio_in(DEVICE(&s
->cpu_irq_splitter
[irqno
]), 0);
273 static void armsse_realize(DeviceState
*dev
, Error
**errp
)
275 ARMSSE
*s
= ARMSSE(dev
);
276 ARMSSEClass
*asc
= ARMSSE_GET_CLASS(dev
);
277 const ARMSSEInfo
*info
= asc
->info
;
281 SysBusDevice
*sbd_apb_ppc0
;
282 SysBusDevice
*sbd_secctl
;
283 DeviceState
*dev_apb_ppc0
;
284 DeviceState
*dev_apb_ppc1
;
285 DeviceState
*dev_secctl
;
286 DeviceState
*dev_splitter
;
287 uint32_t addr_width_max
;
289 if (!s
->board_memory
) {
290 error_setg(errp
, "memory property was not set");
294 if (!s
->mainclk_frq
) {
295 error_setg(errp
, "MAINCLK property was not set");
299 /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
300 assert(is_power_of_2(info
->sram_banks
));
301 addr_width_max
= 24 - ctz32(info
->sram_banks
);
302 if (s
->sram_addr_width
< 1 || s
->sram_addr_width
> addr_width_max
) {
303 error_setg(errp
, "SRAM_ADDR_WIDTH must be between 1 and %d",
308 /* Handling of which devices should be available only to secure
309 * code is usually done differently for M profile than for A profile.
310 * Instead of putting some devices only into the secure address space,
311 * devices exist in both address spaces but with hard-wired security
312 * permissions that will cause the CPU to fault for non-secure accesses.
314 * The ARMSSE has an IDAU (Implementation Defined Access Unit),
315 * which specifies hard-wired security permissions for different
316 * areas of the physical address space. For the ARMSSE IDAU, the
317 * top 4 bits of the physical address are the IDAU region ID, and
318 * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
319 * region, otherwise it is an S region.
321 * The various devices and RAMs are generally all mapped twice,
322 * once into a region that the IDAU defines as secure and once
323 * into a non-secure region. They sit behind either a Memory
324 * Protection Controller (for RAM) or a Peripheral Protection
325 * Controller (for devices), which allow a more fine grained
326 * configuration of whether non-secure accesses are permitted.
328 * (The other place that guest software can configure security
329 * permissions is in the architected SAU (Security Attribution
330 * Unit), which is entirely inside the CPU. The IDAU can upgrade
331 * the security attributes for a region to more restrictive than
332 * the SAU specifies, but cannot downgrade them.)
334 * 0x10000000..0x1fffffff alias of 0x00000000..0x0fffffff
335 * 0x20000000..0x2007ffff 32KB FPGA block RAM
336 * 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff
337 * 0x40000000..0x4000ffff base peripheral region 1
338 * 0x40010000..0x4001ffff CPU peripherals (none for ARMSSE)
339 * 0x40020000..0x4002ffff system control element peripherals
340 * 0x40080000..0x400fffff base peripheral region 2
341 * 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
344 memory_region_add_subregion_overlap(&s
->container
, 0, s
->board_memory
, -2);
346 for (i
= 0; i
< info
->num_cpus
; i
++) {
347 DeviceState
*cpudev
= DEVICE(&s
->armv7m
[i
]);
348 Object
*cpuobj
= OBJECT(&s
->armv7m
[i
]);
352 qdev_prop_set_uint32(cpudev
, "num-irq", s
->exp_numirq
+ 32);
354 * In real hardware the initial Secure VTOR is set from the INITSVTOR0
355 * register in the IoT Kit System Control Register block, and the
356 * initial value of that is in turn specifiable by the FPGA that
357 * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
358 * and simply set the CPU's init-svtor to the IoT Kit default value.
359 * In SSE-200 the situation is similar, except that the default value
360 * is a reset-time signal input. Typically a board using the SSE-200
361 * will have a system control processor whose boot firmware initializes
362 * the INITSVTOR* registers before powering up the CPUs in any case,
363 * so the hardware's default value doesn't matter. QEMU doesn't emulate
364 * the control processor, so instead we behave in the way that the
365 * firmware does. All boards currently known about have firmware that
366 * sets the INITSVTOR0 and INITSVTOR1 registers to 0x10000000, like the
367 * IoTKit default. We can make this more configurable if necessary.
369 qdev_prop_set_uint32(cpudev
, "init-svtor", 0x10000000);
371 * Start all CPUs except CPU0 powered down. In real hardware it is
372 * a configurable property of the SSE-200 which CPUs start powered up
373 * (via the CPUWAIT0_RST and CPUWAIT1_RST parameters), but since all
374 * the boards we care about start CPU0 and leave CPU1 powered off,
375 * we hard-code that for now. We can add QOM properties for this
376 * later if necessary.
379 object_property_set_bool(cpuobj
, true, "start-powered-off", &err
);
381 error_propagate(errp
, err
);
387 memory_region_add_subregion_overlap(&s
->cpu_container
[i
], 0,
388 &s
->container_alias
[i
- 1], -1);
390 memory_region_add_subregion_overlap(&s
->cpu_container
[i
], 0,
393 object_property_set_link(cpuobj
, OBJECT(&s
->cpu_container
[i
]),
396 error_propagate(errp
, err
);
399 object_property_set_link(cpuobj
, OBJECT(s
), "idau", &err
);
401 error_propagate(errp
, err
);
404 object_property_set_bool(cpuobj
, true, "realized", &err
);
406 error_propagate(errp
, err
);
410 /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
411 s
->exp_irqs
[i
] = g_new(qemu_irq
, s
->exp_numirq
);
412 for (j
= 0; j
< s
->exp_numirq
; j
++) {
413 s
->exp_irqs
[i
][j
] = qdev_get_gpio_in(cpudev
, i
+ 32);
416 gpioname
= g_strdup("EXP_IRQ");
418 gpioname
= g_strdup_printf("EXP_CPU%d_IRQ", i
);
420 qdev_init_gpio_in_named_with_opaque(dev
, armsse_exp_irq
,
422 gpioname
, s
->exp_numirq
);
426 /* Wire up the splitters that connect common IRQs to all CPUs */
427 if (info
->num_cpus
> 1) {
428 for (i
= 0; i
< ARRAY_SIZE(s
->cpu_irq_splitter
); i
++) {
429 if (irq_is_common
[i
]) {
430 Object
*splitter
= OBJECT(&s
->cpu_irq_splitter
[i
]);
431 DeviceState
*devs
= DEVICE(splitter
);
434 object_property_set_int(splitter
, info
->num_cpus
,
437 error_propagate(errp
, err
);
440 object_property_set_bool(splitter
, true, "realized", &err
);
442 error_propagate(errp
, err
);
445 for (cpunum
= 0; cpunum
< info
->num_cpus
; cpunum
++) {
446 DeviceState
*cpudev
= DEVICE(&s
->armv7m
[cpunum
]);
448 qdev_connect_gpio_out(devs
, cpunum
,
449 qdev_get_gpio_in(cpudev
, i
));
455 /* Set up the big aliases first */
456 make_alias(s
, &s
->alias1
, "alias 1", 0x10000000, 0x10000000, 0x00000000);
457 make_alias(s
, &s
->alias2
, "alias 2", 0x30000000, 0x10000000, 0x20000000);
458 /* The 0x50000000..0x5fffffff region is not a pure alias: it has
459 * a few extra devices that only appear there (generally the
460 * control interfaces for the protection controllers).
461 * We implement this by mapping those devices over the top of this
462 * alias MR at a higher priority.
464 make_alias(s
, &s
->alias3
, "alias 3", 0x50000000, 0x10000000, 0x40000000);
467 /* Security controller */
468 object_property_set_bool(OBJECT(&s
->secctl
), true, "realized", &err
);
470 error_propagate(errp
, err
);
473 sbd_secctl
= SYS_BUS_DEVICE(&s
->secctl
);
474 dev_secctl
= DEVICE(&s
->secctl
);
475 sysbus_mmio_map(sbd_secctl
, 0, 0x50080000);
476 sysbus_mmio_map(sbd_secctl
, 1, 0x40080000);
478 s
->nsc_cfg_in
= qemu_allocate_irq(nsccfg_handler
, s
, 1);
479 qdev_connect_gpio_out_named(dev_secctl
, "nsc_cfg", 0, s
->nsc_cfg_in
);
481 /* The sec_resp_cfg output from the security controller must be split into
482 * multiple lines, one for each of the PPCs within the ARMSSE and one
483 * that will be an output from the ARMSSE to the system.
485 object_property_set_int(OBJECT(&s
->sec_resp_splitter
), 3,
488 error_propagate(errp
, err
);
491 object_property_set_bool(OBJECT(&s
->sec_resp_splitter
), true,
494 error_propagate(errp
, err
);
497 dev_splitter
= DEVICE(&s
->sec_resp_splitter
);
498 qdev_connect_gpio_out_named(dev_secctl
, "sec_resp_cfg", 0,
499 qdev_get_gpio_in(dev_splitter
, 0));
501 /* Each SRAM bank lives behind its own Memory Protection Controller */
502 for (i
= 0; i
< info
->sram_banks
; i
++) {
503 char *ramname
= g_strdup_printf("armsse.sram%d", i
);
504 SysBusDevice
*sbd_mpc
;
505 uint32_t sram_bank_size
= 1 << s
->sram_addr_width
;
507 memory_region_init_ram(&s
->sram
[i
], NULL
, ramname
,
508 sram_bank_size
, &err
);
511 error_propagate(errp
, err
);
514 object_property_set_link(OBJECT(&s
->mpc
[i
]), OBJECT(&s
->sram
[i
]),
517 error_propagate(errp
, err
);
520 object_property_set_bool(OBJECT(&s
->mpc
[i
]), true, "realized", &err
);
522 error_propagate(errp
, err
);
525 /* Map the upstream end of the MPC into the right place... */
526 sbd_mpc
= SYS_BUS_DEVICE(&s
->mpc
[i
]);
527 memory_region_add_subregion(&s
->container
,
528 0x20000000 + i
* sram_bank_size
,
529 sysbus_mmio_get_region(sbd_mpc
, 1));
530 /* ...and its register interface */
531 memory_region_add_subregion(&s
->container
, 0x50083000 + i
* 0x1000,
532 sysbus_mmio_get_region(sbd_mpc
, 0));
535 /* We must OR together lines from the MPC splitters to go to the NVIC */
536 object_property_set_int(OBJECT(&s
->mpc_irq_orgate
),
537 IOTS_NUM_EXP_MPC
+ info
->sram_banks
,
540 error_propagate(errp
, err
);
543 object_property_set_bool(OBJECT(&s
->mpc_irq_orgate
), true,
546 error_propagate(errp
, err
);
549 qdev_connect_gpio_out(DEVICE(&s
->mpc_irq_orgate
), 0,
550 armsse_get_common_irq_in(s
, 9));
552 /* Devices behind APB PPC0:
555 * 0x40002000: dual timer
556 * We must configure and realize each downstream device and connect
557 * it to the appropriate PPC port; then we can realize the PPC and
558 * map its upstream ends to the right place in the container.
560 qdev_prop_set_uint32(DEVICE(&s
->timer0
), "pclk-frq", s
->mainclk_frq
);
561 object_property_set_bool(OBJECT(&s
->timer0
), true, "realized", &err
);
563 error_propagate(errp
, err
);
566 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->timer0
), 0,
567 armsse_get_common_irq_in(s
, 3));
568 mr
= sysbus_mmio_get_region(SYS_BUS_DEVICE(&s
->timer0
), 0);
569 object_property_set_link(OBJECT(&s
->apb_ppc0
), OBJECT(mr
), "port[0]", &err
);
571 error_propagate(errp
, err
);
575 qdev_prop_set_uint32(DEVICE(&s
->timer1
), "pclk-frq", s
->mainclk_frq
);
576 object_property_set_bool(OBJECT(&s
->timer1
), true, "realized", &err
);
578 error_propagate(errp
, err
);
581 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->timer1
), 0,
582 armsse_get_common_irq_in(s
, 4));
583 mr
= sysbus_mmio_get_region(SYS_BUS_DEVICE(&s
->timer1
), 0);
584 object_property_set_link(OBJECT(&s
->apb_ppc0
), OBJECT(mr
), "port[1]", &err
);
586 error_propagate(errp
, err
);
591 qdev_prop_set_uint32(DEVICE(&s
->dualtimer
), "pclk-frq", s
->mainclk_frq
);
592 object_property_set_bool(OBJECT(&s
->dualtimer
), true, "realized", &err
);
594 error_propagate(errp
, err
);
597 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->dualtimer
), 0,
598 armsse_get_common_irq_in(s
, 5));
599 mr
= sysbus_mmio_get_region(SYS_BUS_DEVICE(&s
->dualtimer
), 0);
600 object_property_set_link(OBJECT(&s
->apb_ppc0
), OBJECT(mr
), "port[2]", &err
);
602 error_propagate(errp
, err
);
606 object_property_set_bool(OBJECT(&s
->apb_ppc0
), true, "realized", &err
);
608 error_propagate(errp
, err
);
612 sbd_apb_ppc0
= SYS_BUS_DEVICE(&s
->apb_ppc0
);
613 dev_apb_ppc0
= DEVICE(&s
->apb_ppc0
);
615 mr
= sysbus_mmio_get_region(sbd_apb_ppc0
, 0);
616 memory_region_add_subregion(&s
->container
, 0x40000000, mr
);
617 mr
= sysbus_mmio_get_region(sbd_apb_ppc0
, 1);
618 memory_region_add_subregion(&s
->container
, 0x40001000, mr
);
619 mr
= sysbus_mmio_get_region(sbd_apb_ppc0
, 2);
620 memory_region_add_subregion(&s
->container
, 0x40002000, mr
);
621 for (i
= 0; i
< IOTS_APB_PPC0_NUM_PORTS
; i
++) {
622 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_nonsec", i
,
623 qdev_get_gpio_in_named(dev_apb_ppc0
,
625 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_ap", i
,
626 qdev_get_gpio_in_named(dev_apb_ppc0
,
629 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_irq_enable", 0,
630 qdev_get_gpio_in_named(dev_apb_ppc0
,
632 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_irq_clear", 0,
633 qdev_get_gpio_in_named(dev_apb_ppc0
,
635 qdev_connect_gpio_out(dev_splitter
, 0,
636 qdev_get_gpio_in_named(dev_apb_ppc0
,
639 /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
640 * ones) are sent individually to the security controller, and also
641 * ORed together to give a single combined PPC interrupt to the NVIC.
643 object_property_set_int(OBJECT(&s
->ppc_irq_orgate
),
644 NUM_PPCS
, "num-lines", &err
);
646 error_propagate(errp
, err
);
649 object_property_set_bool(OBJECT(&s
->ppc_irq_orgate
), true,
652 error_propagate(errp
, err
);
655 qdev_connect_gpio_out(DEVICE(&s
->ppc_irq_orgate
), 0,
656 armsse_get_common_irq_in(s
, 10));
658 /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
660 /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
661 /* Devices behind APB PPC1:
662 * 0x4002f000: S32K timer
664 qdev_prop_set_uint32(DEVICE(&s
->s32ktimer
), "pclk-frq", S32KCLK
);
665 object_property_set_bool(OBJECT(&s
->s32ktimer
), true, "realized", &err
);
667 error_propagate(errp
, err
);
670 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->s32ktimer
), 0,
671 armsse_get_common_irq_in(s
, 2));
672 mr
= sysbus_mmio_get_region(SYS_BUS_DEVICE(&s
->s32ktimer
), 0);
673 object_property_set_link(OBJECT(&s
->apb_ppc1
), OBJECT(mr
), "port[0]", &err
);
675 error_propagate(errp
, err
);
679 object_property_set_bool(OBJECT(&s
->apb_ppc1
), true, "realized", &err
);
681 error_propagate(errp
, err
);
684 mr
= sysbus_mmio_get_region(SYS_BUS_DEVICE(&s
->apb_ppc1
), 0);
685 memory_region_add_subregion(&s
->container
, 0x4002f000, mr
);
687 dev_apb_ppc1
= DEVICE(&s
->apb_ppc1
);
688 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_nonsec", 0,
689 qdev_get_gpio_in_named(dev_apb_ppc1
,
691 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_ap", 0,
692 qdev_get_gpio_in_named(dev_apb_ppc1
,
694 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_irq_enable", 0,
695 qdev_get_gpio_in_named(dev_apb_ppc1
,
697 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_irq_clear", 0,
698 qdev_get_gpio_in_named(dev_apb_ppc1
,
700 qdev_connect_gpio_out(dev_splitter
, 1,
701 qdev_get_gpio_in_named(dev_apb_ppc1
,
704 object_property_set_bool(OBJECT(&s
->sysinfo
), true, "realized", &err
);
706 error_propagate(errp
, err
);
709 /* System information registers */
710 sysbus_mmio_map(SYS_BUS_DEVICE(&s
->sysinfo
), 0, 0x40020000);
711 /* System control registers */
712 object_property_set_bool(OBJECT(&s
->sysctl
), true, "realized", &err
);
714 error_propagate(errp
, err
);
717 sysbus_mmio_map(SYS_BUS_DEVICE(&s
->sysctl
), 0, 0x50021000);
719 /* This OR gate wires together outputs from the secure watchdogs to NMI */
720 object_property_set_int(OBJECT(&s
->nmi_orgate
), 2, "num-lines", &err
);
722 error_propagate(errp
, err
);
725 object_property_set_bool(OBJECT(&s
->nmi_orgate
), true, "realized", &err
);
727 error_propagate(errp
, err
);
730 qdev_connect_gpio_out(DEVICE(&s
->nmi_orgate
), 0,
731 qdev_get_gpio_in_named(DEVICE(&s
->armv7m
), "NMI", 0));
733 qdev_prop_set_uint32(DEVICE(&s
->s32kwatchdog
), "wdogclk-frq", S32KCLK
);
734 object_property_set_bool(OBJECT(&s
->s32kwatchdog
), true, "realized", &err
);
736 error_propagate(errp
, err
);
739 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->s32kwatchdog
), 0,
740 qdev_get_gpio_in(DEVICE(&s
->nmi_orgate
), 0));
741 sysbus_mmio_map(SYS_BUS_DEVICE(&s
->s32kwatchdog
), 0, 0x5002e000);
743 /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
745 qdev_prop_set_uint32(DEVICE(&s
->nswatchdog
), "wdogclk-frq", s
->mainclk_frq
);
746 object_property_set_bool(OBJECT(&s
->nswatchdog
), true, "realized", &err
);
748 error_propagate(errp
, err
);
751 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->nswatchdog
), 0,
752 armsse_get_common_irq_in(s
, 1));
753 sysbus_mmio_map(SYS_BUS_DEVICE(&s
->nswatchdog
), 0, 0x40081000);
755 qdev_prop_set_uint32(DEVICE(&s
->swatchdog
), "wdogclk-frq", s
->mainclk_frq
);
756 object_property_set_bool(OBJECT(&s
->swatchdog
), true, "realized", &err
);
758 error_propagate(errp
, err
);
761 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->swatchdog
), 0,
762 qdev_get_gpio_in(DEVICE(&s
->nmi_orgate
), 1));
763 sysbus_mmio_map(SYS_BUS_DEVICE(&s
->swatchdog
), 0, 0x50081000);
765 for (i
= 0; i
< ARRAY_SIZE(s
->ppc_irq_splitter
); i
++) {
766 Object
*splitter
= OBJECT(&s
->ppc_irq_splitter
[i
]);
768 object_property_set_int(splitter
, 2, "num-lines", &err
);
770 error_propagate(errp
, err
);
773 object_property_set_bool(splitter
, true, "realized", &err
);
775 error_propagate(errp
, err
);
780 for (i
= 0; i
< IOTS_NUM_AHB_EXP_PPC
; i
++) {
781 char *ppcname
= g_strdup_printf("ahb_ppcexp%d", i
);
783 armsse_forward_ppc(s
, ppcname
, i
);
787 for (i
= 0; i
< IOTS_NUM_APB_EXP_PPC
; i
++) {
788 char *ppcname
= g_strdup_printf("apb_ppcexp%d", i
);
790 armsse_forward_ppc(s
, ppcname
, i
+ IOTS_NUM_AHB_EXP_PPC
);
794 for (i
= NUM_EXTERNAL_PPCS
; i
< NUM_PPCS
; i
++) {
795 /* Wire up IRQ splitter for internal PPCs */
796 DeviceState
*devs
= DEVICE(&s
->ppc_irq_splitter
[i
]);
797 char *gpioname
= g_strdup_printf("apb_ppc%d_irq_status",
798 i
- NUM_EXTERNAL_PPCS
);
799 TZPPC
*ppc
= (i
== NUM_EXTERNAL_PPCS
) ? &s
->apb_ppc0
: &s
->apb_ppc1
;
801 qdev_connect_gpio_out(devs
, 0,
802 qdev_get_gpio_in_named(dev_secctl
, gpioname
, 0));
803 qdev_connect_gpio_out(devs
, 1,
804 qdev_get_gpio_in(DEVICE(&s
->ppc_irq_orgate
), i
));
805 qdev_connect_gpio_out_named(DEVICE(ppc
), "irq", 0,
806 qdev_get_gpio_in(devs
, 0));
810 /* Wire up the splitters for the MPC IRQs */
811 for (i
= 0; i
< IOTS_NUM_EXP_MPC
+ info
->sram_banks
; i
++) {
812 SplitIRQ
*splitter
= &s
->mpc_irq_splitter
[i
];
813 DeviceState
*dev_splitter
= DEVICE(splitter
);
815 object_property_set_int(OBJECT(splitter
), 2, "num-lines", &err
);
817 error_propagate(errp
, err
);
820 object_property_set_bool(OBJECT(splitter
), true, "realized", &err
);
822 error_propagate(errp
, err
);
826 if (i
< IOTS_NUM_EXP_MPC
) {
827 /* Splitter input is from GPIO input line */
828 s
->mpcexp_status_in
[i
] = qdev_get_gpio_in(dev_splitter
, 0);
829 qdev_connect_gpio_out(dev_splitter
, 0,
830 qdev_get_gpio_in_named(dev_secctl
,
831 "mpcexp_status", i
));
833 /* Splitter input is from our own MPC */
834 qdev_connect_gpio_out_named(DEVICE(&s
->mpc
[i
- IOTS_NUM_EXP_MPC
]),
836 qdev_get_gpio_in(dev_splitter
, 0));
837 qdev_connect_gpio_out(dev_splitter
, 0,
838 qdev_get_gpio_in_named(dev_secctl
,
842 qdev_connect_gpio_out(dev_splitter
, 1,
843 qdev_get_gpio_in(DEVICE(&s
->mpc_irq_orgate
), i
));
845 /* Create GPIO inputs which will pass the line state for our
846 * mpcexp_irq inputs to the correct splitter devices.
848 qdev_init_gpio_in_named(dev
, armsse_mpcexp_status
, "mpcexp_status",
851 armsse_forward_sec_resp_cfg(s
);
853 /* Forward the MSC related signals */
854 qdev_pass_gpios(dev_secctl
, dev
, "mscexp_status");
855 qdev_pass_gpios(dev_secctl
, dev
, "mscexp_clear");
856 qdev_pass_gpios(dev_secctl
, dev
, "mscexp_ns");
857 qdev_connect_gpio_out_named(dev_secctl
, "msc_irq", 0,
858 armsse_get_common_irq_in(s
, 11));
861 * Expose our container region to the board model; this corresponds
862 * to the AHB Slave Expansion ports which allow bus master devices
863 * (eg DMA controllers) in the board model to make transactions into
864 * devices in the ARMSSE.
866 sysbus_init_mmio(SYS_BUS_DEVICE(s
), &s
->container
);
868 system_clock_scale
= NANOSECONDS_PER_SECOND
/ s
->mainclk_frq
;
871 static void armsse_idau_check(IDAUInterface
*ii
, uint32_t address
,
872 int *iregion
, bool *exempt
, bool *ns
, bool *nsc
)
875 * For ARMSSE systems the IDAU responses are simple logical functions
876 * of the address bits. The NSC attribute is guest-adjustable via the
877 * NSCCFG register in the security controller.
879 ARMSSE
*s
= ARMSSE(ii
);
880 int region
= extract32(address
, 28, 4);
883 *nsc
= (region
== 1 && (s
->nsccfg
& 1)) || (region
== 3 && (s
->nsccfg
& 2));
884 /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
885 *exempt
= (address
& 0xeff00000) == 0xe0000000;
889 static const VMStateDescription armsse_vmstate
= {
892 .minimum_version_id
= 1,
893 .fields
= (VMStateField
[]) {
894 VMSTATE_UINT32(nsccfg
, ARMSSE
),
895 VMSTATE_END_OF_LIST()
899 static Property armsse_properties
[] = {
900 DEFINE_PROP_LINK("memory", ARMSSE
, board_memory
, TYPE_MEMORY_REGION
,
902 DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE
, exp_numirq
, 64),
903 DEFINE_PROP_UINT32("MAINCLK", ARMSSE
, mainclk_frq
, 0),
904 DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE
, sram_addr_width
, 15),
905 DEFINE_PROP_END_OF_LIST()
908 static void armsse_reset(DeviceState
*dev
)
910 ARMSSE
*s
= ARMSSE(dev
);
915 static void armsse_class_init(ObjectClass
*klass
, void *data
)
917 DeviceClass
*dc
= DEVICE_CLASS(klass
);
918 IDAUInterfaceClass
*iic
= IDAU_INTERFACE_CLASS(klass
);
919 ARMSSEClass
*asc
= ARMSSE_CLASS(klass
);
921 dc
->realize
= armsse_realize
;
922 dc
->vmsd
= &armsse_vmstate
;
923 dc
->props
= armsse_properties
;
924 dc
->reset
= armsse_reset
;
925 iic
->check
= armsse_idau_check
;
929 static const TypeInfo armsse_info
= {
931 .parent
= TYPE_SYS_BUS_DEVICE
,
932 .instance_size
= sizeof(ARMSSE
),
933 .instance_init
= armsse_init
,
935 .interfaces
= (InterfaceInfo
[]) {
936 { TYPE_IDAU_INTERFACE
},
941 static void armsse_register_types(void)
945 type_register_static(&armsse_info
);
947 for (i
= 0; i
< ARRAY_SIZE(armsse_variants
); i
++) {
949 .name
= armsse_variants
[i
].name
,
950 .parent
= TYPE_ARMSSE
,
951 .class_init
= armsse_class_init
,
952 .class_data
= (void *)&armsse_variants
[i
],
958 type_init(armsse_register_types
);