1 /* 2 * Arm IoT Kit 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/iotkit.h" 19 #include "hw/misc/unimp.h" 20 #include "hw/arm/arm.h" 21 22 /* Create an alias region of @size bytes starting at @base 23 * which mirrors the memory starting at @orig. 24 */ 25 static void make_alias(IoTKit *s, MemoryRegion *mr, const char *name, 26 hwaddr base, hwaddr size, hwaddr orig) 27 { 28 memory_region_init_alias(mr, NULL, name, &s->container, orig, size); 29 /* The alias is even lower priority than unimplemented_device regions */ 30 memory_region_add_subregion_overlap(&s->container, base, mr, -1500); 31 } 32 33 static void init_sysbus_child(Object *parent, const char *childname, 34 void *child, size_t childsize, 35 const char *childtype) 36 { 37 object_initialize(child, childsize, childtype); 38 object_property_add_child(parent, childname, OBJECT(child), &error_abort); 39 qdev_set_parent_bus(DEVICE(child), sysbus_get_default()); 40 } 41 42 static void irq_status_forwarder(void *opaque, int n, int level) 43 { 44 qemu_irq destirq = opaque; 45 46 qemu_set_irq(destirq, level); 47 } 48 49 static void nsccfg_handler(void *opaque, int n, int level) 50 { 51 IoTKit *s = IOTKIT(opaque); 52 53 s->nsccfg = level; 54 } 55 56 static void iotkit_forward_ppc(IoTKit *s, const char *ppcname, int ppcnum) 57 { 58 /* Each of the 4 AHB and 4 APB PPCs that might be present in a 59 * system using the IoTKit has a collection of control lines which 60 * are provided by the security controller and which we want to 61 * expose as control lines on the IoTKit device itself, so the 62 * code using the IoTKit can wire them up to the PPCs. 63 */ 64 SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum]; 65 DeviceState *iotkitdev = DEVICE(s); 66 DeviceState *dev_secctl = DEVICE(&s->secctl); 67 DeviceState *dev_splitter = DEVICE(splitter); 68 char *name; 69 70 name = g_strdup_printf("%s_nonsec", ppcname); 71 qdev_pass_gpios(dev_secctl, iotkitdev, name); 72 g_free(name); 73 name = g_strdup_printf("%s_ap", ppcname); 74 qdev_pass_gpios(dev_secctl, iotkitdev, name); 75 g_free(name); 76 name = g_strdup_printf("%s_irq_enable", ppcname); 77 qdev_pass_gpios(dev_secctl, iotkitdev, name); 78 g_free(name); 79 name = g_strdup_printf("%s_irq_clear", ppcname); 80 qdev_pass_gpios(dev_secctl, iotkitdev, name); 81 g_free(name); 82 83 /* irq_status is a little more tricky, because we need to 84 * split it so we can send it both to the security controller 85 * and to our OR gate for the NVIC interrupt line. 86 * Connect up the splitter's outputs, and create a GPIO input 87 * which will pass the line state to the input splitter. 88 */ 89 name = g_strdup_printf("%s_irq_status", ppcname); 90 qdev_connect_gpio_out(dev_splitter, 0, 91 qdev_get_gpio_in_named(dev_secctl, 92 name, 0)); 93 qdev_connect_gpio_out(dev_splitter, 1, 94 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum)); 95 s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0); 96 qdev_init_gpio_in_named_with_opaque(iotkitdev, irq_status_forwarder, 97 s->irq_status_in[ppcnum], name, 1); 98 g_free(name); 99 } 100 101 static void iotkit_forward_sec_resp_cfg(IoTKit *s) 102 { 103 /* Forward the 3rd output from the splitter device as a 104 * named GPIO output of the iotkit object. 105 */ 106 DeviceState *dev = DEVICE(s); 107 DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter); 108 109 qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1); 110 s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder, 111 s->sec_resp_cfg, 1); 112 qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in); 113 } 114 115 static void iotkit_init(Object *obj) 116 { 117 IoTKit *s = IOTKIT(obj); 118 int i; 119 120 memory_region_init(&s->container, obj, "iotkit-container", UINT64_MAX); 121 122 init_sysbus_child(obj, "armv7m", &s->armv7m, sizeof(s->armv7m), 123 TYPE_ARMV7M); 124 qdev_prop_set_string(DEVICE(&s->armv7m), "cpu-type", 125 ARM_CPU_TYPE_NAME("cortex-m33")); 126 127 init_sysbus_child(obj, "secctl", &s->secctl, sizeof(s->secctl), 128 TYPE_IOTKIT_SECCTL); 129 init_sysbus_child(obj, "apb-ppc0", &s->apb_ppc0, sizeof(s->apb_ppc0), 130 TYPE_TZ_PPC); 131 init_sysbus_child(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1), 132 TYPE_TZ_PPC); 133 init_sysbus_child(obj, "timer0", &s->timer0, sizeof(s->timer0), 134 TYPE_CMSDK_APB_TIMER); 135 init_sysbus_child(obj, "timer1", &s->timer1, sizeof(s->timer1), 136 TYPE_CMSDK_APB_TIMER); 137 init_sysbus_child(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer), 138 TYPE_UNIMPLEMENTED_DEVICE); 139 object_initialize(&s->ppc_irq_orgate, sizeof(s->ppc_irq_orgate), 140 TYPE_OR_IRQ); 141 object_property_add_child(obj, "ppc-irq-orgate", 142 OBJECT(&s->ppc_irq_orgate), &error_abort); 143 object_initialize(&s->sec_resp_splitter, sizeof(s->sec_resp_splitter), 144 TYPE_SPLIT_IRQ); 145 object_property_add_child(obj, "sec-resp-splitter", 146 OBJECT(&s->sec_resp_splitter), &error_abort); 147 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) { 148 char *name = g_strdup_printf("ppc-irq-splitter-%d", i); 149 SplitIRQ *splitter = &s->ppc_irq_splitter[i]; 150 151 object_initialize(splitter, sizeof(*splitter), TYPE_SPLIT_IRQ); 152 object_property_add_child(obj, name, OBJECT(splitter), &error_abort); 153 } 154 init_sysbus_child(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer), 155 TYPE_UNIMPLEMENTED_DEVICE); 156 } 157 158 static void iotkit_exp_irq(void *opaque, int n, int level) 159 { 160 IoTKit *s = IOTKIT(opaque); 161 162 qemu_set_irq(s->exp_irqs[n], level); 163 } 164 165 static void iotkit_realize(DeviceState *dev, Error **errp) 166 { 167 IoTKit *s = IOTKIT(dev); 168 int i; 169 MemoryRegion *mr; 170 Error *err = NULL; 171 SysBusDevice *sbd_apb_ppc0; 172 SysBusDevice *sbd_secctl; 173 DeviceState *dev_apb_ppc0; 174 DeviceState *dev_apb_ppc1; 175 DeviceState *dev_secctl; 176 DeviceState *dev_splitter; 177 178 if (!s->board_memory) { 179 error_setg(errp, "memory property was not set"); 180 return; 181 } 182 183 if (!s->mainclk_frq) { 184 error_setg(errp, "MAINCLK property was not set"); 185 return; 186 } 187 188 /* Handling of which devices should be available only to secure 189 * code is usually done differently for M profile than for A profile. 190 * Instead of putting some devices only into the secure address space, 191 * devices exist in both address spaces but with hard-wired security 192 * permissions that will cause the CPU to fault for non-secure accesses. 193 * 194 * The IoTKit has an IDAU (Implementation Defined Access Unit), 195 * which specifies hard-wired security permissions for different 196 * areas of the physical address space. For the IoTKit IDAU, the 197 * top 4 bits of the physical address are the IDAU region ID, and 198 * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS 199 * region, otherwise it is an S region. 200 * 201 * The various devices and RAMs are generally all mapped twice, 202 * once into a region that the IDAU defines as secure and once 203 * into a non-secure region. They sit behind either a Memory 204 * Protection Controller (for RAM) or a Peripheral Protection 205 * Controller (for devices), which allow a more fine grained 206 * configuration of whether non-secure accesses are permitted. 207 * 208 * (The other place that guest software can configure security 209 * permissions is in the architected SAU (Security Attribution 210 * Unit), which is entirely inside the CPU. The IDAU can upgrade 211 * the security attributes for a region to more restrictive than 212 * the SAU specifies, but cannot downgrade them.) 213 * 214 * 0x10000000..0x1fffffff alias of 0x00000000..0x0fffffff 215 * 0x20000000..0x2007ffff 32KB FPGA block RAM 216 * 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff 217 * 0x40000000..0x4000ffff base peripheral region 1 218 * 0x40010000..0x4001ffff CPU peripherals (none for IoTKit) 219 * 0x40020000..0x4002ffff system control element peripherals 220 * 0x40080000..0x400fffff base peripheral region 2 221 * 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff 222 */ 223 224 memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1); 225 226 qdev_prop_set_uint32(DEVICE(&s->armv7m), "num-irq", s->exp_numirq + 32); 227 /* In real hardware the initial Secure VTOR is set from the INITSVTOR0 228 * register in the IoT Kit System Control Register block, and the 229 * initial value of that is in turn specifiable by the FPGA that 230 * instantiates the IoT Kit. In QEMU we don't implement this wrinkle, 231 * and simply set the CPU's init-svtor to the IoT Kit default value. 232 */ 233 qdev_prop_set_uint32(DEVICE(&s->armv7m), "init-svtor", 0x10000000); 234 object_property_set_link(OBJECT(&s->armv7m), OBJECT(&s->container), 235 "memory", &err); 236 if (err) { 237 error_propagate(errp, err); 238 return; 239 } 240 object_property_set_link(OBJECT(&s->armv7m), OBJECT(s), "idau", &err); 241 if (err) { 242 error_propagate(errp, err); 243 return; 244 } 245 object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err); 246 if (err) { 247 error_propagate(errp, err); 248 return; 249 } 250 251 /* Connect our EXP_IRQ GPIOs to the NVIC's lines 32 and up. */ 252 s->exp_irqs = g_new(qemu_irq, s->exp_numirq); 253 for (i = 0; i < s->exp_numirq; i++) { 254 s->exp_irqs[i] = qdev_get_gpio_in(DEVICE(&s->armv7m), i + 32); 255 } 256 qdev_init_gpio_in_named(dev, iotkit_exp_irq, "EXP_IRQ", s->exp_numirq); 257 258 /* Set up the big aliases first */ 259 make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000); 260 make_alias(s, &s->alias2, "alias 2", 0x30000000, 0x10000000, 0x20000000); 261 /* The 0x50000000..0x5fffffff region is not a pure alias: it has 262 * a few extra devices that only appear there (generally the 263 * control interfaces for the protection controllers). 264 * We implement this by mapping those devices over the top of this 265 * alias MR at a higher priority. 266 */ 267 make_alias(s, &s->alias3, "alias 3", 0x50000000, 0x10000000, 0x40000000); 268 269 /* This RAM should be behind a Memory Protection Controller, but we 270 * don't implement that yet. 271 */ 272 memory_region_init_ram(&s->sram0, NULL, "iotkit.sram0", 0x00008000, &err); 273 if (err) { 274 error_propagate(errp, err); 275 return; 276 } 277 memory_region_add_subregion(&s->container, 0x20000000, &s->sram0); 278 279 /* Security controller */ 280 object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err); 281 if (err) { 282 error_propagate(errp, err); 283 return; 284 } 285 sbd_secctl = SYS_BUS_DEVICE(&s->secctl); 286 dev_secctl = DEVICE(&s->secctl); 287 sysbus_mmio_map(sbd_secctl, 0, 0x50080000); 288 sysbus_mmio_map(sbd_secctl, 1, 0x40080000); 289 290 s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1); 291 qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in); 292 293 /* The sec_resp_cfg output from the security controller must be split into 294 * multiple lines, one for each of the PPCs within the IoTKit and one 295 * that will be an output from the IoTKit to the system. 296 */ 297 object_property_set_int(OBJECT(&s->sec_resp_splitter), 3, 298 "num-lines", &err); 299 if (err) { 300 error_propagate(errp, err); 301 return; 302 } 303 object_property_set_bool(OBJECT(&s->sec_resp_splitter), true, 304 "realized", &err); 305 if (err) { 306 error_propagate(errp, err); 307 return; 308 } 309 dev_splitter = DEVICE(&s->sec_resp_splitter); 310 qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0, 311 qdev_get_gpio_in(dev_splitter, 0)); 312 313 /* Devices behind APB PPC0: 314 * 0x40000000: timer0 315 * 0x40001000: timer1 316 * 0x40002000: dual timer 317 * We must configure and realize each downstream device and connect 318 * it to the appropriate PPC port; then we can realize the PPC and 319 * map its upstream ends to the right place in the container. 320 */ 321 qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq); 322 object_property_set_bool(OBJECT(&s->timer0), true, "realized", &err); 323 if (err) { 324 error_propagate(errp, err); 325 return; 326 } 327 sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0, 328 qdev_get_gpio_in(DEVICE(&s->armv7m), 3)); 329 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0); 330 object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err); 331 if (err) { 332 error_propagate(errp, err); 333 return; 334 } 335 336 qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq); 337 object_property_set_bool(OBJECT(&s->timer1), true, "realized", &err); 338 if (err) { 339 error_propagate(errp, err); 340 return; 341 } 342 sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0, 343 qdev_get_gpio_in(DEVICE(&s->armv7m), 3)); 344 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0); 345 object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err); 346 if (err) { 347 error_propagate(errp, err); 348 return; 349 } 350 351 qdev_prop_set_string(DEVICE(&s->dualtimer), "name", "Dual timer"); 352 qdev_prop_set_uint64(DEVICE(&s->dualtimer), "size", 0x1000); 353 object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err); 354 if (err) { 355 error_propagate(errp, err); 356 return; 357 } 358 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0); 359 object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err); 360 if (err) { 361 error_propagate(errp, err); 362 return; 363 } 364 365 object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err); 366 if (err) { 367 error_propagate(errp, err); 368 return; 369 } 370 371 sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc0); 372 dev_apb_ppc0 = DEVICE(&s->apb_ppc0); 373 374 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 0); 375 memory_region_add_subregion(&s->container, 0x40000000, mr); 376 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 1); 377 memory_region_add_subregion(&s->container, 0x40001000, mr); 378 mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2); 379 memory_region_add_subregion(&s->container, 0x40002000, mr); 380 for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) { 381 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i, 382 qdev_get_gpio_in_named(dev_apb_ppc0, 383 "cfg_nonsec", i)); 384 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i, 385 qdev_get_gpio_in_named(dev_apb_ppc0, 386 "cfg_ap", i)); 387 } 388 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0, 389 qdev_get_gpio_in_named(dev_apb_ppc0, 390 "irq_enable", 0)); 391 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0, 392 qdev_get_gpio_in_named(dev_apb_ppc0, 393 "irq_clear", 0)); 394 qdev_connect_gpio_out(dev_splitter, 0, 395 qdev_get_gpio_in_named(dev_apb_ppc0, 396 "cfg_sec_resp", 0)); 397 398 /* All the PPC irq lines (from the 2 internal PPCs and the 8 external 399 * ones) are sent individually to the security controller, and also 400 * ORed together to give a single combined PPC interrupt to the NVIC. 401 */ 402 object_property_set_int(OBJECT(&s->ppc_irq_orgate), 403 NUM_PPCS, "num-lines", &err); 404 if (err) { 405 error_propagate(errp, err); 406 return; 407 } 408 object_property_set_bool(OBJECT(&s->ppc_irq_orgate), true, 409 "realized", &err); 410 if (err) { 411 error_propagate(errp, err); 412 return; 413 } 414 qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0, 415 qdev_get_gpio_in(DEVICE(&s->armv7m), 10)); 416 417 /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */ 418 419 /* 0x40020000 .. 0x4002ffff : IoTKit system control peripheral region */ 420 /* Devices behind APB PPC1: 421 * 0x4002f000: S32K timer 422 */ 423 qdev_prop_set_string(DEVICE(&s->s32ktimer), "name", "S32KTIMER"); 424 qdev_prop_set_uint64(DEVICE(&s->s32ktimer), "size", 0x1000); 425 object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err); 426 if (err) { 427 error_propagate(errp, err); 428 return; 429 } 430 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0); 431 object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err); 432 if (err) { 433 error_propagate(errp, err); 434 return; 435 } 436 437 object_property_set_bool(OBJECT(&s->apb_ppc1), true, "realized", &err); 438 if (err) { 439 error_propagate(errp, err); 440 return; 441 } 442 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->apb_ppc1), 0); 443 memory_region_add_subregion(&s->container, 0x4002f000, mr); 444 445 dev_apb_ppc1 = DEVICE(&s->apb_ppc1); 446 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0, 447 qdev_get_gpio_in_named(dev_apb_ppc1, 448 "cfg_nonsec", 0)); 449 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0, 450 qdev_get_gpio_in_named(dev_apb_ppc1, 451 "cfg_ap", 0)); 452 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0, 453 qdev_get_gpio_in_named(dev_apb_ppc1, 454 "irq_enable", 0)); 455 qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0, 456 qdev_get_gpio_in_named(dev_apb_ppc1, 457 "irq_clear", 0)); 458 qdev_connect_gpio_out(dev_splitter, 1, 459 qdev_get_gpio_in_named(dev_apb_ppc1, 460 "cfg_sec_resp", 0)); 461 462 /* Using create_unimplemented_device() maps the stub into the 463 * system address space rather than into our container, but the 464 * overall effect to the guest is the same. 465 */ 466 create_unimplemented_device("SYSINFO", 0x40020000, 0x1000); 467 468 create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000); 469 create_unimplemented_device("S32KWATCHDOG", 0x5002e000, 0x1000); 470 471 /* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */ 472 473 create_unimplemented_device("NS watchdog", 0x40081000, 0x1000); 474 create_unimplemented_device("S watchdog", 0x50081000, 0x1000); 475 476 create_unimplemented_device("SRAM0 MPC", 0x50083000, 0x1000); 477 478 for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) { 479 Object *splitter = OBJECT(&s->ppc_irq_splitter[i]); 480 481 object_property_set_int(splitter, 2, "num-lines", &err); 482 if (err) { 483 error_propagate(errp, err); 484 return; 485 } 486 object_property_set_bool(splitter, true, "realized", &err); 487 if (err) { 488 error_propagate(errp, err); 489 return; 490 } 491 } 492 493 for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) { 494 char *ppcname = g_strdup_printf("ahb_ppcexp%d", i); 495 496 iotkit_forward_ppc(s, ppcname, i); 497 g_free(ppcname); 498 } 499 500 for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) { 501 char *ppcname = g_strdup_printf("apb_ppcexp%d", i); 502 503 iotkit_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC); 504 g_free(ppcname); 505 } 506 507 for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) { 508 /* Wire up IRQ splitter for internal PPCs */ 509 DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]); 510 char *gpioname = g_strdup_printf("apb_ppc%d_irq_status", 511 i - NUM_EXTERNAL_PPCS); 512 TZPPC *ppc = (i == NUM_EXTERNAL_PPCS) ? &s->apb_ppc0 : &s->apb_ppc1; 513 514 qdev_connect_gpio_out(devs, 0, 515 qdev_get_gpio_in_named(dev_secctl, gpioname, 0)); 516 qdev_connect_gpio_out(devs, 1, 517 qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i)); 518 qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0, 519 qdev_get_gpio_in(devs, 0)); 520 } 521 522 iotkit_forward_sec_resp_cfg(s); 523 524 system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq; 525 } 526 527 static void iotkit_idau_check(IDAUInterface *ii, uint32_t address, 528 int *iregion, bool *exempt, bool *ns, bool *nsc) 529 { 530 /* For IoTKit systems the IDAU responses are simple logical functions 531 * of the address bits. The NSC attribute is guest-adjustable via the 532 * NSCCFG register in the security controller. 533 */ 534 IoTKit *s = IOTKIT(ii); 535 int region = extract32(address, 28, 4); 536 537 *ns = !(region & 1); 538 *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2)); 539 /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */ 540 *exempt = (address & 0xeff00000) == 0xe0000000; 541 *iregion = region; 542 } 543 544 static const VMStateDescription iotkit_vmstate = { 545 .name = "iotkit", 546 .version_id = 1, 547 .minimum_version_id = 1, 548 .fields = (VMStateField[]) { 549 VMSTATE_UINT32(nsccfg, IoTKit), 550 VMSTATE_END_OF_LIST() 551 } 552 }; 553 554 static Property iotkit_properties[] = { 555 DEFINE_PROP_LINK("memory", IoTKit, board_memory, TYPE_MEMORY_REGION, 556 MemoryRegion *), 557 DEFINE_PROP_UINT32("EXP_NUMIRQ", IoTKit, exp_numirq, 64), 558 DEFINE_PROP_UINT32("MAINCLK", IoTKit, mainclk_frq, 0), 559 DEFINE_PROP_END_OF_LIST() 560 }; 561 562 static void iotkit_reset(DeviceState *dev) 563 { 564 IoTKit *s = IOTKIT(dev); 565 566 s->nsccfg = 0; 567 } 568 569 static void iotkit_class_init(ObjectClass *klass, void *data) 570 { 571 DeviceClass *dc = DEVICE_CLASS(klass); 572 IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass); 573 574 dc->realize = iotkit_realize; 575 dc->vmsd = &iotkit_vmstate; 576 dc->props = iotkit_properties; 577 dc->reset = iotkit_reset; 578 iic->check = iotkit_idau_check; 579 } 580 581 static const TypeInfo iotkit_info = { 582 .name = TYPE_IOTKIT, 583 .parent = TYPE_SYS_BUS_DEVICE, 584 .instance_size = sizeof(IoTKit), 585 .instance_init = iotkit_init, 586 .class_init = iotkit_class_init, 587 .interfaces = (InterfaceInfo[]) { 588 { TYPE_IDAU_INTERFACE }, 589 { } 590 } 591 }; 592 593 static void iotkit_register_types(void) 594 { 595 type_register_static(&iotkit_info); 596 } 597 598 type_init(iotkit_register_types); 599