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