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