]> git.proxmox.com Git - mirror_qemu.git/blame - hw/arm/armsse.c
hw/arm/armsse: Add unimplemented-device stub for cache control registers
[mirror_qemu.git] / hw / arm / armsse.c
CommitLineData
9e5e54d1 1/*
93dbd103 2 * Arm SSE (Subsystems for Embedded): IoTKit
9e5e54d1
PM
3 *
4 * Copyright (c) 2018 Linaro Limited
5 * Written by Peter Maydell
6 *
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.
10 */
11
12#include "qemu/osdep.h"
13#include "qemu/log.h"
14#include "qapi/error.h"
15#include "trace.h"
16#include "hw/sysbus.h"
17#include "hw/registerfields.h"
6eee5d24 18#include "hw/arm/armsse.h"
9e5e54d1
PM
19#include "hw/arm/arm.h"
20
dde0c491
PM
21/* Format of the System Information block SYS_CONFIG register */
22typedef enum SysConfigFormat {
23 IoTKitFormat,
24 SSE200Format,
25} SysConfigFormat;
26
4c3690b5
PM
27struct ARMSSEInfo {
28 const char *name;
f0cab7fe 29 int sram_banks;
91c1e9fc 30 int num_cpus;
dde0c491
PM
31 uint32_t sys_version;
32 SysConfigFormat sys_config_format;
f8574705 33 bool has_mhus;
e0b00f1b 34 bool has_ppus;
2357bca5 35 bool has_cachectrl;
4c3690b5
PM
36};
37
38static const ARMSSEInfo armsse_variants[] = {
39 {
40 .name = TYPE_IOTKIT,
f0cab7fe 41 .sram_banks = 1,
91c1e9fc 42 .num_cpus = 1,
dde0c491
PM
43 .sys_version = 0x41743,
44 .sys_config_format = IoTKitFormat,
f8574705 45 .has_mhus = false,
e0b00f1b 46 .has_ppus = false,
2357bca5 47 .has_cachectrl = false,
4c3690b5
PM
48 },
49};
50
dde0c491
PM
51static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
52{
53 /* Return the SYS_CONFIG value for this SSE */
54 uint32_t sys_config;
55
56 switch (info->sys_config_format) {
57 case IoTKitFormat:
58 sys_config = 0;
59 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
60 sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
61 break;
62 case SSE200Format:
63 sys_config = 0;
64 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
65 sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
66 sys_config = deposit32(sys_config, 24, 4, 2);
67 if (info->num_cpus > 1) {
68 sys_config = deposit32(sys_config, 10, 1, 1);
69 sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
70 sys_config = deposit32(sys_config, 28, 4, 2);
71 }
72 break;
73 default:
74 g_assert_not_reached();
75 }
76 return sys_config;
77}
78
d61e4e1f
PM
79/* Clock frequency in HZ of the 32KHz "slow clock" */
80#define S32KCLK (32 * 1000)
81
91c1e9fc
PM
82/* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
83static bool irq_is_common[32] = {
84 [0 ... 5] = true,
85 /* 6, 7: per-CPU MHU interrupts */
86 [8 ... 12] = true,
87 /* 13: per-CPU icache interrupt */
88 /* 14: reserved */
89 [15 ... 20] = true,
90 /* 21: reserved */
91 [22 ... 26] = true,
92 /* 27: reserved */
93 /* 28, 29: per-CPU CTI interrupts */
94 /* 30, 31: reserved */
95};
96
9e5e54d1
PM
97/* Create an alias region of @size bytes starting at @base
98 * which mirrors the memory starting at @orig.
99 */
93dbd103 100static void make_alias(ARMSSE *s, MemoryRegion *mr, const char *name,
9e5e54d1
PM
101 hwaddr base, hwaddr size, hwaddr orig)
102{
103 memory_region_init_alias(mr, NULL, name, &s->container, orig, size);
104 /* The alias is even lower priority than unimplemented_device regions */
105 memory_region_add_subregion_overlap(&s->container, base, mr, -1500);
106}
107
9e5e54d1
PM
108static void irq_status_forwarder(void *opaque, int n, int level)
109{
110 qemu_irq destirq = opaque;
111
112 qemu_set_irq(destirq, level);
113}
114
115static void nsccfg_handler(void *opaque, int n, int level)
116{
93dbd103 117 ARMSSE *s = ARMSSE(opaque);
9e5e54d1
PM
118
119 s->nsccfg = level;
120}
121
13628891 122static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
9e5e54d1
PM
123{
124 /* Each of the 4 AHB and 4 APB PPCs that might be present in a
93dbd103 125 * system using the ARMSSE has a collection of control lines which
9e5e54d1 126 * are provided by the security controller and which we want to
93dbd103
PM
127 * expose as control lines on the ARMSSE device itself, so the
128 * code using the ARMSSE can wire them up to the PPCs.
9e5e54d1
PM
129 */
130 SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
13628891 131 DeviceState *armssedev = DEVICE(s);
9e5e54d1
PM
132 DeviceState *dev_secctl = DEVICE(&s->secctl);
133 DeviceState *dev_splitter = DEVICE(splitter);
134 char *name;
135
136 name = g_strdup_printf("%s_nonsec", ppcname);
13628891 137 qdev_pass_gpios(dev_secctl, armssedev, name);
9e5e54d1
PM
138 g_free(name);
139 name = g_strdup_printf("%s_ap", ppcname);
13628891 140 qdev_pass_gpios(dev_secctl, armssedev, name);
9e5e54d1
PM
141 g_free(name);
142 name = g_strdup_printf("%s_irq_enable", ppcname);
13628891 143 qdev_pass_gpios(dev_secctl, armssedev, name);
9e5e54d1
PM
144 g_free(name);
145 name = g_strdup_printf("%s_irq_clear", ppcname);
13628891 146 qdev_pass_gpios(dev_secctl, armssedev, name);
9e5e54d1
PM
147 g_free(name);
148
149 /* irq_status is a little more tricky, because we need to
150 * split it so we can send it both to the security controller
151 * and to our OR gate for the NVIC interrupt line.
152 * Connect up the splitter's outputs, and create a GPIO input
153 * which will pass the line state to the input splitter.
154 */
155 name = g_strdup_printf("%s_irq_status", ppcname);
156 qdev_connect_gpio_out(dev_splitter, 0,
157 qdev_get_gpio_in_named(dev_secctl,
158 name, 0));
159 qdev_connect_gpio_out(dev_splitter, 1,
160 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
161 s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
13628891 162 qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
9e5e54d1
PM
163 s->irq_status_in[ppcnum], name, 1);
164 g_free(name);
165}
166
13628891 167static void armsse_forward_sec_resp_cfg(ARMSSE *s)
9e5e54d1
PM
168{
169 /* Forward the 3rd output from the splitter device as a
13628891 170 * named GPIO output of the armsse object.
9e5e54d1
PM
171 */
172 DeviceState *dev = DEVICE(s);
173 DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
174
175 qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
176 s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
177 s->sec_resp_cfg, 1);
178 qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
179}
180
13628891 181static void armsse_init(Object *obj)
9e5e54d1 182{
93dbd103 183 ARMSSE *s = ARMSSE(obj);
f0cab7fe
PM
184 ARMSSEClass *asc = ARMSSE_GET_CLASS(obj);
185 const ARMSSEInfo *info = asc->info;
9e5e54d1
PM
186 int i;
187
f0cab7fe 188 assert(info->sram_banks <= MAX_SRAM_BANKS);
91c1e9fc 189 assert(info->num_cpus <= SSE_MAX_CPUS);
f0cab7fe 190
13628891 191 memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
9e5e54d1 192
91c1e9fc 193 for (i = 0; i < info->num_cpus; i++) {
7cd3a2e0
PM
194 /*
195 * We put each CPU in its own cluster as they are logically
196 * distinct and may be configured differently.
197 */
198 char *name;
199
200 name = g_strdup_printf("cluster%d", i);
201 object_initialize_child(obj, name, &s->cluster[i],
202 sizeof(s->cluster[i]), TYPE_CPU_CLUSTER,
203 &error_abort, NULL);
204 qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
205 g_free(name);
206
207 name = g_strdup_printf("armv7m%d", i);
208 sysbus_init_child_obj(OBJECT(&s->cluster[i]), name,
209 &s->armv7m[i], sizeof(s->armv7m), TYPE_ARMV7M);
91c1e9fc
PM
210 qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
211 ARM_CPU_TYPE_NAME("cortex-m33"));
212 g_free(name);
d847ca51
PM
213 name = g_strdup_printf("arm-sse-cpu-container%d", i);
214 memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
215 g_free(name);
216 if (i > 0) {
217 name = g_strdup_printf("arm-sse-container-alias%d", i);
218 memory_region_init_alias(&s->container_alias[i - 1], obj,
219 name, &s->container, 0, UINT64_MAX);
220 g_free(name);
221 }
91c1e9fc 222 }
9e5e54d1 223
955cbc6b
TH
224 sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
225 TYPE_IOTKIT_SECCTL);
226 sysbus_init_child_obj(obj, "apb-ppc0", &s->apb_ppc0, sizeof(s->apb_ppc0),
227 TYPE_TZ_PPC);
228 sysbus_init_child_obj(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
229 TYPE_TZ_PPC);
f0cab7fe
PM
230 for (i = 0; i < info->sram_banks; i++) {
231 char *name = g_strdup_printf("mpc%d", i);
232 sysbus_init_child_obj(obj, name, &s->mpc[i],
233 sizeof(s->mpc[i]), TYPE_TZ_MPC);
234 g_free(name);
235 }
955cbc6b
TH
236 object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
237 sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
238 &error_abort, NULL);
239
f0cab7fe 240 for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
bb75e16d
PM
241 char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
242 SplitIRQ *splitter = &s->mpc_irq_splitter[i];
243
955cbc6b
TH
244 object_initialize_child(obj, name, splitter, sizeof(*splitter),
245 TYPE_SPLIT_IRQ, &error_abort, NULL);
bb75e16d
PM
246 g_free(name);
247 }
955cbc6b
TH
248 sysbus_init_child_obj(obj, "timer0", &s->timer0, sizeof(s->timer0),
249 TYPE_CMSDK_APB_TIMER);
250 sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1),
251 TYPE_CMSDK_APB_TIMER);
e2d203ba
PM
252 sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer),
253 TYPE_CMSDK_APB_TIMER);
955cbc6b 254 sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer),
017d069d 255 TYPE_CMSDK_APB_DUALTIMER);
d61e4e1f
PM
256 sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog,
257 sizeof(s->s32kwatchdog), TYPE_CMSDK_APB_WATCHDOG);
258 sysbus_init_child_obj(obj, "nswatchdog", &s->nswatchdog,
259 sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
260 sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
261 sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
13628891 262 sysbus_init_child_obj(obj, "armsse-sysctl", &s->sysctl,
06e65af3 263 sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
13628891 264 sysbus_init_child_obj(obj, "armsse-sysinfo", &s->sysinfo,
06e65af3 265 sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
f8574705
PM
266 if (info->has_mhus) {
267 sysbus_init_child_obj(obj, "mhu0", &s->mhu[0], sizeof(s->mhu[0]),
268 TYPE_UNIMPLEMENTED_DEVICE);
269 sysbus_init_child_obj(obj, "mhu1", &s->mhu[1], sizeof(s->mhu[1]),
270 TYPE_UNIMPLEMENTED_DEVICE);
271 }
e0b00f1b
PM
272 if (info->has_ppus) {
273 for (i = 0; i < info->num_cpus; i++) {
274 char *name = g_strdup_printf("CPU%dCORE_PPU", i);
275 int ppuidx = CPU0CORE_PPU + i;
276
277 sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
278 sizeof(s->ppu[ppuidx]),
279 TYPE_UNIMPLEMENTED_DEVICE);
280 g_free(name);
281 }
282 sysbus_init_child_obj(obj, "DBG_PPU", &s->ppu[DBG_PPU],
283 sizeof(s->ppu[DBG_PPU]),
284 TYPE_UNIMPLEMENTED_DEVICE);
285 for (i = 0; i < info->sram_banks; i++) {
286 char *name = g_strdup_printf("RAM%d_PPU", i);
287 int ppuidx = RAM0_PPU + i;
288
289 sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
290 sizeof(s->ppu[ppuidx]),
291 TYPE_UNIMPLEMENTED_DEVICE);
292 g_free(name);
293 }
294 }
2357bca5
PM
295 if (info->has_cachectrl) {
296 for (i = 0; i < info->num_cpus; i++) {
297 char *name = g_strdup_printf("cachectrl%d", i);
298
299 sysbus_init_child_obj(obj, name, &s->cachectrl[i],
300 sizeof(s->cachectrl[i]),
301 TYPE_UNIMPLEMENTED_DEVICE);
302 g_free(name);
303 }
304 }
d61e4e1f
PM
305 object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
306 sizeof(s->nmi_orgate), TYPE_OR_IRQ,
307 &error_abort, NULL);
955cbc6b
TH
308 object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
309 sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ,
310 &error_abort, NULL);
311 object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
312 sizeof(s->sec_resp_splitter), TYPE_SPLIT_IRQ,
313 &error_abort, NULL);
9e5e54d1
PM
314 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
315 char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
316 SplitIRQ *splitter = &s->ppc_irq_splitter[i];
317
955cbc6b
TH
318 object_initialize_child(obj, name, splitter, sizeof(*splitter),
319 TYPE_SPLIT_IRQ, &error_abort, NULL);
320 g_free(name);
9e5e54d1 321 }
91c1e9fc
PM
322 if (info->num_cpus > 1) {
323 for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
324 if (irq_is_common[i]) {
325 char *name = g_strdup_printf("cpu-irq-splitter%d", i);
326 SplitIRQ *splitter = &s->cpu_irq_splitter[i];
327
328 object_initialize_child(obj, name, splitter, sizeof(*splitter),
329 TYPE_SPLIT_IRQ, &error_abort, NULL);
330 g_free(name);
331 }
332 }
333 }
9e5e54d1
PM
334}
335
13628891 336static void armsse_exp_irq(void *opaque, int n, int level)
9e5e54d1 337{
91c1e9fc 338 qemu_irq *irqarray = opaque;
9e5e54d1 339
91c1e9fc 340 qemu_set_irq(irqarray[n], level);
9e5e54d1
PM
341}
342
13628891 343static void armsse_mpcexp_status(void *opaque, int n, int level)
bb75e16d 344{
93dbd103 345 ARMSSE *s = ARMSSE(opaque);
bb75e16d
PM
346 qemu_set_irq(s->mpcexp_status_in[n], level);
347}
348
91c1e9fc
PM
349static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
350{
351 /*
352 * Return a qemu_irq which can be used to signal IRQ n to
353 * all CPUs in the SSE.
354 */
355 ARMSSEClass *asc = ARMSSE_GET_CLASS(s);
356 const ARMSSEInfo *info = asc->info;
357
358 assert(irq_is_common[irqno]);
359
360 if (info->num_cpus == 1) {
361 /* Only one CPU -- just connect directly to it */
362 return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
363 } else {
364 /* Connect to the splitter which feeds all CPUs */
365 return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
366 }
367}
368
e0b00f1b
PM
369static void map_ppu(ARMSSE *s, int ppuidx, const char *name, hwaddr addr)
370{
371 /* Map a PPU unimplemented device stub */
372 DeviceState *dev = DEVICE(&s->ppu[ppuidx]);
373
374 qdev_prop_set_string(dev, "name", name);
375 qdev_prop_set_uint64(dev, "size", 0x1000);
376 qdev_init_nofail(dev);
377 sysbus_mmio_map(SYS_BUS_DEVICE(&s->ppu[ppuidx]), 0, addr);
378}
379
13628891 380static void armsse_realize(DeviceState *dev, Error **errp)
9e5e54d1 381{
93dbd103 382 ARMSSE *s = ARMSSE(dev);
f0cab7fe
PM
383 ARMSSEClass *asc = ARMSSE_GET_CLASS(dev);
384 const ARMSSEInfo *info = asc->info;
9e5e54d1
PM
385 int i;
386 MemoryRegion *mr;
387 Error *err = NULL;
388 SysBusDevice *sbd_apb_ppc0;
389 SysBusDevice *sbd_secctl;
390 DeviceState *dev_apb_ppc0;
391 DeviceState *dev_apb_ppc1;
392 DeviceState *dev_secctl;
393 DeviceState *dev_splitter;
4b635cf7 394 uint32_t addr_width_max;
9e5e54d1
PM
395
396 if (!s->board_memory) {
397 error_setg(errp, "memory property was not set");
398 return;
399 }
400
401 if (!s->mainclk_frq) {
402 error_setg(errp, "MAINCLK property was not set");
403 return;
404 }
405
4b635cf7
PM
406 /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
407 assert(is_power_of_2(info->sram_banks));
408 addr_width_max = 24 - ctz32(info->sram_banks);
409 if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
410 error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
411 addr_width_max);
412 return;
413 }
414
9e5e54d1
PM
415 /* Handling of which devices should be available only to secure
416 * code is usually done differently for M profile than for A profile.
417 * Instead of putting some devices only into the secure address space,
418 * devices exist in both address spaces but with hard-wired security
419 * permissions that will cause the CPU to fault for non-secure accesses.
420 *
93dbd103 421 * The ARMSSE has an IDAU (Implementation Defined Access Unit),
9e5e54d1 422 * which specifies hard-wired security permissions for different
93dbd103 423 * areas of the physical address space. For the ARMSSE IDAU, the
9e5e54d1
PM
424 * top 4 bits of the physical address are the IDAU region ID, and
425 * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
426 * region, otherwise it is an S region.
427 *
428 * The various devices and RAMs are generally all mapped twice,
429 * once into a region that the IDAU defines as secure and once
430 * into a non-secure region. They sit behind either a Memory
431 * Protection Controller (for RAM) or a Peripheral Protection
432 * Controller (for devices), which allow a more fine grained
433 * configuration of whether non-secure accesses are permitted.
434 *
435 * (The other place that guest software can configure security
436 * permissions is in the architected SAU (Security Attribution
437 * Unit), which is entirely inside the CPU. The IDAU can upgrade
438 * the security attributes for a region to more restrictive than
439 * the SAU specifies, but cannot downgrade them.)
440 *
441 * 0x10000000..0x1fffffff alias of 0x00000000..0x0fffffff
442 * 0x20000000..0x2007ffff 32KB FPGA block RAM
443 * 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff
444 * 0x40000000..0x4000ffff base peripheral region 1
93dbd103 445 * 0x40010000..0x4001ffff CPU peripherals (none for ARMSSE)
9e5e54d1
PM
446 * 0x40020000..0x4002ffff system control element peripherals
447 * 0x40080000..0x400fffff base peripheral region 2
448 * 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
449 */
450
d847ca51 451 memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
9e5e54d1 452
91c1e9fc
PM
453 for (i = 0; i < info->num_cpus; i++) {
454 DeviceState *cpudev = DEVICE(&s->armv7m[i]);
455 Object *cpuobj = OBJECT(&s->armv7m[i]);
456 int j;
457 char *gpioname;
458
459 qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + 32);
460 /*
461 * In real hardware the initial Secure VTOR is set from the INITSVTOR0
462 * register in the IoT Kit System Control Register block, and the
463 * initial value of that is in turn specifiable by the FPGA that
464 * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
465 * and simply set the CPU's init-svtor to the IoT Kit default value.
466 * In SSE-200 the situation is similar, except that the default value
467 * is a reset-time signal input. Typically a board using the SSE-200
468 * will have a system control processor whose boot firmware initializes
469 * the INITSVTOR* registers before powering up the CPUs in any case,
470 * so the hardware's default value doesn't matter. QEMU doesn't emulate
471 * the control processor, so instead we behave in the way that the
472 * firmware does. All boards currently known about have firmware that
473 * sets the INITSVTOR0 and INITSVTOR1 registers to 0x10000000, like the
474 * IoTKit default. We can make this more configurable if necessary.
475 */
476 qdev_prop_set_uint32(cpudev, "init-svtor", 0x10000000);
477 /*
478 * Start all CPUs except CPU0 powered down. In real hardware it is
479 * a configurable property of the SSE-200 which CPUs start powered up
480 * (via the CPUWAIT0_RST and CPUWAIT1_RST parameters), but since all
481 * the boards we care about start CPU0 and leave CPU1 powered off,
482 * we hard-code that for now. We can add QOM properties for this
483 * later if necessary.
484 */
485 if (i > 0) {
486 object_property_set_bool(cpuobj, true, "start-powered-off", &err);
487 if (err) {
488 error_propagate(errp, err);
489 return;
490 }
491 }
d847ca51
PM
492
493 if (i > 0) {
494 memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
495 &s->container_alias[i - 1], -1);
496 } else {
497 memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
498 &s->container, -1);
499 }
500 object_property_set_link(cpuobj, OBJECT(&s->cpu_container[i]),
501 "memory", &err);
91c1e9fc
PM
502 if (err) {
503 error_propagate(errp, err);
504 return;
505 }
506 object_property_set_link(cpuobj, OBJECT(s), "idau", &err);
507 if (err) {
508 error_propagate(errp, err);
509 return;
510 }
511 object_property_set_bool(cpuobj, true, "realized", &err);
512 if (err) {
513 error_propagate(errp, err);
514 return;
515 }
7cd3a2e0
PM
516 /*
517 * The cluster must be realized after the armv7m container, as
518 * the container's CPU object is only created on realize, and the
519 * CPU must exist and have been parented into the cluster before
520 * the cluster is realized.
521 */
522 object_property_set_bool(OBJECT(&s->cluster[i]),
523 true, "realized", &err);
524 if (err) {
525 error_propagate(errp, err);
526 return;
527 }
91c1e9fc
PM
528
529 /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
530 s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
531 for (j = 0; j < s->exp_numirq; j++) {
532 s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, i + 32);
533 }
534 if (i == 0) {
535 gpioname = g_strdup("EXP_IRQ");
536 } else {
537 gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
538 }
539 qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
540 s->exp_irqs[i],
541 gpioname, s->exp_numirq);
542 g_free(gpioname);
9e5e54d1
PM
543 }
544
91c1e9fc
PM
545 /* Wire up the splitters that connect common IRQs to all CPUs */
546 if (info->num_cpus > 1) {
547 for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
548 if (irq_is_common[i]) {
549 Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
550 DeviceState *devs = DEVICE(splitter);
551 int cpunum;
552
553 object_property_set_int(splitter, info->num_cpus,
554 "num-lines", &err);
555 if (err) {
556 error_propagate(errp, err);
557 return;
558 }
559 object_property_set_bool(splitter, true, "realized", &err);
560 if (err) {
561 error_propagate(errp, err);
562 return;
563 }
564 for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
565 DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
566
567 qdev_connect_gpio_out(devs, cpunum,
568 qdev_get_gpio_in(cpudev, i));
569 }
570 }
571 }
9e5e54d1 572 }
9e5e54d1
PM
573
574 /* Set up the big aliases first */
575 make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000);
576 make_alias(s, &s->alias2, "alias 2", 0x30000000, 0x10000000, 0x20000000);
577 /* The 0x50000000..0x5fffffff region is not a pure alias: it has
578 * a few extra devices that only appear there (generally the
579 * control interfaces for the protection controllers).
580 * We implement this by mapping those devices over the top of this
581 * alias MR at a higher priority.
582 */
583 make_alias(s, &s->alias3, "alias 3", 0x50000000, 0x10000000, 0x40000000);
584
9e5e54d1
PM
585
586 /* Security controller */
587 object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err);
588 if (err) {
589 error_propagate(errp, err);
590 return;
591 }
592 sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
593 dev_secctl = DEVICE(&s->secctl);
594 sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
595 sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
596
597 s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
598 qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
599
600 /* The sec_resp_cfg output from the security controller must be split into
93dbd103
PM
601 * multiple lines, one for each of the PPCs within the ARMSSE and one
602 * that will be an output from the ARMSSE to the system.
9e5e54d1
PM
603 */
604 object_property_set_int(OBJECT(&s->sec_resp_splitter), 3,
605 "num-lines", &err);
606 if (err) {
607 error_propagate(errp, err);
608 return;
609 }
610 object_property_set_bool(OBJECT(&s->sec_resp_splitter), true,
611 "realized", &err);
612 if (err) {
613 error_propagate(errp, err);
614 return;
615 }
616 dev_splitter = DEVICE(&s->sec_resp_splitter);
617 qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
618 qdev_get_gpio_in(dev_splitter, 0));
619
f0cab7fe
PM
620 /* Each SRAM bank lives behind its own Memory Protection Controller */
621 for (i = 0; i < info->sram_banks; i++) {
622 char *ramname = g_strdup_printf("armsse.sram%d", i);
623 SysBusDevice *sbd_mpc;
4b635cf7 624 uint32_t sram_bank_size = 1 << s->sram_addr_width;
f0cab7fe 625
4b635cf7
PM
626 memory_region_init_ram(&s->sram[i], NULL, ramname,
627 sram_bank_size, &err);
f0cab7fe
PM
628 g_free(ramname);
629 if (err) {
630 error_propagate(errp, err);
631 return;
632 }
633 object_property_set_link(OBJECT(&s->mpc[i]), OBJECT(&s->sram[i]),
634 "downstream", &err);
635 if (err) {
636 error_propagate(errp, err);
637 return;
638 }
639 object_property_set_bool(OBJECT(&s->mpc[i]), true, "realized", &err);
640 if (err) {
641 error_propagate(errp, err);
642 return;
643 }
644 /* Map the upstream end of the MPC into the right place... */
645 sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
4b635cf7
PM
646 memory_region_add_subregion(&s->container,
647 0x20000000 + i * sram_bank_size,
f0cab7fe
PM
648 sysbus_mmio_get_region(sbd_mpc, 1));
649 /* ...and its register interface */
650 memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
651 sysbus_mmio_get_region(sbd_mpc, 0));
af60b291 652 }
af60b291 653
bb75e16d
PM
654 /* We must OR together lines from the MPC splitters to go to the NVIC */
655 object_property_set_int(OBJECT(&s->mpc_irq_orgate),
f0cab7fe
PM
656 IOTS_NUM_EXP_MPC + info->sram_banks,
657 "num-lines", &err);
bb75e16d
PM
658 if (err) {
659 error_propagate(errp, err);
660 return;
661 }
662 object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
663 "realized", &err);
664 if (err) {
665 error_propagate(errp, err);
666 return;
667 }
668 qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
91c1e9fc 669 armsse_get_common_irq_in(s, 9));
bb75e16d 670
9e5e54d1
PM
671 /* Devices behind APB PPC0:
672 * 0x40000000: timer0
673 * 0x40001000: timer1
674 * 0x40002000: dual timer
f8574705
PM
675 * 0x40003000: MHU0 (SSE-200 only)
676 * 0x40004000: MHU1 (SSE-200 only)
9e5e54d1
PM
677 * We must configure and realize each downstream device and connect
678 * it to the appropriate PPC port; then we can realize the PPC and
679 * map its upstream ends to the right place in the container.
680 */
681 qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
682 object_property_set_bool(OBJECT(&s->timer0), true, "realized", &err);
683 if (err) {
684 error_propagate(errp, err);
685 return;
686 }
687 sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
91c1e9fc 688 armsse_get_common_irq_in(s, 3));
9e5e54d1
PM
689 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
690 object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err);
691 if (err) {
692 error_propagate(errp, err);
693 return;
694 }
695
696 qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
697 object_property_set_bool(OBJECT(&s->timer1), true, "realized", &err);
698 if (err) {
699 error_propagate(errp, err);
700 return;
701 }
702 sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
91c1e9fc 703 armsse_get_common_irq_in(s, 4));
9e5e54d1
PM
704 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
705 object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err);
706 if (err) {
707 error_propagate(errp, err);
708 return;
709 }
710
017d069d
PM
711
712 qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
9e5e54d1
PM
713 object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err);
714 if (err) {
715 error_propagate(errp, err);
716 return;
717 }
017d069d 718 sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
91c1e9fc 719 armsse_get_common_irq_in(s, 5));
9e5e54d1
PM
720 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
721 object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
722 if (err) {
723 error_propagate(errp, err);
724 return;
725 }
726
f8574705
PM
727 if (info->has_mhus) {
728 for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
729 char *name = g_strdup_printf("MHU%d", i);
730 char *port = g_strdup_printf("port[%d]", i + 3);
731
732 qdev_prop_set_string(DEVICE(&s->mhu[i]), "name", name);
733 qdev_prop_set_uint64(DEVICE(&s->mhu[i]), "size", 0x1000);
734 object_property_set_bool(OBJECT(&s->mhu[i]), true,
735 "realized", &err);
736 if (err) {
737 error_propagate(errp, err);
738 return;
739 }
740 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mhu[i]), 0);
741 object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr),
742 port, &err);
743 if (err) {
744 error_propagate(errp, err);
745 return;
746 }
747 g_free(name);
748 g_free(port);
749 }
750 }
751
9e5e54d1
PM
752 object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err);
753 if (err) {
754 error_propagate(errp, err);
755 return;
756 }
757
758 sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0);
759 dev_apb_ppc0 = DEVICE(&s->apb_ppc0);
760
761 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0);
762 memory_region_add_subregion(&s->container, 0x40000000, mr);
763 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1);
764 memory_region_add_subregion(&s->container, 0x40001000, mr);
765 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
766 memory_region_add_subregion(&s->container, 0x40002000, mr);
f8574705
PM
767 if (info->has_mhus) {
768 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
769 memory_region_add_subregion(&s->container, 0x40003000, mr);
770 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
771 memory_region_add_subregion(&s->container, 0x40004000, mr);
772 }
9e5e54d1
PM
773 for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
774 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
775 qdev_get_gpio_in_named(dev_apb_ppc0,
776 "cfg_nonsec", i));
777 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
778 qdev_get_gpio_in_named(dev_apb_ppc0,
779 "cfg_ap", i));
780 }
781 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
782 qdev_get_gpio_in_named(dev_apb_ppc0,
783 "irq_enable", 0));
784 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
785 qdev_get_gpio_in_named(dev_apb_ppc0,
786 "irq_clear", 0));
787 qdev_connect_gpio_out(dev_splitter, 0,
788 qdev_get_gpio_in_named(dev_apb_ppc0,
789 "cfg_sec_resp", 0));
790
791 /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
792 * ones) are sent individually to the security controller, and also
793 * ORed together to give a single combined PPC interrupt to the NVIC.
794 */
795 object_property_set_int(OBJECT(&s->ppc_irq_orgate),
796 NUM_PPCS, "num-lines", &err);
797 if (err) {
798 error_propagate(errp, err);
799 return;
800 }
801 object_property_set_bool(OBJECT(&s->ppc_irq_orgate), true,
802 "realized", &err);
803 if (err) {
804 error_propagate(errp, err);
805 return;
806 }
807 qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
91c1e9fc 808 armsse_get_common_irq_in(s, 10));
9e5e54d1 809
2357bca5
PM
810 /*
811 * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
812 * private per-CPU region (all these devices are SSE-200 only):
813 * 0x50010000: L1 icache control registers
814 * 0x50011000: CPUSECCTRL (CPU local security control registers)
815 * 0x4001f000 and 0x5001f000: CPU_IDENTITY register block
816 */
817 if (info->has_cachectrl) {
818 for (i = 0; i < info->num_cpus; i++) {
819 char *name = g_strdup_printf("cachectrl%d", i);
820 MemoryRegion *mr;
821
822 qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
823 g_free(name);
824 qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
825 object_property_set_bool(OBJECT(&s->cachectrl[i]), true,
826 "realized", &err);
827 if (err) {
828 error_propagate(errp, err);
829 return;
830 }
831
832 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
833 memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
834 }
835 }
9e5e54d1 836
93dbd103 837 /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
9e5e54d1
PM
838 /* Devices behind APB PPC1:
839 * 0x4002f000: S32K timer
840 */
e2d203ba 841 qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
9e5e54d1
PM
842 object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err);
843 if (err) {
844 error_propagate(errp, err);
845 return;
846 }
e2d203ba 847 sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
91c1e9fc 848 armsse_get_common_irq_in(s, 2));
9e5e54d1
PM
849 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
850 object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
851 if (err) {
852 error_propagate(errp, err);
853 return;
854 }
855
856 object_property_set_bool(OBJECT(&s->apb_ppc1), true, "realized", &err);
857 if (err) {
858 error_propagate(errp, err);
859 return;
860 }
861 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0);
862 memory_region_add_subregion(&s->container, 0x4002f000, mr);
863
864 dev_apb_ppc1 = DEVICE(&s->apb_ppc1);
865 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
866 qdev_get_gpio_in_named(dev_apb_ppc1,
867 "cfg_nonsec", 0));
868 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
869 qdev_get_gpio_in_named(dev_apb_ppc1,
870 "cfg_ap", 0));
871 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
872 qdev_get_gpio_in_named(dev_apb_ppc1,
873 "irq_enable", 0));
874 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
875 qdev_get_gpio_in_named(dev_apb_ppc1,
876 "irq_clear", 0));
877 qdev_connect_gpio_out(dev_splitter, 1,
878 qdev_get_gpio_in_named(dev_apb_ppc1,
879 "cfg_sec_resp", 0));
880
dde0c491
PM
881 object_property_set_int(OBJECT(&s->sysinfo), info->sys_version,
882 "SYS_VERSION", &err);
883 if (err) {
884 error_propagate(errp, err);
885 return;
886 }
887 object_property_set_int(OBJECT(&s->sysinfo),
888 armsse_sys_config_value(s, info),
889 "SYS_CONFIG", &err);
890 if (err) {
891 error_propagate(errp, err);
892 return;
893 }
06e65af3
PM
894 object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
895 if (err) {
896 error_propagate(errp, err);
897 return;
898 }
899 /* System information registers */
900 sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
901 /* System control registers */
902 object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
903 if (err) {
904 error_propagate(errp, err);
905 return;
906 }
907 sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
d61e4e1f 908
e0b00f1b
PM
909 if (info->has_ppus) {
910 /* CPUnCORE_PPU for each CPU */
911 for (i = 0; i < info->num_cpus; i++) {
912 char *name = g_strdup_printf("CPU%dCORE_PPU", i);
913
914 map_ppu(s, CPU0CORE_PPU + i, name, 0x50023000 + i * 0x2000);
915 /*
916 * We don't support CPU debug so don't create the
917 * CPU0DEBUG_PPU at 0x50024000 and 0x50026000.
918 */
919 g_free(name);
920 }
921 map_ppu(s, DBG_PPU, "DBG_PPU", 0x50029000);
922
923 for (i = 0; i < info->sram_banks; i++) {
924 char *name = g_strdup_printf("RAM%d_PPU", i);
925
926 map_ppu(s, RAM0_PPU + i, name, 0x5002a000 + i * 0x1000);
927 g_free(name);
928 }
929 }
930
d61e4e1f
PM
931 /* This OR gate wires together outputs from the secure watchdogs to NMI */
932 object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
933 if (err) {
934 error_propagate(errp, err);
935 return;
936 }
937 object_property_set_bool(OBJECT(&s->nmi_orgate), true, "realized", &err);
938 if (err) {
939 error_propagate(errp, err);
940 return;
941 }
942 qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
943 qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
944
945 qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
946 object_property_set_bool(OBJECT(&s->s32kwatchdog), true, "realized", &err);
947 if (err) {
948 error_propagate(errp, err);
949 return;
950 }
951 sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0,
952 qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
953 sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
9e5e54d1 954
93dbd103 955 /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
9e5e54d1 956
d61e4e1f
PM
957 qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
958 object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err);
959 if (err) {
960 error_propagate(errp, err);
961 return;
962 }
963 sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
91c1e9fc 964 armsse_get_common_irq_in(s, 1));
d61e4e1f
PM
965 sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
966
967 qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
968 object_property_set_bool(OBJECT(&s->swatchdog), true, "realized", &err);
969 if (err) {
970 error_propagate(errp, err);
971 return;
972 }
973 sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0,
974 qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1));
975 sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000);
9e5e54d1 976
9e5e54d1
PM
977 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
978 Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
979
980 object_property_set_int(splitter, 2, "num-lines", &err);
981 if (err) {
982 error_propagate(errp, err);
983 return;
984 }
985 object_property_set_bool(splitter, true, "realized", &err);
986 if (err) {
987 error_propagate(errp, err);
988 return;
989 }
990 }
991
992 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
993 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
994
13628891 995 armsse_forward_ppc(s, ppcname, i);
9e5e54d1
PM
996 g_free(ppcname);
997 }
998
999 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
1000 char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
1001
13628891 1002 armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
9e5e54d1
PM
1003 g_free(ppcname);
1004 }
1005
1006 for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
1007 /* Wire up IRQ splitter for internal PPCs */
1008 DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
1009 char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
1010 i - NUM_EXTERNAL_PPCS);
1011 TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1;
1012
1013 qdev_connect_gpio_out(devs, 0,
1014 qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
1015 qdev_connect_gpio_out(devs, 1,
1016 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
1017 qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
1018 qdev_get_gpio_in(devs, 0));
7a35383a 1019 g_free(gpioname);
9e5e54d1
PM
1020 }
1021
bb75e16d 1022 /* Wire up the splitters for the MPC IRQs */
f0cab7fe 1023 for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
bb75e16d
PM
1024 SplitIRQ *splitter = &s->mpc_irq_splitter[i];
1025 DeviceState *dev_splitter = DEVICE(splitter);
1026
1027 object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
1028 if (err) {
1029 error_propagate(errp, err);
1030 return;
1031 }
1032 object_property_set_bool(OBJECT(splitter), true, "realized", &err);
1033 if (err) {
1034 error_propagate(errp, err);
1035 return;
1036 }
1037
1038 if (i < IOTS_NUM_EXP_MPC) {
1039 /* Splitter input is from GPIO input line */
1040 s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
1041 qdev_connect_gpio_out(dev_splitter, 0,
1042 qdev_get_gpio_in_named(dev_secctl,
1043 "mpcexp_status", i));
1044 } else {
1045 /* Splitter input is from our own MPC */
f0cab7fe
PM
1046 qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
1047 "irq", 0,
bb75e16d
PM
1048 qdev_get_gpio_in(dev_splitter, 0));
1049 qdev_connect_gpio_out(dev_splitter, 0,
1050 qdev_get_gpio_in_named(dev_secctl,
1051 "mpc_status", 0));
1052 }
1053
1054 qdev_connect_gpio_out(dev_splitter, 1,
1055 qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
1056 }
1057 /* Create GPIO inputs which will pass the line state for our
1058 * mpcexp_irq inputs to the correct splitter devices.
1059 */
13628891 1060 qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
bb75e16d
PM
1061 IOTS_NUM_EXP_MPC);
1062
13628891 1063 armsse_forward_sec_resp_cfg(s);
9e5e54d1 1064
132b475a
PM
1065 /* Forward the MSC related signals */
1066 qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
1067 qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
1068 qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
1069 qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
91c1e9fc 1070 armsse_get_common_irq_in(s, 11));
132b475a
PM
1071
1072 /*
1073 * Expose our container region to the board model; this corresponds
1074 * to the AHB Slave Expansion ports which allow bus master devices
1075 * (eg DMA controllers) in the board model to make transactions into
93dbd103 1076 * devices in the ARMSSE.
132b475a
PM
1077 */
1078 sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
1079
9e5e54d1
PM
1080 system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
1081}
1082
13628891 1083static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
9e5e54d1
PM
1084 int *iregion, bool *exempt, bool *ns, bool *nsc)
1085{
93dbd103
PM
1086 /*
1087 * For ARMSSE systems the IDAU responses are simple logical functions
9e5e54d1
PM
1088 * of the address bits. The NSC attribute is guest-adjustable via the
1089 * NSCCFG register in the security controller.
1090 */
93dbd103 1091 ARMSSE *s = ARMSSE(ii);
9e5e54d1
PM
1092 int region = extract32(address, 28, 4);
1093
1094 *ns = !(region & 1);
1095 *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
1096 /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
1097 *exempt = (address & 0xeff00000) == 0xe0000000;
1098 *iregion = region;
1099}
1100
13628891 1101static const VMStateDescription armsse_vmstate = {
9e5e54d1
PM
1102 .name = "iotkit",
1103 .version_id = 1,
1104 .minimum_version_id = 1,
1105 .fields = (VMStateField[]) {
93dbd103 1106 VMSTATE_UINT32(nsccfg, ARMSSE),
9e5e54d1
PM
1107 VMSTATE_END_OF_LIST()
1108 }
1109};
1110
13628891 1111static Property armsse_properties[] = {
93dbd103 1112 DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
9e5e54d1 1113 MemoryRegion *),
93dbd103
PM
1114 DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
1115 DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
4b635cf7 1116 DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
9e5e54d1
PM
1117 DEFINE_PROP_END_OF_LIST()
1118};
1119
13628891 1120static void armsse_reset(DeviceState *dev)
9e5e54d1 1121{
93dbd103 1122 ARMSSE *s = ARMSSE(dev);
9e5e54d1
PM
1123
1124 s->nsccfg = 0;
1125}
1126
13628891 1127static void armsse_class_init(ObjectClass *klass, void *data)
9e5e54d1
PM
1128{
1129 DeviceClass *dc = DEVICE_CLASS(klass);
1130 IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
4c3690b5 1131 ARMSSEClass *asc = ARMSSE_CLASS(klass);
9e5e54d1 1132
13628891
PM
1133 dc->realize = armsse_realize;
1134 dc->vmsd = &armsse_vmstate;
1135 dc->props = armsse_properties;
1136 dc->reset = armsse_reset;
1137 iic->check = armsse_idau_check;
4c3690b5 1138 asc->info = data;
9e5e54d1
PM
1139}
1140
4c3690b5 1141static const TypeInfo armsse_info = {
93dbd103 1142 .name = TYPE_ARMSSE,
9e5e54d1 1143 .parent = TYPE_SYS_BUS_DEVICE,
93dbd103 1144 .instance_size = sizeof(ARMSSE),
13628891 1145 .instance_init = armsse_init,
4c3690b5 1146 .abstract = true,
9e5e54d1
PM
1147 .interfaces = (InterfaceInfo[]) {
1148 { TYPE_IDAU_INTERFACE },
1149 { }
1150 }
1151};
1152
4c3690b5 1153static void armsse_register_types(void)
9e5e54d1 1154{
4c3690b5
PM
1155 int i;
1156
1157 type_register_static(&armsse_info);
1158
1159 for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
1160 TypeInfo ti = {
1161 .name = armsse_variants[i].name,
1162 .parent = TYPE_ARMSSE,
13628891 1163 .class_init = armsse_class_init,
4c3690b5
PM
1164 .class_data = (void *)&armsse_variants[i],
1165 };
1166 type_register(&ti);
1167 }
9e5e54d1
PM
1168}
1169
4c3690b5 1170type_init(armsse_register_types);