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"
26 static const ARMSSEInfo armsse_variants
[] = {
33 /* Clock frequency in HZ of the 32KHz "slow clock" */
34 #define S32KCLK (32 * 1000)
36 /* Create an alias region of @size bytes starting at @base
37 * which mirrors the memory starting at @orig.
39 static void make_alias(ARMSSE
*s
, MemoryRegion
*mr
, const char *name
,
40 hwaddr base
, hwaddr size
, hwaddr orig
)
42 memory_region_init_alias(mr
, NULL
, name
, &s
->container
, orig
, size
);
43 /* The alias is even lower priority than unimplemented_device regions */
44 memory_region_add_subregion_overlap(&s
->container
, base
, mr
, -1500);
47 static void irq_status_forwarder(void *opaque
, int n
, int level
)
49 qemu_irq destirq
= opaque
;
51 qemu_set_irq(destirq
, level
);
54 static void nsccfg_handler(void *opaque
, int n
, int level
)
56 ARMSSE
*s
= ARMSSE(opaque
);
61 static void armsse_forward_ppc(ARMSSE
*s
, const char *ppcname
, int ppcnum
)
63 /* Each of the 4 AHB and 4 APB PPCs that might be present in a
64 * system using the ARMSSE has a collection of control lines which
65 * are provided by the security controller and which we want to
66 * expose as control lines on the ARMSSE device itself, so the
67 * code using the ARMSSE can wire them up to the PPCs.
69 SplitIRQ
*splitter
= &s
->ppc_irq_splitter
[ppcnum
];
70 DeviceState
*armssedev
= DEVICE(s
);
71 DeviceState
*dev_secctl
= DEVICE(&s
->secctl
);
72 DeviceState
*dev_splitter
= DEVICE(splitter
);
75 name
= g_strdup_printf("%s_nonsec", ppcname
);
76 qdev_pass_gpios(dev_secctl
, armssedev
, name
);
78 name
= g_strdup_printf("%s_ap", ppcname
);
79 qdev_pass_gpios(dev_secctl
, armssedev
, name
);
81 name
= g_strdup_printf("%s_irq_enable", ppcname
);
82 qdev_pass_gpios(dev_secctl
, armssedev
, name
);
84 name
= g_strdup_printf("%s_irq_clear", ppcname
);
85 qdev_pass_gpios(dev_secctl
, armssedev
, name
);
88 /* irq_status is a little more tricky, because we need to
89 * split it so we can send it both to the security controller
90 * and to our OR gate for the NVIC interrupt line.
91 * Connect up the splitter's outputs, and create a GPIO input
92 * which will pass the line state to the input splitter.
94 name
= g_strdup_printf("%s_irq_status", ppcname
);
95 qdev_connect_gpio_out(dev_splitter
, 0,
96 qdev_get_gpio_in_named(dev_secctl
,
98 qdev_connect_gpio_out(dev_splitter
, 1,
99 qdev_get_gpio_in(DEVICE(&s
->ppc_irq_orgate
), ppcnum
));
100 s
->irq_status_in
[ppcnum
] = qdev_get_gpio_in(dev_splitter
, 0);
101 qdev_init_gpio_in_named_with_opaque(armssedev
, irq_status_forwarder
,
102 s
->irq_status_in
[ppcnum
], name
, 1);
106 static void armsse_forward_sec_resp_cfg(ARMSSE
*s
)
108 /* Forward the 3rd output from the splitter device as a
109 * named GPIO output of the armsse object.
111 DeviceState
*dev
= DEVICE(s
);
112 DeviceState
*dev_splitter
= DEVICE(&s
->sec_resp_splitter
);
114 qdev_init_gpio_out_named(dev
, &s
->sec_resp_cfg
, "sec_resp_cfg", 1);
115 s
->sec_resp_cfg_in
= qemu_allocate_irq(irq_status_forwarder
,
117 qdev_connect_gpio_out(dev_splitter
, 2, s
->sec_resp_cfg_in
);
120 static void armsse_init(Object
*obj
)
122 ARMSSE
*s
= ARMSSE(obj
);
123 ARMSSEClass
*asc
= ARMSSE_GET_CLASS(obj
);
124 const ARMSSEInfo
*info
= asc
->info
;
127 assert(info
->sram_banks
<= MAX_SRAM_BANKS
);
129 memory_region_init(&s
->container
, obj
, "armsse-container", UINT64_MAX
);
131 sysbus_init_child_obj(obj
, "armv7m", &s
->armv7m
, sizeof(s
->armv7m
),
133 qdev_prop_set_string(DEVICE(&s
->armv7m
), "cpu-type",
134 ARM_CPU_TYPE_NAME("cortex-m33"));
136 sysbus_init_child_obj(obj
, "secctl", &s
->secctl
, sizeof(s
->secctl
),
138 sysbus_init_child_obj(obj
, "apb-ppc0", &s
->apb_ppc0
, sizeof(s
->apb_ppc0
),
140 sysbus_init_child_obj(obj
, "apb-ppc1", &s
->apb_ppc1
, sizeof(s
->apb_ppc1
),
142 for (i
= 0; i
< info
->sram_banks
; i
++) {
143 char *name
= g_strdup_printf("mpc%d", i
);
144 sysbus_init_child_obj(obj
, name
, &s
->mpc
[i
],
145 sizeof(s
->mpc
[i
]), TYPE_TZ_MPC
);
148 object_initialize_child(obj
, "mpc-irq-orgate", &s
->mpc_irq_orgate
,
149 sizeof(s
->mpc_irq_orgate
), TYPE_OR_IRQ
,
152 for (i
= 0; i
< IOTS_NUM_EXP_MPC
+ info
->sram_banks
; i
++) {
153 char *name
= g_strdup_printf("mpc-irq-splitter-%d", i
);
154 SplitIRQ
*splitter
= &s
->mpc_irq_splitter
[i
];
156 object_initialize_child(obj
, name
, splitter
, sizeof(*splitter
),
157 TYPE_SPLIT_IRQ
, &error_abort
, NULL
);
160 sysbus_init_child_obj(obj
, "timer0", &s
->timer0
, sizeof(s
->timer0
),
161 TYPE_CMSDK_APB_TIMER
);
162 sysbus_init_child_obj(obj
, "timer1", &s
->timer1
, sizeof(s
->timer1
),
163 TYPE_CMSDK_APB_TIMER
);
164 sysbus_init_child_obj(obj
, "s32ktimer", &s
->s32ktimer
, sizeof(s
->s32ktimer
),
165 TYPE_CMSDK_APB_TIMER
);
166 sysbus_init_child_obj(obj
, "dualtimer", &s
->dualtimer
, sizeof(s
->dualtimer
),
167 TYPE_CMSDK_APB_DUALTIMER
);
168 sysbus_init_child_obj(obj
, "s32kwatchdog", &s
->s32kwatchdog
,
169 sizeof(s
->s32kwatchdog
), TYPE_CMSDK_APB_WATCHDOG
);
170 sysbus_init_child_obj(obj
, "nswatchdog", &s
->nswatchdog
,
171 sizeof(s
->nswatchdog
), TYPE_CMSDK_APB_WATCHDOG
);
172 sysbus_init_child_obj(obj
, "swatchdog", &s
->swatchdog
,
173 sizeof(s
->swatchdog
), TYPE_CMSDK_APB_WATCHDOG
);
174 sysbus_init_child_obj(obj
, "armsse-sysctl", &s
->sysctl
,
175 sizeof(s
->sysctl
), TYPE_IOTKIT_SYSCTL
);
176 sysbus_init_child_obj(obj
, "armsse-sysinfo", &s
->sysinfo
,
177 sizeof(s
->sysinfo
), TYPE_IOTKIT_SYSINFO
);
178 object_initialize_child(obj
, "nmi-orgate", &s
->nmi_orgate
,
179 sizeof(s
->nmi_orgate
), TYPE_OR_IRQ
,
181 object_initialize_child(obj
, "ppc-irq-orgate", &s
->ppc_irq_orgate
,
182 sizeof(s
->ppc_irq_orgate
), TYPE_OR_IRQ
,
184 object_initialize_child(obj
, "sec-resp-splitter", &s
->sec_resp_splitter
,
185 sizeof(s
->sec_resp_splitter
), TYPE_SPLIT_IRQ
,
187 for (i
= 0; i
< ARRAY_SIZE(s
->ppc_irq_splitter
); i
++) {
188 char *name
= g_strdup_printf("ppc-irq-splitter-%d", i
);
189 SplitIRQ
*splitter
= &s
->ppc_irq_splitter
[i
];
191 object_initialize_child(obj
, name
, splitter
, sizeof(*splitter
),
192 TYPE_SPLIT_IRQ
, &error_abort
, NULL
);
197 static void armsse_exp_irq(void *opaque
, int n
, int level
)
199 ARMSSE
*s
= ARMSSE(opaque
);
201 qemu_set_irq(s
->exp_irqs
[n
], level
);
204 static void armsse_mpcexp_status(void *opaque
, int n
, int level
)
206 ARMSSE
*s
= ARMSSE(opaque
);
207 qemu_set_irq(s
->mpcexp_status_in
[n
], level
);
210 static void armsse_realize(DeviceState
*dev
, Error
**errp
)
212 ARMSSE
*s
= ARMSSE(dev
);
213 ARMSSEClass
*asc
= ARMSSE_GET_CLASS(dev
);
214 const ARMSSEInfo
*info
= asc
->info
;
218 SysBusDevice
*sbd_apb_ppc0
;
219 SysBusDevice
*sbd_secctl
;
220 DeviceState
*dev_apb_ppc0
;
221 DeviceState
*dev_apb_ppc1
;
222 DeviceState
*dev_secctl
;
223 DeviceState
*dev_splitter
;
224 uint32_t addr_width_max
;
226 if (!s
->board_memory
) {
227 error_setg(errp
, "memory property was not set");
231 if (!s
->mainclk_frq
) {
232 error_setg(errp
, "MAINCLK property was not set");
236 /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
237 assert(is_power_of_2(info
->sram_banks
));
238 addr_width_max
= 24 - ctz32(info
->sram_banks
);
239 if (s
->sram_addr_width
< 1 || s
->sram_addr_width
> addr_width_max
) {
240 error_setg(errp
, "SRAM_ADDR_WIDTH must be between 1 and %d",
245 /* Handling of which devices should be available only to secure
246 * code is usually done differently for M profile than for A profile.
247 * Instead of putting some devices only into the secure address space,
248 * devices exist in both address spaces but with hard-wired security
249 * permissions that will cause the CPU to fault for non-secure accesses.
251 * The ARMSSE has an IDAU (Implementation Defined Access Unit),
252 * which specifies hard-wired security permissions for different
253 * areas of the physical address space. For the ARMSSE IDAU, the
254 * top 4 bits of the physical address are the IDAU region ID, and
255 * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
256 * region, otherwise it is an S region.
258 * The various devices and RAMs are generally all mapped twice,
259 * once into a region that the IDAU defines as secure and once
260 * into a non-secure region. They sit behind either a Memory
261 * Protection Controller (for RAM) or a Peripheral Protection
262 * Controller (for devices), which allow a more fine grained
263 * configuration of whether non-secure accesses are permitted.
265 * (The other place that guest software can configure security
266 * permissions is in the architected SAU (Security Attribution
267 * Unit), which is entirely inside the CPU. The IDAU can upgrade
268 * the security attributes for a region to more restrictive than
269 * the SAU specifies, but cannot downgrade them.)
271 * 0x10000000..0x1fffffff alias of 0x00000000..0x0fffffff
272 * 0x20000000..0x2007ffff 32KB FPGA block RAM
273 * 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff
274 * 0x40000000..0x4000ffff base peripheral region 1
275 * 0x40010000..0x4001ffff CPU peripherals (none for ARMSSE)
276 * 0x40020000..0x4002ffff system control element peripherals
277 * 0x40080000..0x400fffff base peripheral region 2
278 * 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
281 memory_region_add_subregion_overlap(&s
->container
, 0, s
->board_memory
, -1);
283 qdev_prop_set_uint32(DEVICE(&s
->armv7m
), "num-irq", s
->exp_numirq
+ 32);
284 /* In real hardware the initial Secure VTOR is set from the INITSVTOR0
285 * register in the IoT Kit System Control Register block, and the
286 * initial value of that is in turn specifiable by the FPGA that
287 * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
288 * and simply set the CPU's init-svtor to the IoT Kit default value.
290 qdev_prop_set_uint32(DEVICE(&s
->armv7m
), "init-svtor", 0x10000000);
291 object_property_set_link(OBJECT(&s
->armv7m
), OBJECT(&s
->container
),
294 error_propagate(errp
, err
);
297 object_property_set_link(OBJECT(&s
->armv7m
), OBJECT(s
), "idau", &err
);
299 error_propagate(errp
, err
);
302 object_property_set_bool(OBJECT(&s
->armv7m
), true, "realized", &err
);
304 error_propagate(errp
, err
);
308 /* Connect our EXP_IRQ GPIOs to the NVIC's lines 32 and up. */
309 s
->exp_irqs
= g_new(qemu_irq
, s
->exp_numirq
);
310 for (i
= 0; i
< s
->exp_numirq
; i
++) {
311 s
->exp_irqs
[i
] = qdev_get_gpio_in(DEVICE(&s
->armv7m
), i
+ 32);
313 qdev_init_gpio_in_named(dev
, armsse_exp_irq
, "EXP_IRQ", s
->exp_numirq
);
315 /* Set up the big aliases first */
316 make_alias(s
, &s
->alias1
, "alias 1", 0x10000000, 0x10000000, 0x00000000);
317 make_alias(s
, &s
->alias2
, "alias 2", 0x30000000, 0x10000000, 0x20000000);
318 /* The 0x50000000..0x5fffffff region is not a pure alias: it has
319 * a few extra devices that only appear there (generally the
320 * control interfaces for the protection controllers).
321 * We implement this by mapping those devices over the top of this
322 * alias MR at a higher priority.
324 make_alias(s
, &s
->alias3
, "alias 3", 0x50000000, 0x10000000, 0x40000000);
327 /* Security controller */
328 object_property_set_bool(OBJECT(&s
->secctl
), true, "realized", &err
);
330 error_propagate(errp
, err
);
333 sbd_secctl
= SYS_BUS_DEVICE(&s
->secctl
);
334 dev_secctl
= DEVICE(&s
->secctl
);
335 sysbus_mmio_map(sbd_secctl
, 0, 0x50080000);
336 sysbus_mmio_map(sbd_secctl
, 1, 0x40080000);
338 s
->nsc_cfg_in
= qemu_allocate_irq(nsccfg_handler
, s
, 1);
339 qdev_connect_gpio_out_named(dev_secctl
, "nsc_cfg", 0, s
->nsc_cfg_in
);
341 /* The sec_resp_cfg output from the security controller must be split into
342 * multiple lines, one for each of the PPCs within the ARMSSE and one
343 * that will be an output from the ARMSSE to the system.
345 object_property_set_int(OBJECT(&s
->sec_resp_splitter
), 3,
348 error_propagate(errp
, err
);
351 object_property_set_bool(OBJECT(&s
->sec_resp_splitter
), true,
354 error_propagate(errp
, err
);
357 dev_splitter
= DEVICE(&s
->sec_resp_splitter
);
358 qdev_connect_gpio_out_named(dev_secctl
, "sec_resp_cfg", 0,
359 qdev_get_gpio_in(dev_splitter
, 0));
361 /* Each SRAM bank lives behind its own Memory Protection Controller */
362 for (i
= 0; i
< info
->sram_banks
; i
++) {
363 char *ramname
= g_strdup_printf("armsse.sram%d", i
);
364 SysBusDevice
*sbd_mpc
;
365 uint32_t sram_bank_size
= 1 << s
->sram_addr_width
;
367 memory_region_init_ram(&s
->sram
[i
], NULL
, ramname
,
368 sram_bank_size
, &err
);
371 error_propagate(errp
, err
);
374 object_property_set_link(OBJECT(&s
->mpc
[i
]), OBJECT(&s
->sram
[i
]),
377 error_propagate(errp
, err
);
380 object_property_set_bool(OBJECT(&s
->mpc
[i
]), true, "realized", &err
);
382 error_propagate(errp
, err
);
385 /* Map the upstream end of the MPC into the right place... */
386 sbd_mpc
= SYS_BUS_DEVICE(&s
->mpc
[i
]);
387 memory_region_add_subregion(&s
->container
,
388 0x20000000 + i
* sram_bank_size
,
389 sysbus_mmio_get_region(sbd_mpc
, 1));
390 /* ...and its register interface */
391 memory_region_add_subregion(&s
->container
, 0x50083000 + i
* 0x1000,
392 sysbus_mmio_get_region(sbd_mpc
, 0));
395 /* We must OR together lines from the MPC splitters to go to the NVIC */
396 object_property_set_int(OBJECT(&s
->mpc_irq_orgate
),
397 IOTS_NUM_EXP_MPC
+ info
->sram_banks
,
400 error_propagate(errp
, err
);
403 object_property_set_bool(OBJECT(&s
->mpc_irq_orgate
), true,
406 error_propagate(errp
, err
);
409 qdev_connect_gpio_out(DEVICE(&s
->mpc_irq_orgate
), 0,
410 qdev_get_gpio_in(DEVICE(&s
->armv7m
), 9));
412 /* Devices behind APB PPC0:
415 * 0x40002000: dual timer
416 * We must configure and realize each downstream device and connect
417 * it to the appropriate PPC port; then we can realize the PPC and
418 * map its upstream ends to the right place in the container.
420 qdev_prop_set_uint32(DEVICE(&s
->timer0
), "pclk-frq", s
->mainclk_frq
);
421 object_property_set_bool(OBJECT(&s
->timer0
), true, "realized", &err
);
423 error_propagate(errp
, err
);
426 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->timer0
), 0,
427 qdev_get_gpio_in(DEVICE(&s
->armv7m
), 3));
428 mr
= sysbus_mmio_get_region(SYS_BUS_DEVICE(&s
->timer0
), 0);
429 object_property_set_link(OBJECT(&s
->apb_ppc0
), OBJECT(mr
), "port[0]", &err
);
431 error_propagate(errp
, err
);
435 qdev_prop_set_uint32(DEVICE(&s
->timer1
), "pclk-frq", s
->mainclk_frq
);
436 object_property_set_bool(OBJECT(&s
->timer1
), true, "realized", &err
);
438 error_propagate(errp
, err
);
441 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->timer1
), 0,
442 qdev_get_gpio_in(DEVICE(&s
->armv7m
), 4));
443 mr
= sysbus_mmio_get_region(SYS_BUS_DEVICE(&s
->timer1
), 0);
444 object_property_set_link(OBJECT(&s
->apb_ppc0
), OBJECT(mr
), "port[1]", &err
);
446 error_propagate(errp
, err
);
451 qdev_prop_set_uint32(DEVICE(&s
->dualtimer
), "pclk-frq", s
->mainclk_frq
);
452 object_property_set_bool(OBJECT(&s
->dualtimer
), true, "realized", &err
);
454 error_propagate(errp
, err
);
457 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->dualtimer
), 0,
458 qdev_get_gpio_in(DEVICE(&s
->armv7m
), 5));
459 mr
= sysbus_mmio_get_region(SYS_BUS_DEVICE(&s
->dualtimer
), 0);
460 object_property_set_link(OBJECT(&s
->apb_ppc0
), OBJECT(mr
), "port[2]", &err
);
462 error_propagate(errp
, err
);
466 object_property_set_bool(OBJECT(&s
->apb_ppc0
), true, "realized", &err
);
468 error_propagate(errp
, err
);
472 sbd_apb_ppc0
= SYS_BUS_DEVICE(&s
->apb_ppc0
);
473 dev_apb_ppc0
= DEVICE(&s
->apb_ppc0
);
475 mr
= sysbus_mmio_get_region(sbd_apb_ppc0
, 0);
476 memory_region_add_subregion(&s
->container
, 0x40000000, mr
);
477 mr
= sysbus_mmio_get_region(sbd_apb_ppc0
, 1);
478 memory_region_add_subregion(&s
->container
, 0x40001000, mr
);
479 mr
= sysbus_mmio_get_region(sbd_apb_ppc0
, 2);
480 memory_region_add_subregion(&s
->container
, 0x40002000, mr
);
481 for (i
= 0; i
< IOTS_APB_PPC0_NUM_PORTS
; i
++) {
482 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_nonsec", i
,
483 qdev_get_gpio_in_named(dev_apb_ppc0
,
485 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_ap", i
,
486 qdev_get_gpio_in_named(dev_apb_ppc0
,
489 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_irq_enable", 0,
490 qdev_get_gpio_in_named(dev_apb_ppc0
,
492 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc0_irq_clear", 0,
493 qdev_get_gpio_in_named(dev_apb_ppc0
,
495 qdev_connect_gpio_out(dev_splitter
, 0,
496 qdev_get_gpio_in_named(dev_apb_ppc0
,
499 /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
500 * ones) are sent individually to the security controller, and also
501 * ORed together to give a single combined PPC interrupt to the NVIC.
503 object_property_set_int(OBJECT(&s
->ppc_irq_orgate
),
504 NUM_PPCS
, "num-lines", &err
);
506 error_propagate(errp
, err
);
509 object_property_set_bool(OBJECT(&s
->ppc_irq_orgate
), true,
512 error_propagate(errp
, err
);
515 qdev_connect_gpio_out(DEVICE(&s
->ppc_irq_orgate
), 0,
516 qdev_get_gpio_in(DEVICE(&s
->armv7m
), 10));
518 /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
520 /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
521 /* Devices behind APB PPC1:
522 * 0x4002f000: S32K timer
524 qdev_prop_set_uint32(DEVICE(&s
->s32ktimer
), "pclk-frq", S32KCLK
);
525 object_property_set_bool(OBJECT(&s
->s32ktimer
), true, "realized", &err
);
527 error_propagate(errp
, err
);
530 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->s32ktimer
), 0,
531 qdev_get_gpio_in(DEVICE(&s
->armv7m
), 2));
532 mr
= sysbus_mmio_get_region(SYS_BUS_DEVICE(&s
->s32ktimer
), 0);
533 object_property_set_link(OBJECT(&s
->apb_ppc1
), OBJECT(mr
), "port[0]", &err
);
535 error_propagate(errp
, err
);
539 object_property_set_bool(OBJECT(&s
->apb_ppc1
), true, "realized", &err
);
541 error_propagate(errp
, err
);
544 mr
= sysbus_mmio_get_region(SYS_BUS_DEVICE(&s
->apb_ppc1
), 0);
545 memory_region_add_subregion(&s
->container
, 0x4002f000, mr
);
547 dev_apb_ppc1
= DEVICE(&s
->apb_ppc1
);
548 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_nonsec", 0,
549 qdev_get_gpio_in_named(dev_apb_ppc1
,
551 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_ap", 0,
552 qdev_get_gpio_in_named(dev_apb_ppc1
,
554 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_irq_enable", 0,
555 qdev_get_gpio_in_named(dev_apb_ppc1
,
557 qdev_connect_gpio_out_named(dev_secctl
, "apb_ppc1_irq_clear", 0,
558 qdev_get_gpio_in_named(dev_apb_ppc1
,
560 qdev_connect_gpio_out(dev_splitter
, 1,
561 qdev_get_gpio_in_named(dev_apb_ppc1
,
564 object_property_set_bool(OBJECT(&s
->sysinfo
), true, "realized", &err
);
566 error_propagate(errp
, err
);
569 /* System information registers */
570 sysbus_mmio_map(SYS_BUS_DEVICE(&s
->sysinfo
), 0, 0x40020000);
571 /* System control registers */
572 object_property_set_bool(OBJECT(&s
->sysctl
), true, "realized", &err
);
574 error_propagate(errp
, err
);
577 sysbus_mmio_map(SYS_BUS_DEVICE(&s
->sysctl
), 0, 0x50021000);
579 /* This OR gate wires together outputs from the secure watchdogs to NMI */
580 object_property_set_int(OBJECT(&s
->nmi_orgate
), 2, "num-lines", &err
);
582 error_propagate(errp
, err
);
585 object_property_set_bool(OBJECT(&s
->nmi_orgate
), true, "realized", &err
);
587 error_propagate(errp
, err
);
590 qdev_connect_gpio_out(DEVICE(&s
->nmi_orgate
), 0,
591 qdev_get_gpio_in_named(DEVICE(&s
->armv7m
), "NMI", 0));
593 qdev_prop_set_uint32(DEVICE(&s
->s32kwatchdog
), "wdogclk-frq", S32KCLK
);
594 object_property_set_bool(OBJECT(&s
->s32kwatchdog
), true, "realized", &err
);
596 error_propagate(errp
, err
);
599 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->s32kwatchdog
), 0,
600 qdev_get_gpio_in(DEVICE(&s
->nmi_orgate
), 0));
601 sysbus_mmio_map(SYS_BUS_DEVICE(&s
->s32kwatchdog
), 0, 0x5002e000);
603 /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
605 qdev_prop_set_uint32(DEVICE(&s
->nswatchdog
), "wdogclk-frq", s
->mainclk_frq
);
606 object_property_set_bool(OBJECT(&s
->nswatchdog
), true, "realized", &err
);
608 error_propagate(errp
, err
);
611 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->nswatchdog
), 0,
612 qdev_get_gpio_in(DEVICE(&s
->armv7m
), 1));
613 sysbus_mmio_map(SYS_BUS_DEVICE(&s
->nswatchdog
), 0, 0x40081000);
615 qdev_prop_set_uint32(DEVICE(&s
->swatchdog
), "wdogclk-frq", s
->mainclk_frq
);
616 object_property_set_bool(OBJECT(&s
->swatchdog
), true, "realized", &err
);
618 error_propagate(errp
, err
);
621 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->swatchdog
), 0,
622 qdev_get_gpio_in(DEVICE(&s
->nmi_orgate
), 1));
623 sysbus_mmio_map(SYS_BUS_DEVICE(&s
->swatchdog
), 0, 0x50081000);
625 for (i
= 0; i
< ARRAY_SIZE(s
->ppc_irq_splitter
); i
++) {
626 Object
*splitter
= OBJECT(&s
->ppc_irq_splitter
[i
]);
628 object_property_set_int(splitter
, 2, "num-lines", &err
);
630 error_propagate(errp
, err
);
633 object_property_set_bool(splitter
, true, "realized", &err
);
635 error_propagate(errp
, err
);
640 for (i
= 0; i
< IOTS_NUM_AHB_EXP_PPC
; i
++) {
641 char *ppcname
= g_strdup_printf("ahb_ppcexp%d", i
);
643 armsse_forward_ppc(s
, ppcname
, i
);
647 for (i
= 0; i
< IOTS_NUM_APB_EXP_PPC
; i
++) {
648 char *ppcname
= g_strdup_printf("apb_ppcexp%d", i
);
650 armsse_forward_ppc(s
, ppcname
, i
+ IOTS_NUM_AHB_EXP_PPC
);
654 for (i
= NUM_EXTERNAL_PPCS
; i
< NUM_PPCS
; i
++) {
655 /* Wire up IRQ splitter for internal PPCs */
656 DeviceState
*devs
= DEVICE(&s
->ppc_irq_splitter
[i
]);
657 char *gpioname
= g_strdup_printf("apb_ppc%d_irq_status",
658 i
- NUM_EXTERNAL_PPCS
);
659 TZPPC
*ppc
= (i
== NUM_EXTERNAL_PPCS
) ? &s
->apb_ppc0
: &s
->apb_ppc1
;
661 qdev_connect_gpio_out(devs
, 0,
662 qdev_get_gpio_in_named(dev_secctl
, gpioname
, 0));
663 qdev_connect_gpio_out(devs
, 1,
664 qdev_get_gpio_in(DEVICE(&s
->ppc_irq_orgate
), i
));
665 qdev_connect_gpio_out_named(DEVICE(ppc
), "irq", 0,
666 qdev_get_gpio_in(devs
, 0));
670 /* Wire up the splitters for the MPC IRQs */
671 for (i
= 0; i
< IOTS_NUM_EXP_MPC
+ info
->sram_banks
; i
++) {
672 SplitIRQ
*splitter
= &s
->mpc_irq_splitter
[i
];
673 DeviceState
*dev_splitter
= DEVICE(splitter
);
675 object_property_set_int(OBJECT(splitter
), 2, "num-lines", &err
);
677 error_propagate(errp
, err
);
680 object_property_set_bool(OBJECT(splitter
), true, "realized", &err
);
682 error_propagate(errp
, err
);
686 if (i
< IOTS_NUM_EXP_MPC
) {
687 /* Splitter input is from GPIO input line */
688 s
->mpcexp_status_in
[i
] = qdev_get_gpio_in(dev_splitter
, 0);
689 qdev_connect_gpio_out(dev_splitter
, 0,
690 qdev_get_gpio_in_named(dev_secctl
,
691 "mpcexp_status", i
));
693 /* Splitter input is from our own MPC */
694 qdev_connect_gpio_out_named(DEVICE(&s
->mpc
[i
- IOTS_NUM_EXP_MPC
]),
696 qdev_get_gpio_in(dev_splitter
, 0));
697 qdev_connect_gpio_out(dev_splitter
, 0,
698 qdev_get_gpio_in_named(dev_secctl
,
702 qdev_connect_gpio_out(dev_splitter
, 1,
703 qdev_get_gpio_in(DEVICE(&s
->mpc_irq_orgate
), i
));
705 /* Create GPIO inputs which will pass the line state for our
706 * mpcexp_irq inputs to the correct splitter devices.
708 qdev_init_gpio_in_named(dev
, armsse_mpcexp_status
, "mpcexp_status",
711 armsse_forward_sec_resp_cfg(s
);
713 /* Forward the MSC related signals */
714 qdev_pass_gpios(dev_secctl
, dev
, "mscexp_status");
715 qdev_pass_gpios(dev_secctl
, dev
, "mscexp_clear");
716 qdev_pass_gpios(dev_secctl
, dev
, "mscexp_ns");
717 qdev_connect_gpio_out_named(dev_secctl
, "msc_irq", 0,
718 qdev_get_gpio_in(DEVICE(&s
->armv7m
), 11));
721 * Expose our container region to the board model; this corresponds
722 * to the AHB Slave Expansion ports which allow bus master devices
723 * (eg DMA controllers) in the board model to make transactions into
724 * devices in the ARMSSE.
726 sysbus_init_mmio(SYS_BUS_DEVICE(s
), &s
->container
);
728 system_clock_scale
= NANOSECONDS_PER_SECOND
/ s
->mainclk_frq
;
731 static void armsse_idau_check(IDAUInterface
*ii
, uint32_t address
,
732 int *iregion
, bool *exempt
, bool *ns
, bool *nsc
)
735 * For ARMSSE systems the IDAU responses are simple logical functions
736 * of the address bits. The NSC attribute is guest-adjustable via the
737 * NSCCFG register in the security controller.
739 ARMSSE
*s
= ARMSSE(ii
);
740 int region
= extract32(address
, 28, 4);
743 *nsc
= (region
== 1 && (s
->nsccfg
& 1)) || (region
== 3 && (s
->nsccfg
& 2));
744 /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
745 *exempt
= (address
& 0xeff00000) == 0xe0000000;
749 static const VMStateDescription armsse_vmstate
= {
752 .minimum_version_id
= 1,
753 .fields
= (VMStateField
[]) {
754 VMSTATE_UINT32(nsccfg
, ARMSSE
),
755 VMSTATE_END_OF_LIST()
759 static Property armsse_properties
[] = {
760 DEFINE_PROP_LINK("memory", ARMSSE
, board_memory
, TYPE_MEMORY_REGION
,
762 DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE
, exp_numirq
, 64),
763 DEFINE_PROP_UINT32("MAINCLK", ARMSSE
, mainclk_frq
, 0),
764 DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE
, sram_addr_width
, 15),
765 DEFINE_PROP_END_OF_LIST()
768 static void armsse_reset(DeviceState
*dev
)
770 ARMSSE
*s
= ARMSSE(dev
);
775 static void armsse_class_init(ObjectClass
*klass
, void *data
)
777 DeviceClass
*dc
= DEVICE_CLASS(klass
);
778 IDAUInterfaceClass
*iic
= IDAU_INTERFACE_CLASS(klass
);
779 ARMSSEClass
*asc
= ARMSSE_CLASS(klass
);
781 dc
->realize
= armsse_realize
;
782 dc
->vmsd
= &armsse_vmstate
;
783 dc
->props
= armsse_properties
;
784 dc
->reset
= armsse_reset
;
785 iic
->check
= armsse_idau_check
;
789 static const TypeInfo armsse_info
= {
791 .parent
= TYPE_SYS_BUS_DEVICE
,
792 .instance_size
= sizeof(ARMSSE
),
793 .instance_init
= armsse_init
,
795 .interfaces
= (InterfaceInfo
[]) {
796 { TYPE_IDAU_INTERFACE
},
801 static void armsse_register_types(void)
805 type_register_static(&armsse_info
);
807 for (i
= 0; i
< ARRAY_SIZE(armsse_variants
); i
++) {
809 .name
= armsse_variants
[i
].name
,
810 .parent
= TYPE_ARMSSE
,
811 .class_init
= armsse_class_init
,
812 .class_data
= (void *)&armsse_variants
[i
],
818 type_init(armsse_register_types
);