1 /* 2 * Xilinx Versal SoC model. 3 * 4 * Copyright (c) 2018 Xilinx Inc. 5 * Written by Edgar E. Iglesias 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/units.h" 14 #include "qapi/error.h" 15 #include "qemu/module.h" 16 #include "hw/sysbus.h" 17 #include "net/net.h" 18 #include "sysemu/sysemu.h" 19 #include "sysemu/kvm.h" 20 #include "hw/arm/boot.h" 21 #include "kvm_arm.h" 22 #include "hw/misc/unimp.h" 23 #include "hw/arm/xlnx-versal.h" 24 #include "qemu/log.h" 25 #include "hw/sysbus.h" 26 27 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72") 28 #define GEM_REVISION 0x40070106 29 30 #define VERSAL_NUM_PMC_APB_IRQS 3 31 32 static void versal_create_apu_cpus(Versal *s) 33 { 34 int i; 35 36 for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) { 37 Object *obj; 38 39 object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i], 40 XLNX_VERSAL_ACPU_TYPE); 41 obj = OBJECT(&s->fpd.apu.cpu[i]); 42 object_property_set_int(obj, "psci-conduit", s->cfg.psci_conduit, 43 &error_abort); 44 if (i) { 45 /* Secondary CPUs start in PSCI powered-down state */ 46 object_property_set_bool(obj, "start-powered-off", true, 47 &error_abort); 48 } 49 50 object_property_set_int(obj, "core-count", ARRAY_SIZE(s->fpd.apu.cpu), 51 &error_abort); 52 object_property_set_link(obj, "memory", OBJECT(&s->fpd.apu.mr), 53 &error_abort); 54 qdev_realize(DEVICE(obj), NULL, &error_fatal); 55 } 56 } 57 58 static void versal_create_apu_gic(Versal *s, qemu_irq *pic) 59 { 60 static const uint64_t addrs[] = { 61 MM_GIC_APU_DIST_MAIN, 62 MM_GIC_APU_REDIST_0 63 }; 64 SysBusDevice *gicbusdev; 65 DeviceState *gicdev; 66 int nr_apu_cpus = ARRAY_SIZE(s->fpd.apu.cpu); 67 int i; 68 69 object_initialize_child(OBJECT(s), "apu-gic", &s->fpd.apu.gic, 70 gicv3_class_name()); 71 gicbusdev = SYS_BUS_DEVICE(&s->fpd.apu.gic); 72 gicdev = DEVICE(&s->fpd.apu.gic); 73 qdev_prop_set_uint32(gicdev, "revision", 3); 74 qdev_prop_set_uint32(gicdev, "num-cpu", nr_apu_cpus); 75 qdev_prop_set_uint32(gicdev, "num-irq", XLNX_VERSAL_NR_IRQS + 32); 76 qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1); 77 qdev_prop_set_uint32(gicdev, "redist-region-count[0]", nr_apu_cpus); 78 qdev_prop_set_bit(gicdev, "has-security-extensions", true); 79 80 sysbus_realize(SYS_BUS_DEVICE(&s->fpd.apu.gic), &error_fatal); 81 82 for (i = 0; i < ARRAY_SIZE(addrs); i++) { 83 MemoryRegion *mr; 84 85 mr = sysbus_mmio_get_region(gicbusdev, i); 86 memory_region_add_subregion(&s->fpd.apu.mr, addrs[i], mr); 87 } 88 89 for (i = 0; i < nr_apu_cpus; i++) { 90 DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]); 91 int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS; 92 qemu_irq maint_irq; 93 int ti; 94 /* Mapping from the output timer irq lines from the CPU to the 95 * GIC PPI inputs. 96 */ 97 const int timer_irq[] = { 98 [GTIMER_PHYS] = VERSAL_TIMER_NS_EL1_IRQ, 99 [GTIMER_VIRT] = VERSAL_TIMER_VIRT_IRQ, 100 [GTIMER_HYP] = VERSAL_TIMER_NS_EL2_IRQ, 101 [GTIMER_SEC] = VERSAL_TIMER_S_EL1_IRQ, 102 }; 103 104 for (ti = 0; ti < ARRAY_SIZE(timer_irq); ti++) { 105 qdev_connect_gpio_out(cpudev, ti, 106 qdev_get_gpio_in(gicdev, 107 ppibase + timer_irq[ti])); 108 } 109 maint_irq = qdev_get_gpio_in(gicdev, 110 ppibase + VERSAL_GIC_MAINT_IRQ); 111 qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 112 0, maint_irq); 113 sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); 114 sysbus_connect_irq(gicbusdev, i + nr_apu_cpus, 115 qdev_get_gpio_in(cpudev, ARM_CPU_FIQ)); 116 sysbus_connect_irq(gicbusdev, i + 2 * nr_apu_cpus, 117 qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ)); 118 sysbus_connect_irq(gicbusdev, i + 3 * nr_apu_cpus, 119 qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); 120 } 121 122 for (i = 0; i < XLNX_VERSAL_NR_IRQS; i++) { 123 pic[i] = qdev_get_gpio_in(gicdev, i); 124 } 125 } 126 127 static void versal_create_uarts(Versal *s, qemu_irq *pic) 128 { 129 int i; 130 131 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) { 132 static const int irqs[] = { VERSAL_UART0_IRQ_0, VERSAL_UART1_IRQ_0}; 133 static const uint64_t addrs[] = { MM_UART0, MM_UART1 }; 134 char *name = g_strdup_printf("uart%d", i); 135 DeviceState *dev; 136 MemoryRegion *mr; 137 138 object_initialize_child(OBJECT(s), name, &s->lpd.iou.uart[i], 139 TYPE_PL011); 140 dev = DEVICE(&s->lpd.iou.uart[i]); 141 qdev_prop_set_chr(dev, "chardev", serial_hd(i)); 142 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 143 144 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 145 memory_region_add_subregion(&s->mr_ps, addrs[i], mr); 146 147 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]); 148 g_free(name); 149 } 150 } 151 152 static void versal_create_usbs(Versal *s, qemu_irq *pic) 153 { 154 DeviceState *dev; 155 MemoryRegion *mr; 156 157 object_initialize_child(OBJECT(s), "usb2", &s->lpd.iou.usb, 158 TYPE_XILINX_VERSAL_USB2); 159 dev = DEVICE(&s->lpd.iou.usb); 160 161 object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps), 162 &error_abort); 163 qdev_prop_set_uint32(dev, "intrs", 1); 164 qdev_prop_set_uint32(dev, "slots", 2); 165 166 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 167 168 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 169 memory_region_add_subregion(&s->mr_ps, MM_USB_0, mr); 170 171 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_USB0_IRQ_0]); 172 173 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); 174 memory_region_add_subregion(&s->mr_ps, MM_USB2_CTRL_REGS, mr); 175 } 176 177 static void versal_create_gems(Versal *s, qemu_irq *pic) 178 { 179 int i; 180 181 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) { 182 static const int irqs[] = { VERSAL_GEM0_IRQ_0, VERSAL_GEM1_IRQ_0}; 183 static const uint64_t addrs[] = { MM_GEM0, MM_GEM1 }; 184 char *name = g_strdup_printf("gem%d", i); 185 NICInfo *nd = &nd_table[i]; 186 DeviceState *dev; 187 MemoryRegion *mr; 188 189 object_initialize_child(OBJECT(s), name, &s->lpd.iou.gem[i], 190 TYPE_CADENCE_GEM); 191 dev = DEVICE(&s->lpd.iou.gem[i]); 192 /* FIXME use qdev NIC properties instead of nd_table[] */ 193 if (nd->used) { 194 qemu_check_nic_model(nd, "cadence_gem"); 195 qdev_set_nic_properties(dev, nd); 196 } 197 object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort); 198 object_property_set_int(OBJECT(dev), "num-priority-queues", 2, 199 &error_abort); 200 object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps), 201 &error_abort); 202 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 203 204 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 205 memory_region_add_subregion(&s->mr_ps, addrs[i], mr); 206 207 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]); 208 g_free(name); 209 } 210 } 211 212 static void versal_create_admas(Versal *s, qemu_irq *pic) 213 { 214 int i; 215 216 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) { 217 char *name = g_strdup_printf("adma%d", i); 218 DeviceState *dev; 219 MemoryRegion *mr; 220 221 object_initialize_child(OBJECT(s), name, &s->lpd.iou.adma[i], 222 TYPE_XLNX_ZDMA); 223 dev = DEVICE(&s->lpd.iou.adma[i]); 224 object_property_set_int(OBJECT(dev), "bus-width", 128, &error_abort); 225 object_property_set_link(OBJECT(dev), "dma", 226 OBJECT(get_system_memory()), &error_fatal); 227 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 228 229 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 230 memory_region_add_subregion(&s->mr_ps, 231 MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr); 232 233 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]); 234 g_free(name); 235 } 236 } 237 238 #define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */ 239 static void versal_create_sds(Versal *s, qemu_irq *pic) 240 { 241 int i; 242 243 for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) { 244 DeviceState *dev; 245 MemoryRegion *mr; 246 247 object_initialize_child(OBJECT(s), "sd[*]", &s->pmc.iou.sd[i], 248 TYPE_SYSBUS_SDHCI); 249 dev = DEVICE(&s->pmc.iou.sd[i]); 250 251 object_property_set_uint(OBJECT(dev), "sd-spec-version", 3, 252 &error_fatal); 253 object_property_set_uint(OBJECT(dev), "capareg", SDHCI_CAPABILITIES, 254 &error_fatal); 255 object_property_set_uint(OBJECT(dev), "uhs", UHS_I, &error_fatal); 256 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 257 258 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 259 memory_region_add_subregion(&s->mr_ps, 260 MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr); 261 262 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, 263 pic[VERSAL_SD0_IRQ_0 + i * 2]); 264 } 265 } 266 267 static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic) 268 { 269 DeviceState *orgate; 270 271 /* 272 * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following 273 * models: 274 * - RTC 275 * - BBRAM 276 * - PMC SLCR 277 */ 278 object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate", 279 &s->pmc.apb_irq_orgate, TYPE_OR_IRQ); 280 orgate = DEVICE(&s->pmc.apb_irq_orgate); 281 object_property_set_int(OBJECT(orgate), 282 "num-lines", VERSAL_NUM_PMC_APB_IRQS, &error_fatal); 283 qdev_realize(orgate, NULL, &error_fatal); 284 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]); 285 } 286 287 static void versal_create_rtc(Versal *s, qemu_irq *pic) 288 { 289 SysBusDevice *sbd; 290 MemoryRegion *mr; 291 292 object_initialize_child(OBJECT(s), "rtc", &s->pmc.rtc, 293 TYPE_XLNX_ZYNQMP_RTC); 294 sbd = SYS_BUS_DEVICE(&s->pmc.rtc); 295 sysbus_realize(SYS_BUS_DEVICE(sbd), &error_fatal); 296 297 mr = sysbus_mmio_get_region(sbd, 0); 298 memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr); 299 300 /* 301 * TODO: Connect the ALARM and SECONDS interrupts once our RTC model 302 * supports them. 303 */ 304 sysbus_connect_irq(sbd, 1, 305 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 0)); 306 } 307 308 static void versal_create_xrams(Versal *s, qemu_irq *pic) 309 { 310 int nr_xrams = ARRAY_SIZE(s->lpd.xram.ctrl); 311 DeviceState *orgate; 312 int i; 313 314 /* XRAM IRQs get ORed into a single line. */ 315 object_initialize_child(OBJECT(s), "xram-irq-orgate", 316 &s->lpd.xram.irq_orgate, TYPE_OR_IRQ); 317 orgate = DEVICE(&s->lpd.xram.irq_orgate); 318 object_property_set_int(OBJECT(orgate), 319 "num-lines", nr_xrams, &error_fatal); 320 qdev_realize(orgate, NULL, &error_fatal); 321 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_XRAM_IRQ_0]); 322 323 for (i = 0; i < ARRAY_SIZE(s->lpd.xram.ctrl); i++) { 324 SysBusDevice *sbd; 325 MemoryRegion *mr; 326 327 object_initialize_child(OBJECT(s), "xram[*]", &s->lpd.xram.ctrl[i], 328 TYPE_XLNX_XRAM_CTRL); 329 sbd = SYS_BUS_DEVICE(&s->lpd.xram.ctrl[i]); 330 sysbus_realize(sbd, &error_fatal); 331 332 mr = sysbus_mmio_get_region(sbd, 0); 333 memory_region_add_subregion(&s->mr_ps, 334 MM_XRAMC + i * MM_XRAMC_SIZE, mr); 335 mr = sysbus_mmio_get_region(sbd, 1); 336 memory_region_add_subregion(&s->mr_ps, MM_XRAM + i * MiB, mr); 337 338 sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(orgate, i)); 339 } 340 } 341 342 static void versal_create_bbram(Versal *s, qemu_irq *pic) 343 { 344 SysBusDevice *sbd; 345 346 object_initialize_child_with_props(OBJECT(s), "bbram", &s->pmc.bbram, 347 sizeof(s->pmc.bbram), TYPE_XLNX_BBRAM, 348 &error_fatal, 349 "crc-zpads", "0", 350 NULL); 351 sbd = SYS_BUS_DEVICE(&s->pmc.bbram); 352 353 sysbus_realize(sbd, &error_fatal); 354 memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL, 355 sysbus_mmio_get_region(sbd, 0)); 356 sysbus_connect_irq(sbd, 0, 357 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1)); 358 } 359 360 static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base) 361 { 362 SysBusDevice *part = SYS_BUS_DEVICE(dev); 363 364 object_property_set_link(OBJECT(part), "efuse", 365 OBJECT(&s->pmc.efuse), &error_abort); 366 367 sysbus_realize(part, &error_abort); 368 memory_region_add_subregion(&s->mr_ps, base, 369 sysbus_mmio_get_region(part, 0)); 370 } 371 372 static void versal_create_efuse(Versal *s, qemu_irq *pic) 373 { 374 Object *bits = OBJECT(&s->pmc.efuse); 375 Object *ctrl = OBJECT(&s->pmc.efuse_ctrl); 376 Object *cache = OBJECT(&s->pmc.efuse_cache); 377 378 object_initialize_child(OBJECT(s), "efuse-ctrl", &s->pmc.efuse_ctrl, 379 TYPE_XLNX_VERSAL_EFUSE_CTRL); 380 381 object_initialize_child(OBJECT(s), "efuse-cache", &s->pmc.efuse_cache, 382 TYPE_XLNX_VERSAL_EFUSE_CACHE); 383 384 object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits, 385 sizeof(s->pmc.efuse), 386 TYPE_XLNX_EFUSE, &error_abort, 387 "efuse-nr", "3", 388 "efuse-size", "8192", 389 NULL); 390 391 qdev_realize(DEVICE(bits), NULL, &error_abort); 392 versal_realize_efuse_part(s, ctrl, MM_PMC_EFUSE_CTRL); 393 versal_realize_efuse_part(s, cache, MM_PMC_EFUSE_CACHE); 394 395 sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]); 396 } 397 398 static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic) 399 { 400 SysBusDevice *sbd; 401 402 object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr, 403 TYPE_XILINX_VERSAL_PMC_IOU_SLCR); 404 405 sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr); 406 sysbus_realize(sbd, &error_fatal); 407 408 memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR, 409 sysbus_mmio_get_region(sbd, 0)); 410 411 sysbus_connect_irq(sbd, 0, 412 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2)); 413 } 414 415 /* This takes the board allocated linear DDR memory and creates aliases 416 * for each split DDR range/aperture on the Versal address map. 417 */ 418 static void versal_map_ddr(Versal *s) 419 { 420 uint64_t size = memory_region_size(s->cfg.mr_ddr); 421 /* Describes the various split DDR access regions. */ 422 static const struct { 423 uint64_t base; 424 uint64_t size; 425 } addr_ranges[] = { 426 { MM_TOP_DDR, MM_TOP_DDR_SIZE }, 427 { MM_TOP_DDR_2, MM_TOP_DDR_2_SIZE }, 428 { MM_TOP_DDR_3, MM_TOP_DDR_3_SIZE }, 429 { MM_TOP_DDR_4, MM_TOP_DDR_4_SIZE } 430 }; 431 uint64_t offset = 0; 432 int i; 433 434 assert(ARRAY_SIZE(addr_ranges) == ARRAY_SIZE(s->noc.mr_ddr_ranges)); 435 for (i = 0; i < ARRAY_SIZE(addr_ranges) && size; i++) { 436 char *name; 437 uint64_t mapsize; 438 439 mapsize = size < addr_ranges[i].size ? size : addr_ranges[i].size; 440 name = g_strdup_printf("noc-ddr-range%d", i); 441 /* Create the MR alias. */ 442 memory_region_init_alias(&s->noc.mr_ddr_ranges[i], OBJECT(s), 443 name, s->cfg.mr_ddr, 444 offset, mapsize); 445 446 /* Map it onto the NoC MR. */ 447 memory_region_add_subregion(&s->mr_ps, addr_ranges[i].base, 448 &s->noc.mr_ddr_ranges[i]); 449 offset += mapsize; 450 size -= mapsize; 451 g_free(name); 452 } 453 } 454 455 static void versal_unimp_area(Versal *s, const char *name, 456 MemoryRegion *mr, 457 hwaddr base, hwaddr size) 458 { 459 DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE); 460 MemoryRegion *mr_dev; 461 462 qdev_prop_set_string(dev, "name", name); 463 qdev_prop_set_uint64(dev, "size", size); 464 object_property_add_child(OBJECT(s), name, OBJECT(dev)); 465 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 466 467 mr_dev = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 468 memory_region_add_subregion(mr, base, mr_dev); 469 } 470 471 static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level) 472 { 473 qemu_log_mask(LOG_UNIMP, 474 "Selecting between enabling SD mode or eMMC mode on " 475 "controller %d is not yet implemented\n", n); 476 } 477 478 static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level) 479 { 480 qemu_log_mask(LOG_UNIMP, 481 "Selecting between enabling the QSPI or OSPI linear address " 482 "region is not yet implemented\n"); 483 } 484 485 static void versal_unimp_irq_parity_imr(void *opaque, int n, int level) 486 { 487 qemu_log_mask(LOG_UNIMP, 488 "PMC SLCR parity interrupt behaviour " 489 "is not yet implemented\n"); 490 } 491 492 static void versal_unimp(Versal *s) 493 { 494 qemu_irq gpio_in; 495 496 versal_unimp_area(s, "psm", &s->mr_ps, 497 MM_PSM_START, MM_PSM_END - MM_PSM_START); 498 versal_unimp_area(s, "crl", &s->mr_ps, 499 MM_CRL, MM_CRL_SIZE); 500 versal_unimp_area(s, "crf", &s->mr_ps, 501 MM_FPD_CRF, MM_FPD_CRF_SIZE); 502 versal_unimp_area(s, "apu", &s->mr_ps, 503 MM_FPD_FPD_APU, MM_FPD_FPD_APU_SIZE); 504 versal_unimp_area(s, "crp", &s->mr_ps, 505 MM_PMC_CRP, MM_PMC_CRP_SIZE); 506 versal_unimp_area(s, "iou-scntr", &s->mr_ps, 507 MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE); 508 versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps, 509 MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE); 510 511 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel, 512 "sd-emmc-sel-dummy", 2); 513 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel, 514 "qspi-ospi-mux-sel-dummy", 1); 515 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr, 516 "irq-parity-imr-dummy", 1); 517 518 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0); 519 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 0, 520 gpio_in); 521 522 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1); 523 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 1, 524 gpio_in); 525 526 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 0); 527 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), 528 "qspi-ospi-mux-sel", 0, 529 gpio_in); 530 531 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0); 532 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), 533 SYSBUS_DEVICE_GPIO_IRQ, 0, 534 gpio_in); 535 } 536 537 static void versal_realize(DeviceState *dev, Error **errp) 538 { 539 Versal *s = XLNX_VERSAL(dev); 540 qemu_irq pic[XLNX_VERSAL_NR_IRQS]; 541 542 versal_create_apu_cpus(s); 543 versal_create_apu_gic(s, pic); 544 versal_create_uarts(s, pic); 545 versal_create_usbs(s, pic); 546 versal_create_gems(s, pic); 547 versal_create_admas(s, pic); 548 versal_create_sds(s, pic); 549 versal_create_pmc_apb_irq_orgate(s, pic); 550 versal_create_rtc(s, pic); 551 versal_create_xrams(s, pic); 552 versal_create_bbram(s, pic); 553 versal_create_efuse(s, pic); 554 versal_create_pmc_iou_slcr(s, pic); 555 versal_map_ddr(s); 556 versal_unimp(s); 557 558 /* Create the On Chip Memory (OCM). */ 559 memory_region_init_ram(&s->lpd.mr_ocm, OBJECT(s), "ocm", 560 MM_OCM_SIZE, &error_fatal); 561 562 memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0); 563 memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0); 564 } 565 566 static void versal_init(Object *obj) 567 { 568 Versal *s = XLNX_VERSAL(obj); 569 570 memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX); 571 memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX); 572 } 573 574 static Property versal_properties[] = { 575 DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION, 576 MemoryRegion *), 577 DEFINE_PROP_UINT32("psci-conduit", Versal, cfg.psci_conduit, 0), 578 DEFINE_PROP_END_OF_LIST() 579 }; 580 581 static void versal_class_init(ObjectClass *klass, void *data) 582 { 583 DeviceClass *dc = DEVICE_CLASS(klass); 584 585 dc->realize = versal_realize; 586 device_class_set_props(dc, versal_properties); 587 /* No VMSD since we haven't got any top-level SoC state to save. */ 588 } 589 590 static const TypeInfo versal_info = { 591 .name = TYPE_XLNX_VERSAL, 592 .parent = TYPE_SYS_BUS_DEVICE, 593 .instance_size = sizeof(Versal), 594 .instance_init = versal_init, 595 .class_init = versal_class_init, 596 }; 597 598 static void versal_register_types(void) 599 { 600 type_register_static(&versal_info); 601 } 602 603 type_init(versal_register_types); 604