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