master
c 1,935 lines 65.1 KB
Raw
1 /*
2 * Arm SSE (Subsystems for Embedded): IoTKit
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 "qemu/module.h"
15 #include "qemu/bitops.h"
16 #include "qemu/units.h"
17 #include "qapi/error.h"
18 #include "trace.h"
19 #include "hw/core/sysbus.h"
20 #include "migration/vmstate.h"
21 #include "hw/core/registerfields.h"
22 #include "hw/arm/armsse.h"
23 #include "hw/arm/armsse-version.h"
24 #include "hw/arm/boot.h"
25 #include "hw/core/irq.h"
26 #include "hw/core/qdev-clock.h"
27
28 /*
29 * The SSE-300 and SSE-310 put some devices in different places to the
30 * SSE-200 (and original IoTKit). We use an array of these structs
31 * to define how each variant lays out these devices. (Parts of the
32 * SoC that are the same for all variants aren't handled via these
33 * data structures.)
34 */
35
36 #define NO_IRQ -1
37 #define NO_PPC -1
38 /*
39 * Special values for ARMSSEDeviceInfo::irq to indicate that this
40 * device uses one of the inputs to the OR gate that feeds into the
41 * CPU NMI input.
42 */
43 #define NMI_0 10000
44 #define NMI_1 10001
45
46 typedef struct ARMSSEDeviceInfo {
47 const char *name; /* name to use for the QOM object; NULL terminates list */
48 const char *type; /* QOM type name */
49 unsigned int index; /* Which of the N devices of this type is this ? */
50 hwaddr addr;
51 hwaddr size; /* only needed for TYPE_UNIMPLEMENTED_DEVICE */
52 int ppc; /* Index of APB PPC this device is wired up to, or NO_PPC */
53 int ppc_port; /* Port number of this device on the PPC */
54 int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1, or NMI_0 or NMI_1 */
55 bool slowclk; /* true if device uses the slow 32KHz clock */
56 } ARMSSEDeviceInfo;
57
58 struct ARMSSEInfo {
59 const char *name;
60 const char *cpu_type;
61 uint32_t sse_version;
62 int sram_banks;
63 uint32_t sram_bank_base;
64 int num_cpus;
65 uint32_t sys_version;
66 uint32_t iidr;
67 uint32_t cpuwait_rst;
68 bool has_mhus;
69 bool has_cachectrl;
70 bool has_cpusecctrl;
71 bool has_cpuid;
72 bool has_cpu_pwrctrl;
73 bool has_sse_counter;
74 bool has_tcms;
75 uint8_t props_count;
76 const Property *props;
77 const ARMSSEDeviceInfo *devinfo;
78 const bool *irq_is_common;
79 };
80
81 static const Property iotkit_properties[] = {
82 DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
83 MemoryRegion *),
84 DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
85 DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
86 DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
87 DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
88 DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
89 DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
90 DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
91 };
92
93 static const Property sse200_properties[] = {
94 DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
95 MemoryRegion *),
96 DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
97 DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
98 DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
99 DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
100 DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
101 DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
102 DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
103 DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
104 DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
105 DEFINE_PROP_UINT32("CPU1_MPU_NS", ARMSSE, cpu_mpu_ns[1], 8),
106 DEFINE_PROP_UINT32("CPU1_MPU_S", ARMSSE, cpu_mpu_s[1], 8),
107 };
108
109 static const Property sse300_properties[] = {
110 DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
111 MemoryRegion *),
112 DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
113 DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 18),
114 DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
115 DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
116 DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
117 DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
118 DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
119 };
120
121 static const Property sse310_properties[] = {
122 DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
123 MemoryRegion *),
124 DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
125 DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 21),
126 DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
127 DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
128 DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
129 DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
130 DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
131 };
132
133 static const ARMSSEDeviceInfo iotkit_devices[] = {
134 {
135 .name = "timer0",
136 .type = TYPE_CMSDK_APB_TIMER,
137 .index = 0,
138 .addr = 0x40000000,
139 .ppc = 0,
140 .ppc_port = 0,
141 .irq = 3,
142 },
143 {
144 .name = "timer1",
145 .type = TYPE_CMSDK_APB_TIMER,
146 .index = 1,
147 .addr = 0x40001000,
148 .ppc = 0,
149 .ppc_port = 1,
150 .irq = 4,
151 },
152 {
153 .name = "s32ktimer",
154 .type = TYPE_CMSDK_APB_TIMER,
155 .index = 2,
156 .addr = 0x4002f000,
157 .ppc = 1,
158 .ppc_port = 0,
159 .irq = 2,
160 .slowclk = true,
161 },
162 {
163 .name = "dualtimer",
164 .type = TYPE_CMSDK_APB_DUALTIMER,
165 .index = 0,
166 .addr = 0x40002000,
167 .ppc = 0,
168 .ppc_port = 2,
169 .irq = 5,
170 },
171 {
172 .name = "s32kwatchdog",
173 .type = TYPE_CMSDK_APB_WATCHDOG,
174 .index = 0,
175 .addr = 0x5002e000,
176 .ppc = NO_PPC,
177 .irq = NMI_0,
178 .slowclk = true,
179 },
180 {
181 .name = "nswatchdog",
182 .type = TYPE_CMSDK_APB_WATCHDOG,
183 .index = 1,
184 .addr = 0x40081000,
185 .ppc = NO_PPC,
186 .irq = 1,
187 },
188 {
189 .name = "swatchdog",
190 .type = TYPE_CMSDK_APB_WATCHDOG,
191 .index = 2,
192 .addr = 0x50081000,
193 .ppc = NO_PPC,
194 .irq = NMI_1,
195 },
196 {
197 .name = "armsse-sysinfo",
198 .type = TYPE_IOTKIT_SYSINFO,
199 .index = 0,
200 .addr = 0x40020000,
201 .ppc = NO_PPC,
202 .irq = NO_IRQ,
203 },
204 {
205 .name = "armsse-sysctl",
206 .type = TYPE_IOTKIT_SYSCTL,
207 .index = 0,
208 .addr = 0x50021000,
209 .ppc = NO_PPC,
210 .irq = NO_IRQ,
211 },
212 {
213 .name = NULL,
214 }
215 };
216
217 static const ARMSSEDeviceInfo sse200_devices[] = {
218 {
219 .name = "timer0",
220 .type = TYPE_CMSDK_APB_TIMER,
221 .index = 0,
222 .addr = 0x40000000,
223 .ppc = 0,
224 .ppc_port = 0,
225 .irq = 3,
226 },
227 {
228 .name = "timer1",
229 .type = TYPE_CMSDK_APB_TIMER,
230 .index = 1,
231 .addr = 0x40001000,
232 .ppc = 0,
233 .ppc_port = 1,
234 .irq = 4,
235 },
236 {
237 .name = "s32ktimer",
238 .type = TYPE_CMSDK_APB_TIMER,
239 .index = 2,
240 .addr = 0x4002f000,
241 .ppc = 1,
242 .ppc_port = 0,
243 .irq = 2,
244 .slowclk = true,
245 },
246 {
247 .name = "dualtimer",
248 .type = TYPE_CMSDK_APB_DUALTIMER,
249 .index = 0,
250 .addr = 0x40002000,
251 .ppc = 0,
252 .ppc_port = 2,
253 .irq = 5,
254 },
255 {
256 .name = "s32kwatchdog",
257 .type = TYPE_CMSDK_APB_WATCHDOG,
258 .index = 0,
259 .addr = 0x5002e000,
260 .ppc = NO_PPC,
261 .irq = NMI_0,
262 .slowclk = true,
263 },
264 {
265 .name = "nswatchdog",
266 .type = TYPE_CMSDK_APB_WATCHDOG,
267 .index = 1,
268 .addr = 0x40081000,
269 .ppc = NO_PPC,
270 .irq = 1,
271 },
272 {
273 .name = "swatchdog",
274 .type = TYPE_CMSDK_APB_WATCHDOG,
275 .index = 2,
276 .addr = 0x50081000,
277 .ppc = NO_PPC,
278 .irq = NMI_1,
279 },
280 {
281 .name = "armsse-sysinfo",
282 .type = TYPE_IOTKIT_SYSINFO,
283 .index = 0,
284 .addr = 0x40020000,
285 .ppc = NO_PPC,
286 .irq = NO_IRQ,
287 },
288 {
289 .name = "armsse-sysctl",
290 .type = TYPE_IOTKIT_SYSCTL,
291 .index = 0,
292 .addr = 0x50021000,
293 .ppc = NO_PPC,
294 .irq = NO_IRQ,
295 },
296 {
297 .name = "CPU0CORE_PPU",
298 .type = TYPE_UNIMPLEMENTED_DEVICE,
299 .index = 0,
300 .addr = 0x50023000,
301 .size = 0x1000,
302 .ppc = NO_PPC,
303 .irq = NO_IRQ,
304 },
305 {
306 .name = "CPU1CORE_PPU",
307 .type = TYPE_UNIMPLEMENTED_DEVICE,
308 .index = 1,
309 .addr = 0x50025000,
310 .size = 0x1000,
311 .ppc = NO_PPC,
312 .irq = NO_IRQ,
313 },
314 {
315 .name = "DBG_PPU",
316 .type = TYPE_UNIMPLEMENTED_DEVICE,
317 .index = 2,
318 .addr = 0x50029000,
319 .size = 0x1000,
320 .ppc = NO_PPC,
321 .irq = NO_IRQ,
322 },
323 {
324 .name = "RAM0_PPU",
325 .type = TYPE_UNIMPLEMENTED_DEVICE,
326 .index = 3,
327 .addr = 0x5002a000,
328 .size = 0x1000,
329 .ppc = NO_PPC,
330 .irq = NO_IRQ,
331 },
332 {
333 .name = "RAM1_PPU",
334 .type = TYPE_UNIMPLEMENTED_DEVICE,
335 .index = 4,
336 .addr = 0x5002b000,
337 .size = 0x1000,
338 .ppc = NO_PPC,
339 .irq = NO_IRQ,
340 },
341 {
342 .name = "RAM2_PPU",
343 .type = TYPE_UNIMPLEMENTED_DEVICE,
344 .index = 5,
345 .addr = 0x5002c000,
346 .size = 0x1000,
347 .ppc = NO_PPC,
348 .irq = NO_IRQ,
349 },
350 {
351 .name = "RAM3_PPU",
352 .type = TYPE_UNIMPLEMENTED_DEVICE,
353 .index = 6,
354 .addr = 0x5002d000,
355 .size = 0x1000,
356 .ppc = NO_PPC,
357 .irq = NO_IRQ,
358 },
359 {
360 .name = "SYS_PPU",
361 .type = TYPE_UNIMPLEMENTED_DEVICE,
362 .index = 7,
363 .addr = 0x50022000,
364 .size = 0x1000,
365 .ppc = NO_PPC,
366 .irq = NO_IRQ,
367 },
368 {
369 .name = NULL,
370 }
371 };
372
373 static const ARMSSEDeviceInfo sse300_devices[] = {
374 {
375 .name = "timer0",
376 .type = TYPE_SSE_TIMER,
377 .index = 0,
378 .addr = 0x48000000,
379 .ppc = 0,
380 .ppc_port = 0,
381 .irq = 3,
382 },
383 {
384 .name = "timer1",
385 .type = TYPE_SSE_TIMER,
386 .index = 1,
387 .addr = 0x48001000,
388 .ppc = 0,
389 .ppc_port = 1,
390 .irq = 4,
391 },
392 {
393 .name = "timer2",
394 .type = TYPE_SSE_TIMER,
395 .index = 2,
396 .addr = 0x48002000,
397 .ppc = 0,
398 .ppc_port = 2,
399 .irq = 5,
400 },
401 {
402 .name = "timer3",
403 .type = TYPE_SSE_TIMER,
404 .index = 3,
405 .addr = 0x48003000,
406 .ppc = 0,
407 .ppc_port = 5,
408 .irq = 27,
409 },
410 {
411 .name = "s32ktimer",
412 .type = TYPE_CMSDK_APB_TIMER,
413 .index = 0,
414 .addr = 0x4802f000,
415 .ppc = 1,
416 .ppc_port = 0,
417 .irq = 2,
418 .slowclk = true,
419 },
420 {
421 .name = "s32kwatchdog",
422 .type = TYPE_CMSDK_APB_WATCHDOG,
423 .index = 0,
424 .addr = 0x5802e000,
425 .ppc = NO_PPC,
426 .irq = NMI_0,
427 .slowclk = true,
428 },
429 {
430 .name = "watchdog",
431 .type = TYPE_UNIMPLEMENTED_DEVICE,
432 .index = 0,
433 .addr = 0x48040000,
434 .size = 0x2000,
435 .ppc = NO_PPC,
436 .irq = NO_IRQ,
437 },
438 {
439 .name = "armsse-sysinfo",
440 .type = TYPE_IOTKIT_SYSINFO,
441 .index = 0,
442 .addr = 0x48020000,
443 .ppc = NO_PPC,
444 .irq = NO_IRQ,
445 },
446 {
447 .name = "armsse-sysctl",
448 .type = TYPE_IOTKIT_SYSCTL,
449 .index = 0,
450 .addr = 0x58021000,
451 .ppc = NO_PPC,
452 .irq = NO_IRQ,
453 },
454 {
455 .name = "SYS_PPU",
456 .type = TYPE_UNIMPLEMENTED_DEVICE,
457 .index = 1,
458 .addr = 0x58022000,
459 .size = 0x1000,
460 .ppc = NO_PPC,
461 .irq = NO_IRQ,
462 },
463 {
464 .name = "CPU0CORE_PPU",
465 .type = TYPE_UNIMPLEMENTED_DEVICE,
466 .index = 2,
467 .addr = 0x58023000,
468 .size = 0x1000,
469 .ppc = NO_PPC,
470 .irq = NO_IRQ,
471 },
472 {
473 .name = "MGMT_PPU",
474 .type = TYPE_UNIMPLEMENTED_DEVICE,
475 .index = 3,
476 .addr = 0x58028000,
477 .size = 0x1000,
478 .ppc = NO_PPC,
479 .irq = NO_IRQ,
480 },
481 {
482 .name = "DEBUG_PPU",
483 .type = TYPE_UNIMPLEMENTED_DEVICE,
484 .index = 4,
485 .addr = 0x58029000,
486 .size = 0x1000,
487 .ppc = NO_PPC,
488 .irq = NO_IRQ,
489 },
490 {
491 .name = NULL,
492 }
493 };
494
495 static const ARMSSEDeviceInfo sse310_devices[] = {
496 {
497 .name = "timer0",
498 .type = TYPE_SSE_TIMER,
499 .index = 0,
500 .addr = 0x48000000,
501 .ppc = 0,
502 .ppc_port = 0,
503 .irq = 3,
504 },
505 {
506 .name = "timer1",
507 .type = TYPE_SSE_TIMER,
508 .index = 1,
509 .addr = 0x48001000,
510 .ppc = 0,
511 .ppc_port = 1,
512 .irq = 4,
513 },
514 {
515 .name = "timer2",
516 .type = TYPE_SSE_TIMER,
517 .index = 2,
518 .addr = 0x48002000,
519 .ppc = 0,
520 .ppc_port = 2,
521 .irq = 5,
522 },
523 {
524 .name = "timer3",
525 .type = TYPE_SSE_TIMER,
526 .index = 3,
527 .addr = 0x48003000,
528 .ppc = 0,
529 .ppc_port = 5,
530 .irq = 27,
531 },
532 {
533 .name = "s32ktimer",
534 .type = TYPE_CMSDK_APB_TIMER,
535 .index = 0,
536 .addr = 0x4802f000,
537 .ppc = 1,
538 .ppc_port = 0,
539 .irq = 2,
540 .slowclk = true,
541 },
542 {
543 .name = "s32kwatchdog",
544 .type = TYPE_CMSDK_APB_WATCHDOG,
545 .index = 0,
546 .addr = 0x5802e000,
547 .ppc = NO_PPC,
548 .irq = NMI_0,
549 .slowclk = true,
550 },
551 {
552 .name = "watchdog",
553 .type = TYPE_UNIMPLEMENTED_DEVICE,
554 .index = 0,
555 .addr = 0x48040000,
556 .size = 0x2000,
557 .ppc = NO_PPC,
558 .irq = NO_IRQ,
559 },
560 {
561 .name = "armsse-sysinfo",
562 .type = TYPE_IOTKIT_SYSINFO,
563 .index = 0,
564 .addr = 0x48020000,
565 .ppc = NO_PPC,
566 .irq = NO_IRQ,
567 },
568 {
569 .name = "armsse-sysctl",
570 .type = TYPE_IOTKIT_SYSCTL,
571 .index = 0,
572 .addr = 0x58021000,
573 .ppc = NO_PPC,
574 .irq = NO_IRQ,
575 },
576 {
577 .name = "SYS_PPU",
578 .type = TYPE_UNIMPLEMENTED_DEVICE,
579 .index = 1,
580 .addr = 0x58022000,
581 .size = 0x1000,
582 .ppc = NO_PPC,
583 .irq = NO_IRQ,
584 },
585 {
586 .name = "CPU0CORE_PPU",
587 .type = TYPE_UNIMPLEMENTED_DEVICE,
588 .index = 2,
589 .addr = 0x58023000,
590 .size = 0x1000,
591 .ppc = NO_PPC,
592 .irq = NO_IRQ,
593 },
594 {
595 .name = "MGMT_PPU",
596 .type = TYPE_UNIMPLEMENTED_DEVICE,
597 .index = 3,
598 .addr = 0x58028000,
599 .size = 0x1000,
600 .ppc = NO_PPC,
601 .irq = NO_IRQ,
602 },
603 {
604 .name = "DEBUG_PPU",
605 .type = TYPE_UNIMPLEMENTED_DEVICE,
606 .index = 4,
607 .addr = 0x58029000,
608 .size = 0x1000,
609 .ppc = NO_PPC,
610 .irq = NO_IRQ,
611 },
612 {
613 .name = "NPU0_PPU",
614 .type = TYPE_UNIMPLEMENTED_DEVICE,
615 .index = 5,
616 .addr = 0x5802a000,
617 .size = 0x1000,
618 .ppc = NO_PPC,
619 .irq = NO_IRQ,
620 },
621 {
622 .name = "NPU0_CFG",
623 .type = TYPE_UNIMPLEMENTED_DEVICE,
624 .index = 6,
625 .addr = 0x40004000,
626 .size = 0x1000,
627 .ppc = NO_PPC,
628 .irq = NO_IRQ,
629 },
630 {
631 .name = NULL,
632 }
633 };
634
635 /* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
636 static const bool sse200_irq_is_common[32] = {
637 [0 ... 5] = true,
638 /* 6, 7: per-CPU MHU interrupts */
639 [8 ... 12] = true,
640 /* 13: per-CPU icache interrupt */
641 /* 14: reserved */
642 [15 ... 20] = true,
643 /* 21: reserved */
644 [22 ... 26] = true,
645 /* 27: reserved */
646 /* 28, 29: per-CPU CTI interrupts */
647 /* 30, 31: reserved */
648 };
649
650 static const bool sse300_irq_is_common[32] = {
651 [0 ... 5] = true,
652 /* 6, 7: per-CPU MHU interrupts */
653 [8 ... 12] = true,
654 /* 13: reserved */
655 [14 ... 16] = true,
656 /* 17-25: reserved */
657 [26 ... 27] = true,
658 /* 28, 29: per-CPU CTI interrupts */
659 /* 30, 31: reserved */
660 };
661
662 static const bool sse310_irq_is_common[32] = {
663 [0 ... 5] = true,
664 /* 6-8: reserved */
665 [9 ... 12] = true,
666 /* 13: reserved */
667 [14] = true,
668 /* 15: reserved */
669 [16] = true,
670 /* 17-26: reserved */
671 [27] = true,
672 /* 28, 29: per-CPU CTI interrupts */
673 /* 30, 31: reserved */
674 };
675
676 static const ARMSSEInfo armsse_variants[] = {
677 {
678 .name = TYPE_IOTKIT,
679 .sse_version = ARMSSE_IOTKIT,
680 .cpu_type = ARM_CPU_TYPE_NAME("cortex-m33"),
681 .sram_banks = 1,
682 .sram_bank_base = 0x20000000,
683 .num_cpus = 1,
684 .sys_version = 0x41743,
685 .iidr = 0,
686 .cpuwait_rst = 0,
687 .has_mhus = false,
688 .has_cachectrl = false,
689 .has_cpusecctrl = false,
690 .has_cpuid = false,
691 .has_cpu_pwrctrl = false,
692 .has_sse_counter = false,
693 .has_tcms = false,
694 .props = iotkit_properties,
695 .props_count = ARRAY_SIZE(iotkit_properties),
696 .devinfo = iotkit_devices,
697 .irq_is_common = sse200_irq_is_common,
698 },
699 {
700 .name = TYPE_SSE200,
701 .sse_version = ARMSSE_SSE200,
702 .cpu_type = ARM_CPU_TYPE_NAME("cortex-m33"),
703 .sram_banks = 4,
704 .sram_bank_base = 0x20000000,
705 .num_cpus = 2,
706 .sys_version = 0x22041743,
707 .iidr = 0,
708 .cpuwait_rst = 2,
709 .has_mhus = true,
710 .has_cachectrl = true,
711 .has_cpusecctrl = true,
712 .has_cpuid = true,
713 .has_cpu_pwrctrl = false,
714 .has_sse_counter = false,
715 .has_tcms = false,
716 .props = sse200_properties,
717 .props_count = ARRAY_SIZE(sse200_properties),
718 .devinfo = sse200_devices,
719 .irq_is_common = sse200_irq_is_common,
720 },
721 {
722 .name = TYPE_SSE300,
723 .sse_version = ARMSSE_SSE300,
724 .cpu_type = ARM_CPU_TYPE_NAME("cortex-m55"),
725 .sram_banks = 2,
726 .sram_bank_base = 0x21000000,
727 .num_cpus = 1,
728 .sys_version = 0x7e00043b,
729 .iidr = 0x74a0043b,
730 .cpuwait_rst = 0,
731 .has_mhus = false,
732 .has_cachectrl = false,
733 .has_cpusecctrl = true,
734 .has_cpuid = true,
735 .has_cpu_pwrctrl = true,
736 .has_sse_counter = true,
737 .has_tcms = true,
738 .props = sse300_properties,
739 .props_count = ARRAY_SIZE(sse300_properties),
740 .devinfo = sse300_devices,
741 .irq_is_common = sse300_irq_is_common,
742 },
743 {
744 .name = TYPE_SSE310,
745 .sse_version = ARMSSE_SSE310,
746 .cpu_type = ARM_CPU_TYPE_NAME("cortex-m85"),
747 .sram_banks = 2,
748 .sram_bank_base = 0x21000000,
749 .num_cpus = 1,
750 .sys_version = 0x7e10043b,
751 .iidr = 0x74e0043b,
752 .cpuwait_rst = 0,
753 .has_mhus = false,
754 .has_cachectrl = false,
755 .has_cpusecctrl = true,
756 .has_cpuid = true,
757 .has_cpu_pwrctrl = true,
758 .has_sse_counter = true,
759 .has_tcms = true,
760 .props = sse310_properties,
761 .props_count = ARRAY_SIZE(sse310_properties),
762 .devinfo = sse310_devices,
763 .irq_is_common = sse310_irq_is_common,
764 }
765 };
766
767 static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
768 {
769 /* Return the SYS_CONFIG value for this SSE */
770 uint32_t sys_config;
771
772 switch (info->sse_version) {
773 case ARMSSE_IOTKIT:
774 sys_config = 0;
775 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
776 sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
777 break;
778 case ARMSSE_SSE200:
779 sys_config = 0;
780 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
781 sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
782 sys_config = deposit32(sys_config, 24, 4, 2);
783 if (info->num_cpus > 1) {
784 sys_config = deposit32(sys_config, 10, 1, 1);
785 sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
786 sys_config = deposit32(sys_config, 28, 4, 2);
787 }
788 break;
789 case ARMSSE_SSE300:
790 sys_config = 0;
791 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
792 sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
793 sys_config = deposit32(sys_config, 16, 3, 3); /* CPU0 = Cortex-M55 */
794 break;
795 case ARMSSE_SSE310:
796 sys_config = 0;
797 sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
798 sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
799 sys_config = deposit32(sys_config, 10, 1, 0); /* No CoreSight SoC */
800 sys_config = deposit32(sys_config, 11, 2, 0); /* Basic level PI */
801 sys_config = deposit32(sys_config, 16, 3, 4); /* CPU0 = Cortex-M85 */
802 break;
803 default:
804 g_assert_not_reached();
805 }
806 return sys_config;
807 }
808
809 /* Clock frequency in HZ of the 32KHz "slow clock" */
810 #define S32KCLK (32 * 1000)
811
812 /*
813 * Create an alias region in @container of @size bytes starting at @base
814 * which mirrors the memory starting at @orig.
815 */
816 static void make_alias(ARMSSE *s, MemoryRegion *mr, MemoryRegion *container,
817 const char *name, hwaddr base, hwaddr size, hwaddr orig)
818 {
819 memory_region_init_alias(mr, NULL, name, container, orig, size);
820 /* The alias is even lower priority than unimplemented_device regions */
821 memory_region_add_subregion_overlap(container, base, mr, -1500);
822 }
823
824 static void irq_status_forwarder(void *opaque, int n, int level)
825 {
826 qemu_irq destirq = opaque;
827
828 qemu_set_irq(destirq, level);
829 }
830
831 static void nsccfg_handler(void *opaque, int n, int level)
832 {
833 ARMSSE *s = ARM_SSE(opaque);
834
835 s->nsccfg = level;
836 }
837
838 static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
839 {
840 /* Each of the 4 AHB and 4 APB PPCs that might be present in a
841 * system using the ARMSSE has a collection of control lines which
842 * are provided by the security controller and which we want to
843 * expose as control lines on the ARMSSE device itself, so the
844 * code using the ARMSSE can wire them up to the PPCs.
845 */
846 SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
847 DeviceState *armssedev = DEVICE(s);
848 DeviceState *dev_secctl = DEVICE(&s->secctl);
849 DeviceState *dev_splitter = DEVICE(splitter);
850 char *name;
851
852 name = g_strdup_printf("%s_nonsec", ppcname);
853 qdev_pass_gpios(dev_secctl, armssedev, name);
854 g_free(name);
855 name = g_strdup_printf("%s_ap", ppcname);
856 qdev_pass_gpios(dev_secctl, armssedev, name);
857 g_free(name);
858 name = g_strdup_printf("%s_irq_enable", ppcname);
859 qdev_pass_gpios(dev_secctl, armssedev, name);
860 g_free(name);
861 name = g_strdup_printf("%s_irq_clear", ppcname);
862 qdev_pass_gpios(dev_secctl, armssedev, name);
863 g_free(name);
864
865 /* irq_status is a little more tricky, because we need to
866 * split it so we can send it both to the security controller
867 * and to our OR gate for the NVIC interrupt line.
868 * Connect up the splitter's outputs, and create a GPIO input
869 * which will pass the line state to the input splitter.
870 */
871 name = g_strdup_printf("%s_irq_status", ppcname);
872 qdev_connect_gpio_out(dev_splitter, 0,
873 qdev_get_gpio_in_named(dev_secctl,
874 name, 0));
875 qdev_connect_gpio_out(dev_splitter, 1,
876 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
877 s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
878 qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
879 s->irq_status_in[ppcnum], name, 1);
880 g_free(name);
881 }
882
883 static void armsse_forward_sec_resp_cfg(ARMSSE *s)
884 {
885 /* Forward the 3rd output from the splitter device as a
886 * named GPIO output of the armsse object.
887 */
888 DeviceState *dev = DEVICE(s);
889 DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
890
891 qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
892 s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
893 s->sec_resp_cfg, 1);
894 qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
895 }
896
897 static void armsse_init(Object *obj)
898 {
899 ARMSSE *s = ARM_SSE(obj);
900 ARMSSEClass *asc = ARM_SSE_GET_CLASS(obj);
901 const ARMSSEInfo *info = asc->info;
902 const ARMSSEDeviceInfo *devinfo;
903 int i;
904
905 assert(info->sram_banks <= MAX_SRAM_BANKS);
906 assert(info->num_cpus <= SSE_MAX_CPUS);
907
908 s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK", NULL, NULL, 0);
909 s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL, 0);
910
911 memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
912
913 for (i = 0; i < info->num_cpus; i++) {
914 /*
915 * We put each CPU in its own cluster as they are logically
916 * distinct and may be configured differently.
917 */
918 char *name;
919
920 name = g_strdup_printf("cluster%d", i);
921 object_initialize_child(obj, name, &s->cluster[i], TYPE_CPU_CLUSTER);
922 qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
923 g_free(name);
924
925 name = g_strdup_printf("armv7m%d", i);
926 object_initialize_child(OBJECT(&s->cluster[i]), name, &s->armv7m[i],
927 TYPE_ARMV7M);
928 qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type", info->cpu_type);
929 g_free(name);
930 name = g_strdup_printf("arm-sse-cpu-container%d", i);
931 memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
932 g_free(name);
933 if (i > 0) {
934 name = g_strdup_printf("arm-sse-container-alias%d", i);
935 memory_region_init_alias(&s->container_alias[i - 1], obj,
936 name, &s->container, 0, UINT64_MAX);
937 g_free(name);
938 }
939 }
940
941 for (devinfo = info->devinfo; devinfo->name; devinfo++) {
942 assert(devinfo->ppc == NO_PPC || devinfo->ppc < ARRAY_SIZE(s->apb_ppc));
943 if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
944 assert(devinfo->index < ARRAY_SIZE(s->timer));
945 object_initialize_child(obj, devinfo->name,
946 &s->timer[devinfo->index],
947 TYPE_CMSDK_APB_TIMER);
948 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
949 assert(devinfo->index == 0);
950 object_initialize_child(obj, devinfo->name, &s->dualtimer,
951 TYPE_CMSDK_APB_DUALTIMER);
952 } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
953 assert(devinfo->index < ARRAY_SIZE(s->sse_timer));
954 object_initialize_child(obj, devinfo->name,
955 &s->sse_timer[devinfo->index],
956 TYPE_SSE_TIMER);
957 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
958 assert(devinfo->index < ARRAY_SIZE(s->cmsdk_watchdog));
959 object_initialize_child(obj, devinfo->name,
960 &s->cmsdk_watchdog[devinfo->index],
961 TYPE_CMSDK_APB_WATCHDOG);
962 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
963 assert(devinfo->index == 0);
964 object_initialize_child(obj, devinfo->name, &s->sysinfo,
965 TYPE_IOTKIT_SYSINFO);
966 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
967 assert(devinfo->index == 0);
968 object_initialize_child(obj, devinfo->name, &s->sysctl,
969 TYPE_IOTKIT_SYSCTL);
970 } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
971 assert(devinfo->index < ARRAY_SIZE(s->unimp));
972 object_initialize_child(obj, devinfo->name,
973 &s->unimp[devinfo->index],
974 TYPE_UNIMPLEMENTED_DEVICE);
975 } else {
976 g_assert_not_reached();
977 }
978 }
979
980 object_initialize_child(obj, "secctl", &s->secctl, TYPE_IOTKIT_SECCTL);
981
982 for (i = 0; i < ARRAY_SIZE(s->apb_ppc); i++) {
983 g_autofree char *name = g_strdup_printf("apb-ppc%d", i);
984 object_initialize_child(obj, name, &s->apb_ppc[i], TYPE_TZ_PPC);
985 }
986
987 for (i = 0; i < info->sram_banks; i++) {
988 char *name = g_strdup_printf("mpc%d", i);
989 object_initialize_child(obj, name, &s->mpc[i], TYPE_TZ_MPC);
990 g_free(name);
991 }
992 object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
993 TYPE_OR_IRQ);
994
995 for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
996 char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
997 SplitIRQ *splitter = &s->mpc_irq_splitter[i];
998
999 object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
1000 g_free(name);
1001 }
1002
1003 if (info->has_mhus) {
1004 object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
1005 object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
1006 }
1007 if (info->has_cachectrl) {
1008 for (i = 0; i < info->num_cpus; i++) {
1009 char *name = g_strdup_printf("cachectrl%d", i);
1010
1011 object_initialize_child(obj, name, &s->cachectrl[i],
1012 TYPE_UNIMPLEMENTED_DEVICE);
1013 g_free(name);
1014 }
1015 }
1016 if (info->has_cpusecctrl) {
1017 for (i = 0; i < info->num_cpus; i++) {
1018 char *name = g_strdup_printf("cpusecctrl%d", i);
1019
1020 object_initialize_child(obj, name, &s->cpusecctrl[i],
1021 TYPE_UNIMPLEMENTED_DEVICE);
1022 g_free(name);
1023 }
1024 }
1025 if (info->has_cpuid) {
1026 for (i = 0; i < info->num_cpus; i++) {
1027 char *name = g_strdup_printf("cpuid%d", i);
1028
1029 object_initialize_child(obj, name, &s->cpuid[i],
1030 TYPE_ARMSSE_CPUID);
1031 g_free(name);
1032 }
1033 }
1034 if (info->has_cpu_pwrctrl) {
1035 for (i = 0; i < info->num_cpus; i++) {
1036 char *name = g_strdup_printf("cpu_pwrctrl%d", i);
1037
1038 object_initialize_child(obj, name, &s->cpu_pwrctrl[i],
1039 TYPE_ARMSSE_CPU_PWRCTRL);
1040 g_free(name);
1041 }
1042 }
1043 if (info->has_sse_counter) {
1044 object_initialize_child(obj, "sse-counter", &s->sse_counter,
1045 TYPE_SSE_COUNTER);
1046 }
1047
1048 object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, TYPE_OR_IRQ);
1049 object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
1050 TYPE_OR_IRQ);
1051 object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
1052 TYPE_SPLIT_IRQ);
1053 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
1054 char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
1055 SplitIRQ *splitter = &s->ppc_irq_splitter[i];
1056
1057 object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
1058 g_free(name);
1059 }
1060 if (info->num_cpus > 1) {
1061 for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
1062 if (info->irq_is_common[i]) {
1063 char *name = g_strdup_printf("cpu-irq-splitter%d", i);
1064 SplitIRQ *splitter = &s->cpu_irq_splitter[i];
1065
1066 object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
1067 g_free(name);
1068 }
1069 }
1070 }
1071 }
1072
1073 static void armsse_exp_irq(void *opaque, int n, int level)
1074 {
1075 qemu_irq *irqarray = opaque;
1076
1077 qemu_set_irq(irqarray[n], level);
1078 }
1079
1080 static void armsse_mpcexp_status(void *opaque, int n, int level)
1081 {
1082 ARMSSE *s = ARM_SSE(opaque);
1083 qemu_set_irq(s->mpcexp_status_in[n], level);
1084 }
1085
1086 static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
1087 {
1088 /*
1089 * Return a qemu_irq which can be used to signal IRQ n to
1090 * all CPUs in the SSE.
1091 */
1092 ARMSSEClass *asc = ARM_SSE_GET_CLASS(s);
1093 const ARMSSEInfo *info = asc->info;
1094
1095 assert(info->irq_is_common[irqno]);
1096
1097 if (info->num_cpus == 1) {
1098 /* Only one CPU -- just connect directly to it */
1099 return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
1100 } else {
1101 /* Connect to the splitter which feeds all CPUs */
1102 return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
1103 }
1104 }
1105
1106 static void armsse_realize(DeviceState *dev, Error **errp)
1107 {
1108 ERRP_GUARD();
1109 ARMSSE *s = ARM_SSE(dev);
1110 ARMSSEClass *asc = ARM_SSE_GET_CLASS(dev);
1111 const ARMSSEInfo *info = asc->info;
1112 const ARMSSEDeviceInfo *devinfo;
1113 int i;
1114 MemoryRegion *mr;
1115 SysBusDevice *sbd_apb_ppc0;
1116 SysBusDevice *sbd_secctl;
1117 DeviceState *dev_apb_ppc0;
1118 DeviceState *dev_apb_ppc1;
1119 DeviceState *dev_secctl;
1120 DeviceState *dev_splitter;
1121 uint32_t addr_width_max;
1122
1123 if (!s->board_memory) {
1124 error_setg(errp, "memory property was not set");
1125 return;
1126 }
1127
1128 if (!clock_has_source(s->mainclk)) {
1129 error_setg(errp, "MAINCLK clock was not connected");
1130 }
1131 if (!clock_has_source(s->s32kclk)) {
1132 error_setg(errp, "S32KCLK clock was not connected");
1133 }
1134
1135 assert(info->num_cpus <= SSE_MAX_CPUS);
1136
1137 /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
1138 assert(is_power_of_2(info->sram_banks));
1139 addr_width_max = 24 - ctz32(info->sram_banks);
1140 if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
1141 error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
1142 addr_width_max);
1143 return;
1144 }
1145
1146 /* Handling of which devices should be available only to secure
1147 * code is usually done differently for M profile than for A profile.
1148 * Instead of putting some devices only into the secure address space,
1149 * devices exist in both address spaces but with hard-wired security
1150 * permissions that will cause the CPU to fault for non-secure accesses.
1151 *
1152 * The ARMSSE has an IDAU (Implementation Defined Access Unit),
1153 * which specifies hard-wired security permissions for different
1154 * areas of the physical address space. For the ARMSSE IDAU, the
1155 * top 4 bits of the physical address are the IDAU region ID, and
1156 * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
1157 * region, otherwise it is an S region.
1158 *
1159 * The various devices and RAMs are generally all mapped twice,
1160 * once into a region that the IDAU defines as secure and once
1161 * into a non-secure region. They sit behind either a Memory
1162 * Protection Controller (for RAM) or a Peripheral Protection
1163 * Controller (for devices), which allow a more fine grained
1164 * configuration of whether non-secure accesses are permitted.
1165 *
1166 * (The other place that guest software can configure security
1167 * permissions is in the architected SAU (Security Attribution
1168 * Unit), which is entirely inside the CPU. The IDAU can upgrade
1169 * the security attributes for a region to more restrictive than
1170 * the SAU specifies, but cannot downgrade them.)
1171 *
1172 * 0x10000000..0x1fffffff alias of 0x00000000..0x0fffffff
1173 * 0x20000000..0x2007ffff 32KB FPGA block RAM
1174 * 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff
1175 * 0x40000000..0x4000ffff base peripheral region 1
1176 * 0x40010000..0x4001ffff CPU peripherals (none for ARMSSE)
1177 * 0x40020000..0x4002ffff system control element peripherals
1178 * 0x40080000..0x400fffff base peripheral region 2
1179 * 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
1180 */
1181
1182 memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
1183
1184 for (i = 0; i < info->num_cpus; i++) {
1185 DeviceState *cpudev = DEVICE(&s->armv7m[i]);
1186 Object *cpuobj = OBJECT(&s->armv7m[i]);
1187 int j;
1188 char *gpioname;
1189
1190 qdev_connect_clock_in(cpudev, "cpuclk", s->mainclk);
1191 /* The SSE subsystems do not wire up a systick refclk */
1192
1193 qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + NUM_SSE_IRQS);
1194 /*
1195 * In real hardware the initial Secure VTOR is set from the INITSVTOR*
1196 * registers in the IoT Kit System Control Register block. In QEMU
1197 * we set the initial value here, and also the reset value of the
1198 * sysctl register, from this object's QOM init-svtor property.
1199 * If the guest changes the INITSVTOR* registers at runtime then the
1200 * code in iotkit-sysctl.c will update the CPU init-svtor property
1201 * (which will then take effect on the next CPU warm-reset).
1202 *
1203 * Note that typically a board using the SSE-200 will have a system
1204 * control processor whose boot firmware initializes the INITSVTOR*
1205 * registers before powering up the CPUs. QEMU doesn't emulate
1206 * the control processor, so instead we behave in the way that the
1207 * firmware does: the initial value should be set by the board code
1208 * (using the init-svtor property on the ARMSSE object) to match
1209 * whatever its firmware does.
1210 */
1211 qdev_prop_set_uint32(cpudev, "init-svtor", s->init_svtor);
1212 /*
1213 * CPUs start powered down if the corresponding bit in the CPUWAIT
1214 * register is 1. In real hardware the CPUWAIT register reset value is
1215 * a configurable property of the SSE-200 (via the CPUWAIT0_RST and
1216 * CPUWAIT1_RST parameters), but since all the boards we care about
1217 * start CPU0 and leave CPU1 powered off, we hard-code that in
1218 * info->cpuwait_rst for now. We can add QOM properties for this
1219 * later if necessary.
1220 */
1221 if (extract32(info->cpuwait_rst, i, 1)) {
1222 object_property_set_bool(cpuobj, "start-powered-off", true,
1223 &error_abort);
1224 }
1225 if (!s->cpu_fpu[i]) {
1226 if (!object_property_set_bool(cpuobj, "vfp", false, errp)) {
1227 return;
1228 }
1229 }
1230 if (!s->cpu_dsp[i]) {
1231 if (!object_property_set_bool(cpuobj, "dsp", false, errp)) {
1232 return;
1233 }
1234 }
1235 if (!object_property_set_uint(cpuobj, "mpu-ns-regions",
1236 s->cpu_mpu_ns[i], errp)) {
1237 return;
1238 }
1239 if (!object_property_set_uint(cpuobj, "mpu-s-regions",
1240 s->cpu_mpu_s[i], errp)) {
1241 return;
1242 }
1243
1244 if (i > 0) {
1245 memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
1246 &s->container_alias[i - 1], -1);
1247 } else {
1248 memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
1249 &s->container, -1);
1250 }
1251 object_property_set_link(cpuobj, "memory",
1252 OBJECT(&s->cpu_container[i]), &error_abort);
1253 object_property_set_link(cpuobj, "idau", OBJECT(s), &error_abort);
1254 if (!sysbus_realize(SYS_BUS_DEVICE(cpuobj), errp)) {
1255 return;
1256 }
1257 /*
1258 * The cluster must be realized after the armv7m container, as
1259 * the container's CPU object is only created on realize, and the
1260 * CPU must exist and have been parented into the cluster before
1261 * the cluster is realized.
1262 */
1263 if (!qdev_realize(DEVICE(&s->cluster[i]), NULL, errp)) {
1264 return;
1265 }
1266
1267 /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
1268 s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
1269 for (j = 0; j < s->exp_numirq; j++) {
1270 s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + NUM_SSE_IRQS);
1271 }
1272 if (i == 0) {
1273 gpioname = g_strdup("EXP_IRQ");
1274 } else {
1275 gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
1276 }
1277 qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
1278 s->exp_irqs[i],
1279 gpioname, s->exp_numirq);
1280 g_free(gpioname);
1281 }
1282
1283 /* Wire up the splitters that connect common IRQs to all CPUs */
1284 if (info->num_cpus > 1) {
1285 for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
1286 if (info->irq_is_common[i]) {
1287 Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
1288 DeviceState *devs = DEVICE(splitter);
1289 int cpunum;
1290
1291 if (!object_property_set_int(splitter, "num-lines",
1292 info->num_cpus, errp)) {
1293 return;
1294 }
1295 if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
1296 return;
1297 }
1298 for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
1299 DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
1300
1301 qdev_connect_gpio_out(devs, cpunum,
1302 qdev_get_gpio_in(cpudev, i));
1303 }
1304 }
1305 }
1306 }
1307
1308 /* Set up the big aliases first */
1309 make_alias(s, &s->alias1, &s->container, "alias 1",
1310 0x10000000, 0x10000000, 0x00000000);
1311 make_alias(s, &s->alias2, &s->container,
1312 "alias 2", 0x30000000, 0x10000000, 0x20000000);
1313 /* The 0x50000000..0x5fffffff region is not a pure alias: it has
1314 * a few extra devices that only appear there (generally the
1315 * control interfaces for the protection controllers).
1316 * We implement this by mapping those devices over the top of this
1317 * alias MR at a higher priority. Some of the devices in this range
1318 * are per-CPU, so we must put this alias in the per-cpu containers.
1319 */
1320 for (i = 0; i < info->num_cpus; i++) {
1321 make_alias(s, &s->alias3[i], &s->cpu_container[i],
1322 "alias 3", 0x50000000, 0x10000000, 0x40000000);
1323 }
1324
1325 /* Security controller */
1326 object_property_set_int(OBJECT(&s->secctl), "sse-version",
1327 info->sse_version, &error_abort);
1328 if (!sysbus_realize(SYS_BUS_DEVICE(&s->secctl), errp)) {
1329 return;
1330 }
1331 sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
1332 dev_secctl = DEVICE(&s->secctl);
1333 sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
1334 sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
1335
1336 s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
1337 qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
1338
1339 /* The sec_resp_cfg output from the security controller must be split into
1340 * multiple lines, one for each of the PPCs within the ARMSSE and one
1341 * that will be an output from the ARMSSE to the system.
1342 */
1343 if (!object_property_set_int(OBJECT(&s->sec_resp_splitter),
1344 "num-lines", 3, errp)) {
1345 return;
1346 }
1347 if (!qdev_realize(DEVICE(&s->sec_resp_splitter), NULL, errp)) {
1348 return;
1349 }
1350 dev_splitter = DEVICE(&s->sec_resp_splitter);
1351 qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
1352 qdev_get_gpio_in(dev_splitter, 0));
1353
1354 /* Each SRAM bank lives behind its own Memory Protection Controller */
1355 for (i = 0; i < info->sram_banks; i++) {
1356 char *ramname = g_strdup_printf("armsse.sram%d", i);
1357 SysBusDevice *sbd_mpc;
1358 uint32_t sram_bank_size = 1 << s->sram_addr_width;
1359
1360 memory_region_init_ram(&s->sram[i], NULL, ramname,
1361 sram_bank_size, errp);
1362 g_free(ramname);
1363 if (*errp) {
1364 return;
1365 }
1366 object_property_set_link(OBJECT(&s->mpc[i]), "downstream",
1367 OBJECT(&s->sram[i]), &error_abort);
1368 if (!sysbus_realize(SYS_BUS_DEVICE(&s->mpc[i]), errp)) {
1369 return;
1370 }
1371 /* Map the upstream end of the MPC into the right place... */
1372 sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
1373 memory_region_add_subregion(&s->container,
1374 info->sram_bank_base + i * sram_bank_size,
1375 sysbus_mmio_get_region(sbd_mpc, 1));
1376 /* ...and its register interface */
1377 memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
1378 sysbus_mmio_get_region(sbd_mpc, 0));
1379 }
1380
1381 /* We must OR together lines from the MPC splitters to go to the NVIC */
1382 if (!object_property_set_int(OBJECT(&s->mpc_irq_orgate), "num-lines",
1383 IOTS_NUM_EXP_MPC + info->sram_banks,
1384 errp)) {
1385 return;
1386 }
1387 if (!qdev_realize(DEVICE(&s->mpc_irq_orgate), NULL, errp)) {
1388 return;
1389 }
1390 qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
1391 armsse_get_common_irq_in(s, 9));
1392
1393 /* This OR gate wires together outputs from the secure watchdogs to NMI */
1394 if (!object_property_set_int(OBJECT(&s->nmi_orgate), "num-lines", 2,
1395 errp)) {
1396 return;
1397 }
1398 if (!qdev_realize(DEVICE(&s->nmi_orgate), NULL, errp)) {
1399 return;
1400 }
1401 qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
1402 qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
1403
1404 /* The SSE-300/SSE-310 has a System Counter / System Timestamp Generator */
1405 if (info->has_sse_counter) {
1406 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->sse_counter);
1407
1408 qdev_connect_clock_in(DEVICE(sbd), "CLK", s->mainclk);
1409 if (!sysbus_realize(sbd, errp)) {
1410 return;
1411 }
1412 /*
1413 * The control frame is only in the Secure region;
1414 * the status frame is in the NS region (and visible in the
1415 * S region via the alias mapping).
1416 */
1417 memory_region_add_subregion(&s->container, 0x58100000,
1418 sysbus_mmio_get_region(sbd, 0));
1419 memory_region_add_subregion(&s->container, 0x48101000,
1420 sysbus_mmio_get_region(sbd, 1));
1421 }
1422
1423 if (info->has_tcms) {
1424 /* SSE-300/SSE-310 have ITCM at 0x0000_0000 and DTCM at 0x2000_0000 */
1425 memory_region_init_ram(&s->itcm, NULL, "itcm", 512 * KiB, errp);
1426 if (*errp) {
1427 return;
1428 }
1429 memory_region_init_ram(&s->dtcm, NULL, "dtcm", 512 * KiB, errp);
1430 if (*errp) {
1431 return;
1432 }
1433 memory_region_add_subregion(&s->container, 0x00000000, &s->itcm);
1434 memory_region_add_subregion(&s->container, 0x20000000, &s->dtcm);
1435 }
1436
1437 /* Devices behind APB PPC0:
1438 * 0x40000000: timer0
1439 * 0x40001000: timer1
1440 * 0x40002000: dual timer
1441 * 0x40003000: MHU0 (SSE-200 only)
1442 * 0x40004000: MHU1 (SSE-200 only)
1443 * We must configure and realize each downstream device and connect
1444 * it to the appropriate PPC port; then we can realize the PPC and
1445 * map its upstream ends to the right place in the container.
1446 */
1447 for (devinfo = info->devinfo; devinfo->name; devinfo++) {
1448 SysBusDevice *sbd;
1449 qemu_irq irq;
1450
1451 if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
1452 sbd = SYS_BUS_DEVICE(&s->timer[devinfo->index]);
1453
1454 qdev_connect_clock_in(DEVICE(sbd), "pclk",
1455 devinfo->slowclk ? s->s32kclk : s->mainclk);
1456 if (!sysbus_realize(sbd, errp)) {
1457 return;
1458 }
1459 mr = sysbus_mmio_get_region(sbd, 0);
1460 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
1461 sbd = SYS_BUS_DEVICE(&s->dualtimer);
1462
1463 qdev_connect_clock_in(DEVICE(sbd), "TIMCLK", s->mainclk);
1464 if (!sysbus_realize(sbd, errp)) {
1465 return;
1466 }
1467 mr = sysbus_mmio_get_region(sbd, 0);
1468 } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
1469 sbd = SYS_BUS_DEVICE(&s->sse_timer[devinfo->index]);
1470
1471 assert(info->has_sse_counter);
1472 object_property_set_link(OBJECT(sbd), "counter",
1473 OBJECT(&s->sse_counter), &error_abort);
1474 if (!sysbus_realize(sbd, errp)) {
1475 return;
1476 }
1477 mr = sysbus_mmio_get_region(sbd, 0);
1478 } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
1479 sbd = SYS_BUS_DEVICE(&s->cmsdk_watchdog[devinfo->index]);
1480
1481 qdev_connect_clock_in(DEVICE(sbd), "WDOGCLK",
1482 devinfo->slowclk ? s->s32kclk : s->mainclk);
1483 if (!sysbus_realize(sbd, errp)) {
1484 return;
1485 }
1486 mr = sysbus_mmio_get_region(sbd, 0);
1487 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
1488 sbd = SYS_BUS_DEVICE(&s->sysinfo);
1489
1490 object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
1491 info->sys_version, &error_abort);
1492 object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
1493 armsse_sys_config_value(s, info),
1494 &error_abort);
1495 object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
1496 info->sse_version, &error_abort);
1497 object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
1498 info->iidr, &error_abort);
1499 if (!sysbus_realize(sbd, errp)) {
1500 return;
1501 }
1502 mr = sysbus_mmio_get_region(sbd, 0);
1503 } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
1504 /* System control registers */
1505 sbd = SYS_BUS_DEVICE(&s->sysctl);
1506
1507 object_property_set_int(OBJECT(&s->sysctl), "sse-version",
1508 info->sse_version, &error_abort);
1509 object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
1510 info->cpuwait_rst, &error_abort);
1511 object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
1512 s->init_svtor, &error_abort);
1513 object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR1_RST",
1514 s->init_svtor, &error_abort);
1515 if (!sysbus_realize(sbd, errp)) {
1516 return;
1517 }
1518 mr = sysbus_mmio_get_region(sbd, 0);
1519 } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
1520 sbd = SYS_BUS_DEVICE(&s->unimp[devinfo->index]);
1521
1522 qdev_prop_set_string(DEVICE(sbd), "name", devinfo->name);
1523 qdev_prop_set_uint64(DEVICE(sbd), "size", devinfo->size);
1524 if (!sysbus_realize(sbd, errp)) {
1525 return;
1526 }
1527 mr = sysbus_mmio_get_region(sbd, 0);
1528 } else {
1529 g_assert_not_reached();
1530 }
1531
1532 switch (devinfo->irq) {
1533 case NO_IRQ:
1534 irq = NULL;
1535 break;
1536 case 0 ... NUM_SSE_IRQS - 1:
1537 irq = armsse_get_common_irq_in(s, devinfo->irq);
1538 break;
1539 case NMI_0:
1540 case NMI_1:
1541 irq = qdev_get_gpio_in(DEVICE(&s->nmi_orgate),
1542 devinfo->irq - NMI_0);
1543 break;
1544 default:
1545 g_assert_not_reached();
1546 }
1547
1548 if (irq) {
1549 sysbus_connect_irq(sbd, 0, irq);
1550 }
1551
1552 /*
1553 * Devices connected to a PPC are connected to the port here;
1554 * we will map the upstream end of that port to the right address
1555 * in the container later after the PPC has been realized.
1556 * Devices not connected to a PPC can be mapped immediately.
1557 */
1558 if (devinfo->ppc != NO_PPC) {
1559 TZPPC *ppc = &s->apb_ppc[devinfo->ppc];
1560 g_autofree char *portname = g_strdup_printf("port[%d]",
1561 devinfo->ppc_port);
1562 object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
1563 &error_abort);
1564 } else {
1565 memory_region_add_subregion(&s->container, devinfo->addr, mr);
1566 }
1567 }
1568
1569 if (info->has_mhus) {
1570 /*
1571 * An SSE-200 with only one CPU should have only one MHU created,
1572 * with the region where the second MHU usually is being RAZ/WI.
1573 * We don't implement that SSE-200 config; if we want to support
1574 * it then this code needs to be enhanced to handle creating the
1575 * RAZ/WI region instead of the second MHU.
1576 */
1577 assert(info->num_cpus == ARRAY_SIZE(s->mhu));
1578
1579 for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
1580 char *port;
1581 int cpunum;
1582 SysBusDevice *mhu_sbd = SYS_BUS_DEVICE(&s->mhu[i]);
1583
1584 if (!sysbus_realize(SYS_BUS_DEVICE(&s->mhu[i]), errp)) {
1585 return;
1586 }
1587 port = g_strdup_printf("port[%d]", i + 3);
1588 mr = sysbus_mmio_get_region(mhu_sbd, 0);
1589 object_property_set_link(OBJECT(&s->apb_ppc[0]), port, OBJECT(mr),
1590 &error_abort);
1591 g_free(port);
1592
1593 /*
1594 * Each MHU has an irq line for each CPU:
1595 * MHU 0 irq line 0 -> CPU 0 IRQ 6
1596 * MHU 0 irq line 1 -> CPU 1 IRQ 6
1597 * MHU 1 irq line 0 -> CPU 0 IRQ 7
1598 * MHU 1 irq line 1 -> CPU 1 IRQ 7
1599 */
1600 for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
1601 DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
1602
1603 sysbus_connect_irq(mhu_sbd, cpunum,
1604 qdev_get_gpio_in(cpudev, 6 + i));
1605 }
1606 }
1607 }
1608
1609 if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[0]), errp)) {
1610 return;
1611 }
1612
1613 sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc[0]);
1614 dev_apb_ppc0 = DEVICE(&s->apb_ppc[0]);
1615
1616 if (info->has_mhus) {
1617 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
1618 memory_region_add_subregion(&s->container, 0x40003000, mr);
1619 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
1620 memory_region_add_subregion(&s->container, 0x40004000, mr);
1621 }
1622 for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
1623 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
1624 qdev_get_gpio_in_named(dev_apb_ppc0,
1625 "cfg_nonsec", i));
1626 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
1627 qdev_get_gpio_in_named(dev_apb_ppc0,
1628 "cfg_ap", i));
1629 }
1630 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
1631 qdev_get_gpio_in_named(dev_apb_ppc0,
1632 "irq_enable", 0));
1633 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
1634 qdev_get_gpio_in_named(dev_apb_ppc0,
1635 "irq_clear", 0));
1636 qdev_connect_gpio_out(dev_splitter, 0,
1637 qdev_get_gpio_in_named(dev_apb_ppc0,
1638 "cfg_sec_resp", 0));
1639
1640 /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
1641 * ones) are sent individually to the security controller, and also
1642 * ORed together to give a single combined PPC interrupt to the NVIC.
1643 */
1644 if (!object_property_set_int(OBJECT(&s->ppc_irq_orgate),
1645 "num-lines", NUM_PPCS, errp)) {
1646 return;
1647 }
1648 if (!qdev_realize(DEVICE(&s->ppc_irq_orgate), NULL, errp)) {
1649 return;
1650 }
1651 qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
1652 armsse_get_common_irq_in(s, 10));
1653
1654 /*
1655 * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
1656 * private per-CPU region (all these devices are SSE-200 only):
1657 * 0x50010000: L1 icache control registers
1658 * 0x50011000: CPUSECCTRL (CPU local security control registers)
1659 * 0x4001f000 and 0x5001f000: CPU_IDENTITY register block
1660 * The SSE-300 and SSE-310 have an extra:
1661 * 0x40012000 and 0x50012000: CPU_PWRCTRL register block
1662 */
1663 if (info->has_cachectrl) {
1664 for (i = 0; i < info->num_cpus; i++) {
1665 char *name = g_strdup_printf("cachectrl%d", i);
1666
1667 qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
1668 g_free(name);
1669 qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
1670 if (!sysbus_realize(SYS_BUS_DEVICE(&s->cachectrl[i]), errp)) {
1671 return;
1672 }
1673
1674 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
1675 memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
1676 }
1677 }
1678 if (info->has_cpusecctrl) {
1679 for (i = 0; i < info->num_cpus; i++) {
1680 char *name = g_strdup_printf("CPUSECCTRL%d", i);
1681
1682 qdev_prop_set_string(DEVICE(&s->cpusecctrl[i]), "name", name);
1683 g_free(name);
1684 qdev_prop_set_uint64(DEVICE(&s->cpusecctrl[i]), "size", 0x1000);
1685 if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpusecctrl[i]), errp)) {
1686 return;
1687 }
1688
1689 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpusecctrl[i]), 0);
1690 memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
1691 }
1692 }
1693 if (info->has_cpuid) {
1694 for (i = 0; i < info->num_cpus; i++) {
1695
1696 qdev_prop_set_uint32(DEVICE(&s->cpuid[i]), "CPUID", i);
1697 if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpuid[i]), errp)) {
1698 return;
1699 }
1700
1701 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpuid[i]), 0);
1702 memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
1703 }
1704 }
1705 if (info->has_cpu_pwrctrl) {
1706 for (i = 0; i < info->num_cpus; i++) {
1707
1708 if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpu_pwrctrl[i]), errp)) {
1709 return;
1710 }
1711
1712 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpu_pwrctrl[i]), 0);
1713 memory_region_add_subregion(&s->cpu_container[i], 0x40012000, mr);
1714 }
1715 }
1716
1717 if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[1]), errp)) {
1718 return;
1719 }
1720
1721 dev_apb_ppc1 = DEVICE(&s->apb_ppc[1]);
1722 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
1723 qdev_get_gpio_in_named(dev_apb_ppc1,
1724 "cfg_nonsec", 0));
1725 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
1726 qdev_get_gpio_in_named(dev_apb_ppc1,
1727 "cfg_ap", 0));
1728 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
1729 qdev_get_gpio_in_named(dev_apb_ppc1,
1730 "irq_enable", 0));
1731 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
1732 qdev_get_gpio_in_named(dev_apb_ppc1,
1733 "irq_clear", 0));
1734 qdev_connect_gpio_out(dev_splitter, 1,
1735 qdev_get_gpio_in_named(dev_apb_ppc1,
1736 "cfg_sec_resp", 0));
1737
1738 /*
1739 * Now both PPCs are realized we can map the upstream ends of
1740 * ports which correspond to entries in the devinfo array.
1741 * The ports which are connected to non-devinfo devices have
1742 * already been mapped.
1743 */
1744 for (devinfo = info->devinfo; devinfo->name; devinfo++) {
1745 SysBusDevice *ppc_sbd;
1746
1747 if (devinfo->ppc == NO_PPC) {
1748 continue;
1749 }
1750 ppc_sbd = SYS_BUS_DEVICE(&s->apb_ppc[devinfo->ppc]);
1751 mr = sysbus_mmio_get_region(ppc_sbd, devinfo->ppc_port);
1752 memory_region_add_subregion(&s->container, devinfo->addr, mr);
1753 }
1754
1755 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
1756 Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
1757
1758 if (!object_property_set_int(splitter, "num-lines", 2, errp)) {
1759 return;
1760 }
1761 if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
1762 return;
1763 }
1764 }
1765
1766 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
1767 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
1768
1769 armsse_forward_ppc(s, ppcname, i);
1770 g_free(ppcname);
1771 }
1772
1773 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
1774 char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
1775
1776 armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
1777 g_free(ppcname);
1778 }
1779
1780 for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
1781 /* Wire up IRQ splitter for internal PPCs */
1782 DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
1783 char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
1784 i - NUM_EXTERNAL_PPCS);
1785 TZPPC *ppc = &s->apb_ppc[i - NUM_EXTERNAL_PPCS];
1786
1787 qdev_connect_gpio_out(devs, 0,
1788 qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
1789 qdev_connect_gpio_out(devs, 1,
1790 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
1791 qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
1792 qdev_get_gpio_in(devs, 0));
1793 g_free(gpioname);
1794 }
1795
1796 /* Wire up the splitters for the MPC IRQs */
1797 for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
1798 SplitIRQ *splitter = &s->mpc_irq_splitter[i];
1799 DeviceState *devs = DEVICE(splitter);
1800
1801 if (!object_property_set_int(OBJECT(splitter), "num-lines", 2,
1802 errp)) {
1803 return;
1804 }
1805 if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
1806 return;
1807 }
1808
1809 if (i < IOTS_NUM_EXP_MPC) {
1810 /* Splitter input is from GPIO input line */
1811 s->mpcexp_status_in[i] = qdev_get_gpio_in(devs, 0);
1812 qdev_connect_gpio_out(devs, 0,
1813 qdev_get_gpio_in_named(dev_secctl,
1814 "mpcexp_status", i));
1815 } else {
1816 /* Splitter input is from our own MPC */
1817 qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
1818 "irq", 0,
1819 qdev_get_gpio_in(devs, 0));
1820 qdev_connect_gpio_out(devs, 0,
1821 qdev_get_gpio_in_named(dev_secctl,
1822 "mpc_status",
1823 i - IOTS_NUM_EXP_MPC));
1824 }
1825
1826 qdev_connect_gpio_out(devs, 1,
1827 qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
1828 }
1829 /* Create GPIO inputs which will pass the line state for our
1830 * mpcexp_irq inputs to the correct splitter devices.
1831 */
1832 qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
1833 IOTS_NUM_EXP_MPC);
1834
1835 armsse_forward_sec_resp_cfg(s);
1836
1837 /* Forward the MSC related signals */
1838 qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
1839 qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
1840 qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
1841 qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
1842 armsse_get_common_irq_in(s, 11));
1843
1844 /*
1845 * Expose our container region to the board model; this corresponds
1846 * to the AHB Slave Expansion ports which allow bus master devices
1847 * (eg DMA controllers) in the board model to make transactions into
1848 * devices in the ARMSSE.
1849 */
1850 sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
1851 }
1852
1853 static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
1854 int *iregion, bool *exempt, bool *ns, bool *nsc)
1855 {
1856 /*
1857 * For ARMSSE systems the IDAU responses are simple logical functions
1858 * of the address bits. The NSC attribute is guest-adjustable via the
1859 * NSCCFG register in the security controller.
1860 */
1861 ARMSSE *s = ARM_SSE(ii);
1862 int region = extract32(address, 28, 4);
1863
1864 *ns = !(region & 1);
1865 *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
1866 /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
1867 *exempt = (address & 0xeff00000) == 0xe0000000;
1868 *iregion = region;
1869 }
1870
1871 static const VMStateDescription armsse_vmstate = {
1872 .name = "iotkit",
1873 .version_id = 2,
1874 .minimum_version_id = 2,
1875 .fields = (const VMStateField[]) {
1876 VMSTATE_CLOCK(mainclk, ARMSSE),
1877 VMSTATE_CLOCK(s32kclk, ARMSSE),
1878 VMSTATE_UINT32(nsccfg, ARMSSE),
1879 VMSTATE_END_OF_LIST()
1880 }
1881 };
1882
1883 static void armsse_reset(DeviceState *dev)
1884 {
1885 ARMSSE *s = ARM_SSE(dev);
1886
1887 s->nsccfg = 0;
1888 }
1889
1890 static void armsse_class_init(ObjectClass *klass, const void *data)
1891 {
1892 DeviceClass *dc = DEVICE_CLASS(klass);
1893 IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
1894 ARMSSEClass *asc = ARM_SSE_CLASS(klass);
1895 const ARMSSEInfo *info = data;
1896
1897 dc->realize = armsse_realize;
1898 dc->vmsd = &armsse_vmstate;
1899 device_class_set_props_n(dc, info->props, info->props_count);
1900 device_class_set_legacy_reset(dc, armsse_reset);
1901 iic->check = armsse_idau_check;
1902 asc->info = info;
1903 }
1904
1905 static const TypeInfo armsse_info = {
1906 .name = TYPE_ARM_SSE,
1907 .parent = TYPE_SYS_BUS_DEVICE,
1908 .instance_size = sizeof(ARMSSE),
1909 .class_size = sizeof(ARMSSEClass),
1910 .instance_init = armsse_init,
1911 .abstract = true,
1912 .interfaces = (const InterfaceInfo[]) {
1913 { TYPE_IDAU_INTERFACE },
1914 { }
1915 }
1916 };
1917
1918 static void armsse_register_types(void)
1919 {
1920 int i;
1921
1922 type_register_static(&armsse_info);
1923
1924 for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
1925 TypeInfo ti = {
1926 .name = armsse_variants[i].name,
1927 .parent = TYPE_ARM_SSE,
1928 .class_init = armsse_class_init,
1929 .class_data = &armsse_variants[i],
1930 };
1931 type_register_static(&ti);
1932 }
1933 }
1934
1935 type_init(armsse_register_types);