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 "qapi/qmp/qlist.h" 16 #include "qemu/module.h" 17 #include "hw/sysbus.h" 18 #include "net/net.h" 19 #include "sysemu/sysemu.h" 20 #include "sysemu/kvm.h" 21 #include "hw/arm/boot.h" 22 #include "kvm_arm.h" 23 #include "hw/misc/unimp.h" 24 #include "hw/arm/xlnx-versal.h" 25 #include "qemu/log.h" 26 #include "target/arm/cpu-qom.h" 27 #include "target/arm/gtimer.h" 28 29 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72") 30 #define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f") 31 #define GEM_REVISION 0x40070106 32 33 #define VERSAL_NUM_PMC_APB_IRQS 18 34 #define NUM_OSPI_IRQ_LINES 3 35 36 static void versal_create_apu_cpus(Versal *s) 37 { 38 int i; 39 40 object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster, 41 TYPE_CPU_CLUSTER); 42 qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0); 43 44 for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) { 45 Object *obj; 46 47 object_initialize_child(OBJECT(&s->fpd.apu.cluster), 48 "apu-cpu[*]", &s->fpd.apu.cpu[i], 49 XLNX_VERSAL_ACPU_TYPE); 50 obj = OBJECT(&s->fpd.apu.cpu[i]); 51 if (i) { 52 /* Secondary CPUs start in powered-down state */ 53 object_property_set_bool(obj, "start-powered-off", true, 54 &error_abort); 55 } 56 57 object_property_set_int(obj, "core-count", ARRAY_SIZE(s->fpd.apu.cpu), 58 &error_abort); 59 object_property_set_link(obj, "memory", OBJECT(&s->fpd.apu.mr), 60 &error_abort); 61 qdev_realize(DEVICE(obj), NULL, &error_fatal); 62 } 63 64 qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal); 65 } 66 67 static void versal_create_apu_gic(Versal *s, qemu_irq *pic) 68 { 69 static const uint64_t addrs[] = { 70 MM_GIC_APU_DIST_MAIN, 71 MM_GIC_APU_REDIST_0 72 }; 73 SysBusDevice *gicbusdev; 74 DeviceState *gicdev; 75 QList *redist_region_count; 76 int nr_apu_cpus = ARRAY_SIZE(s->fpd.apu.cpu); 77 int i; 78 79 object_initialize_child(OBJECT(s), "apu-gic", &s->fpd.apu.gic, 80 gicv3_class_name()); 81 gicbusdev = SYS_BUS_DEVICE(&s->fpd.apu.gic); 82 gicdev = DEVICE(&s->fpd.apu.gic); 83 qdev_prop_set_uint32(gicdev, "revision", 3); 84 qdev_prop_set_uint32(gicdev, "num-cpu", nr_apu_cpus); 85 qdev_prop_set_uint32(gicdev, "num-irq", XLNX_VERSAL_NR_IRQS + 32); 86 87 redist_region_count = qlist_new(); 88 qlist_append_int(redist_region_count, nr_apu_cpus); 89 qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count); 90 91 qdev_prop_set_bit(gicdev, "has-security-extensions", true); 92 93 sysbus_realize(SYS_BUS_DEVICE(&s->fpd.apu.gic), &error_fatal); 94 95 for (i = 0; i < ARRAY_SIZE(addrs); i++) { 96 MemoryRegion *mr; 97 98 mr = sysbus_mmio_get_region(gicbusdev, i); 99 memory_region_add_subregion(&s->fpd.apu.mr, addrs[i], mr); 100 } 101 102 for (i = 0; i < nr_apu_cpus; i++) { 103 DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]); 104 int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS; 105 qemu_irq maint_irq; 106 int ti; 107 /* Mapping from the output timer irq lines from the CPU to the 108 * GIC PPI inputs. 109 */ 110 const int timer_irq[] = { 111 [GTIMER_PHYS] = VERSAL_TIMER_NS_EL1_IRQ, 112 [GTIMER_VIRT] = VERSAL_TIMER_VIRT_IRQ, 113 [GTIMER_HYP] = VERSAL_TIMER_NS_EL2_IRQ, 114 [GTIMER_SEC] = VERSAL_TIMER_S_EL1_IRQ, 115 }; 116 117 for (ti = 0; ti < ARRAY_SIZE(timer_irq); ti++) { 118 qdev_connect_gpio_out(cpudev, ti, 119 qdev_get_gpio_in(gicdev, 120 ppibase + timer_irq[ti])); 121 } 122 maint_irq = qdev_get_gpio_in(gicdev, 123 ppibase + VERSAL_GIC_MAINT_IRQ); 124 qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 125 0, maint_irq); 126 sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); 127 sysbus_connect_irq(gicbusdev, i + nr_apu_cpus, 128 qdev_get_gpio_in(cpudev, ARM_CPU_FIQ)); 129 sysbus_connect_irq(gicbusdev, i + 2 * nr_apu_cpus, 130 qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ)); 131 sysbus_connect_irq(gicbusdev, i + 3 * nr_apu_cpus, 132 qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); 133 } 134 135 for (i = 0; i < XLNX_VERSAL_NR_IRQS; i++) { 136 pic[i] = qdev_get_gpio_in(gicdev, i); 137 } 138 } 139 140 static void versal_create_rpu_cpus(Versal *s) 141 { 142 int i; 143 144 object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster, 145 TYPE_CPU_CLUSTER); 146 qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1); 147 148 for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) { 149 Object *obj; 150 151 object_initialize_child(OBJECT(&s->lpd.rpu.cluster), 152 "rpu-cpu[*]", &s->lpd.rpu.cpu[i], 153 XLNX_VERSAL_RCPU_TYPE); 154 obj = OBJECT(&s->lpd.rpu.cpu[i]); 155 object_property_set_bool(obj, "start-powered-off", true, 156 &error_abort); 157 158 object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort); 159 object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu), 160 &error_abort); 161 object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr), 162 &error_abort); 163 qdev_realize(DEVICE(obj), NULL, &error_fatal); 164 } 165 166 qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal); 167 } 168 169 static void versal_create_uarts(Versal *s, qemu_irq *pic) 170 { 171 int i; 172 173 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) { 174 static const int irqs[] = { VERSAL_UART0_IRQ_0, VERSAL_UART1_IRQ_0}; 175 static const uint64_t addrs[] = { MM_UART0, MM_UART1 }; 176 char *name = g_strdup_printf("uart%d", i); 177 DeviceState *dev; 178 MemoryRegion *mr; 179 180 object_initialize_child(OBJECT(s), name, &s->lpd.iou.uart[i], 181 TYPE_PL011); 182 dev = DEVICE(&s->lpd.iou.uart[i]); 183 qdev_prop_set_chr(dev, "chardev", serial_hd(i)); 184 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 185 186 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 187 memory_region_add_subregion(&s->mr_ps, addrs[i], mr); 188 189 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]); 190 g_free(name); 191 } 192 } 193 194 static void versal_create_canfds(Versal *s, qemu_irq *pic) 195 { 196 int i; 197 uint32_t irqs[] = { VERSAL_CANFD0_IRQ_0, VERSAL_CANFD1_IRQ_0}; 198 uint64_t addrs[] = { MM_CANFD0, MM_CANFD1 }; 199 200 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.canfd); i++) { 201 char *name = g_strdup_printf("canfd%d", i); 202 SysBusDevice *sbd; 203 MemoryRegion *mr; 204 205 object_initialize_child(OBJECT(s), name, &s->lpd.iou.canfd[i], 206 TYPE_XILINX_CANFD); 207 sbd = SYS_BUS_DEVICE(&s->lpd.iou.canfd[i]); 208 209 object_property_set_int(OBJECT(&s->lpd.iou.canfd[i]), "ext_clk_freq", 210 XLNX_VERSAL_CANFD_REF_CLK , &error_abort); 211 212 object_property_set_link(OBJECT(&s->lpd.iou.canfd[i]), "canfdbus", 213 OBJECT(s->lpd.iou.canbus[i]), 214 &error_abort); 215 216 sysbus_realize(sbd, &error_fatal); 217 218 mr = sysbus_mmio_get_region(sbd, 0); 219 memory_region_add_subregion(&s->mr_ps, addrs[i], mr); 220 221 sysbus_connect_irq(sbd, 0, pic[irqs[i]]); 222 g_free(name); 223 } 224 } 225 226 static void versal_create_usbs(Versal *s, qemu_irq *pic) 227 { 228 DeviceState *dev; 229 MemoryRegion *mr; 230 231 object_initialize_child(OBJECT(s), "usb2", &s->lpd.iou.usb, 232 TYPE_XILINX_VERSAL_USB2); 233 dev = DEVICE(&s->lpd.iou.usb); 234 235 object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps), 236 &error_abort); 237 qdev_prop_set_uint32(dev, "intrs", 1); 238 qdev_prop_set_uint32(dev, "slots", 2); 239 240 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 241 242 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 243 memory_region_add_subregion(&s->mr_ps, MM_USB_0, mr); 244 245 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_USB0_IRQ_0]); 246 247 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); 248 memory_region_add_subregion(&s->mr_ps, MM_USB2_CTRL_REGS, mr); 249 } 250 251 static void versal_create_gems(Versal *s, qemu_irq *pic) 252 { 253 int i; 254 255 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) { 256 static const int irqs[] = { VERSAL_GEM0_IRQ_0, VERSAL_GEM1_IRQ_0}; 257 static const uint64_t addrs[] = { MM_GEM0, MM_GEM1 }; 258 char *name = g_strdup_printf("gem%d", i); 259 DeviceState *dev; 260 MemoryRegion *mr; 261 OrIRQState *or_irq; 262 263 object_initialize_child(OBJECT(s), name, &s->lpd.iou.gem[i], 264 TYPE_CADENCE_GEM); 265 or_irq = &s->lpd.iou.gem_irq_orgate[i]; 266 object_initialize_child(OBJECT(s), "gem-irq-orgate[*]", 267 or_irq, TYPE_OR_IRQ); 268 dev = DEVICE(&s->lpd.iou.gem[i]); 269 qemu_configure_nic_device(dev, true, NULL); 270 object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort); 271 object_property_set_int(OBJECT(dev), "num-priority-queues", 2, 272 &error_abort); 273 object_property_set_int(OBJECT(or_irq), 274 "num-lines", 2, &error_fatal); 275 qdev_realize(DEVICE(or_irq), NULL, &error_fatal); 276 qdev_connect_gpio_out(DEVICE(or_irq), 0, pic[irqs[i]]); 277 278 object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps), 279 &error_abort); 280 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 281 282 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 283 memory_region_add_subregion(&s->mr_ps, addrs[i], mr); 284 285 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(DEVICE(or_irq), 0)); 286 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, qdev_get_gpio_in(DEVICE(or_irq), 1)); 287 g_free(name); 288 } 289 } 290 291 static void versal_create_admas(Versal *s, qemu_irq *pic) 292 { 293 int i; 294 295 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) { 296 char *name = g_strdup_printf("adma%d", i); 297 DeviceState *dev; 298 MemoryRegion *mr; 299 300 object_initialize_child(OBJECT(s), name, &s->lpd.iou.adma[i], 301 TYPE_XLNX_ZDMA); 302 dev = DEVICE(&s->lpd.iou.adma[i]); 303 object_property_set_int(OBJECT(dev), "bus-width", 128, &error_abort); 304 object_property_set_link(OBJECT(dev), "dma", 305 OBJECT(get_system_memory()), &error_fatal); 306 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 307 308 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 309 memory_region_add_subregion(&s->mr_ps, 310 MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr); 311 312 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]); 313 g_free(name); 314 } 315 } 316 317 #define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */ 318 static void versal_create_sds(Versal *s, qemu_irq *pic) 319 { 320 int i; 321 322 for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) { 323 DeviceState *dev; 324 MemoryRegion *mr; 325 326 object_initialize_child(OBJECT(s), "sd[*]", &s->pmc.iou.sd[i], 327 TYPE_SYSBUS_SDHCI); 328 dev = DEVICE(&s->pmc.iou.sd[i]); 329 330 object_property_set_uint(OBJECT(dev), "sd-spec-version", 3, 331 &error_fatal); 332 object_property_set_uint(OBJECT(dev), "capareg", SDHCI_CAPABILITIES, 333 &error_fatal); 334 object_property_set_uint(OBJECT(dev), "uhs", UHS_I, &error_fatal); 335 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 336 337 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 338 memory_region_add_subregion(&s->mr_ps, 339 MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr); 340 341 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, 342 pic[VERSAL_SD0_IRQ_0 + i * 2]); 343 } 344 } 345 346 static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic) 347 { 348 DeviceState *orgate; 349 350 /* 351 * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following 352 * models: 353 * - RTC 354 * - BBRAM 355 * - PMC SLCR 356 * - CFRAME regs (input 3 - 17 to the orgate) 357 */ 358 object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate", 359 &s->pmc.apb_irq_orgate, TYPE_OR_IRQ); 360 orgate = DEVICE(&s->pmc.apb_irq_orgate); 361 object_property_set_int(OBJECT(orgate), 362 "num-lines", VERSAL_NUM_PMC_APB_IRQS, &error_fatal); 363 qdev_realize(orgate, NULL, &error_fatal); 364 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]); 365 } 366 367 static void versal_create_rtc(Versal *s, qemu_irq *pic) 368 { 369 SysBusDevice *sbd; 370 MemoryRegion *mr; 371 372 object_initialize_child(OBJECT(s), "rtc", &s->pmc.rtc, 373 TYPE_XLNX_ZYNQMP_RTC); 374 sbd = SYS_BUS_DEVICE(&s->pmc.rtc); 375 sysbus_realize(sbd, &error_fatal); 376 377 mr = sysbus_mmio_get_region(sbd, 0); 378 memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr); 379 380 /* 381 * TODO: Connect the ALARM and SECONDS interrupts once our RTC model 382 * supports them. 383 */ 384 sysbus_connect_irq(sbd, 1, 385 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 0)); 386 } 387 388 static void versal_create_trng(Versal *s, qemu_irq *pic) 389 { 390 SysBusDevice *sbd; 391 MemoryRegion *mr; 392 393 object_initialize_child(OBJECT(s), "trng", &s->pmc.trng, 394 TYPE_XLNX_VERSAL_TRNG); 395 sbd = SYS_BUS_DEVICE(&s->pmc.trng); 396 sysbus_realize(sbd, &error_fatal); 397 398 mr = sysbus_mmio_get_region(sbd, 0); 399 memory_region_add_subregion(&s->mr_ps, MM_PMC_TRNG, mr); 400 sysbus_connect_irq(sbd, 0, pic[VERSAL_TRNG_IRQ]); 401 } 402 403 static void versal_create_xrams(Versal *s, qemu_irq *pic) 404 { 405 int nr_xrams = ARRAY_SIZE(s->lpd.xram.ctrl); 406 DeviceState *orgate; 407 int i; 408 409 /* XRAM IRQs get ORed into a single line. */ 410 object_initialize_child(OBJECT(s), "xram-irq-orgate", 411 &s->lpd.xram.irq_orgate, TYPE_OR_IRQ); 412 orgate = DEVICE(&s->lpd.xram.irq_orgate); 413 object_property_set_int(OBJECT(orgate), 414 "num-lines", nr_xrams, &error_fatal); 415 qdev_realize(orgate, NULL, &error_fatal); 416 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_XRAM_IRQ_0]); 417 418 for (i = 0; i < ARRAY_SIZE(s->lpd.xram.ctrl); i++) { 419 SysBusDevice *sbd; 420 MemoryRegion *mr; 421 422 object_initialize_child(OBJECT(s), "xram[*]", &s->lpd.xram.ctrl[i], 423 TYPE_XLNX_XRAM_CTRL); 424 sbd = SYS_BUS_DEVICE(&s->lpd.xram.ctrl[i]); 425 sysbus_realize(sbd, &error_fatal); 426 427 mr = sysbus_mmio_get_region(sbd, 0); 428 memory_region_add_subregion(&s->mr_ps, 429 MM_XRAMC + i * MM_XRAMC_SIZE, mr); 430 mr = sysbus_mmio_get_region(sbd, 1); 431 memory_region_add_subregion(&s->mr_ps, MM_XRAM + i * MiB, mr); 432 433 sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(orgate, i)); 434 } 435 } 436 437 static void versal_create_bbram(Versal *s, qemu_irq *pic) 438 { 439 SysBusDevice *sbd; 440 441 object_initialize_child_with_props(OBJECT(s), "bbram", &s->pmc.bbram, 442 sizeof(s->pmc.bbram), TYPE_XLNX_BBRAM, 443 &error_fatal, 444 "crc-zpads", "0", 445 NULL); 446 sbd = SYS_BUS_DEVICE(&s->pmc.bbram); 447 448 sysbus_realize(sbd, &error_fatal); 449 memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL, 450 sysbus_mmio_get_region(sbd, 0)); 451 sysbus_connect_irq(sbd, 0, 452 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1)); 453 } 454 455 static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base) 456 { 457 SysBusDevice *part = SYS_BUS_DEVICE(dev); 458 459 object_property_set_link(OBJECT(part), "efuse", 460 OBJECT(&s->pmc.efuse), &error_abort); 461 462 sysbus_realize(part, &error_abort); 463 memory_region_add_subregion(&s->mr_ps, base, 464 sysbus_mmio_get_region(part, 0)); 465 } 466 467 static void versal_create_efuse(Versal *s, qemu_irq *pic) 468 { 469 Object *bits = OBJECT(&s->pmc.efuse); 470 Object *ctrl = OBJECT(&s->pmc.efuse_ctrl); 471 Object *cache = OBJECT(&s->pmc.efuse_cache); 472 473 object_initialize_child(OBJECT(s), "efuse-ctrl", &s->pmc.efuse_ctrl, 474 TYPE_XLNX_VERSAL_EFUSE_CTRL); 475 476 object_initialize_child(OBJECT(s), "efuse-cache", &s->pmc.efuse_cache, 477 TYPE_XLNX_VERSAL_EFUSE_CACHE); 478 479 object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits, 480 sizeof(s->pmc.efuse), 481 TYPE_XLNX_EFUSE, &error_abort, 482 "efuse-nr", "3", 483 "efuse-size", "8192", 484 NULL); 485 486 qdev_realize(DEVICE(bits), NULL, &error_abort); 487 versal_realize_efuse_part(s, ctrl, MM_PMC_EFUSE_CTRL); 488 versal_realize_efuse_part(s, cache, MM_PMC_EFUSE_CACHE); 489 490 sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]); 491 } 492 493 static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic) 494 { 495 SysBusDevice *sbd; 496 497 object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr, 498 TYPE_XILINX_VERSAL_PMC_IOU_SLCR); 499 500 sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr); 501 sysbus_realize(sbd, &error_fatal); 502 503 memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR, 504 sysbus_mmio_get_region(sbd, 0)); 505 506 sysbus_connect_irq(sbd, 0, 507 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2)); 508 } 509 510 static void versal_create_ospi(Versal *s, qemu_irq *pic) 511 { 512 SysBusDevice *sbd; 513 MemoryRegion *mr_dac; 514 qemu_irq ospi_mux_sel; 515 DeviceState *orgate; 516 517 memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s), 518 "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE); 519 520 object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi, 521 TYPE_XILINX_VERSAL_OSPI); 522 523 mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1); 524 memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac); 525 526 /* Create the OSPI destination DMA */ 527 object_initialize_child(OBJECT(s), "versal-ospi-dma-dst", 528 &s->pmc.iou.ospi.dma_dst, 529 TYPE_XLNX_CSU_DMA); 530 531 object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst), 532 "dma", OBJECT(get_system_memory()), 533 &error_abort); 534 535 sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst); 536 sysbus_realize(sbd, &error_fatal); 537 538 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST, 539 sysbus_mmio_get_region(sbd, 0)); 540 541 /* Create the OSPI source DMA */ 542 object_initialize_child(OBJECT(s), "versal-ospi-dma-src", 543 &s->pmc.iou.ospi.dma_src, 544 TYPE_XLNX_CSU_DMA); 545 546 object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst", 547 false, &error_abort); 548 549 object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src), 550 "dma", OBJECT(mr_dac), &error_abort); 551 552 object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src), 553 "stream-connected-dma", 554 OBJECT(&s->pmc.iou.ospi.dma_dst), 555 &error_abort); 556 557 sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src); 558 sysbus_realize(sbd, &error_fatal); 559 560 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC, 561 sysbus_mmio_get_region(sbd, 0)); 562 563 /* Realize the OSPI */ 564 object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src", 565 OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort); 566 567 sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi); 568 sysbus_realize(sbd, &error_fatal); 569 570 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI, 571 sysbus_mmio_get_region(sbd, 0)); 572 573 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC, 574 &s->pmc.iou.ospi.linear_mr); 575 576 /* ospi_mux_sel */ 577 ospi_mux_sel = qdev_get_gpio_in_named(DEVICE(&s->pmc.iou.ospi.ospi), 578 "ospi-mux-sel", 0); 579 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "ospi-mux-sel", 0, 580 ospi_mux_sel); 581 582 /* OSPI irq */ 583 object_initialize_child(OBJECT(s), "ospi-irq-orgate", 584 &s->pmc.iou.ospi.irq_orgate, TYPE_OR_IRQ); 585 object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq_orgate), 586 "num-lines", NUM_OSPI_IRQ_LINES, &error_fatal); 587 588 orgate = DEVICE(&s->pmc.iou.ospi.irq_orgate); 589 qdev_realize(orgate, NULL, &error_fatal); 590 591 sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0, 592 qdev_get_gpio_in(orgate, 0)); 593 sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0, 594 qdev_get_gpio_in(orgate, 1)); 595 sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0, 596 qdev_get_gpio_in(orgate, 2)); 597 598 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]); 599 } 600 601 static void versal_create_cfu(Versal *s, qemu_irq *pic) 602 { 603 SysBusDevice *sbd; 604 DeviceState *dev; 605 int i; 606 const struct { 607 uint64_t reg_base; 608 uint64_t fdri_base; 609 } cframe_addr[] = { 610 { MM_PMC_CFRAME0_REG, MM_PMC_CFRAME0_FDRI }, 611 { MM_PMC_CFRAME1_REG, MM_PMC_CFRAME1_FDRI }, 612 { MM_PMC_CFRAME2_REG, MM_PMC_CFRAME2_FDRI }, 613 { MM_PMC_CFRAME3_REG, MM_PMC_CFRAME3_FDRI }, 614 { MM_PMC_CFRAME4_REG, MM_PMC_CFRAME4_FDRI }, 615 { MM_PMC_CFRAME5_REG, MM_PMC_CFRAME5_FDRI }, 616 { MM_PMC_CFRAME6_REG, MM_PMC_CFRAME6_FDRI }, 617 { MM_PMC_CFRAME7_REG, MM_PMC_CFRAME7_FDRI }, 618 { MM_PMC_CFRAME8_REG, MM_PMC_CFRAME8_FDRI }, 619 { MM_PMC_CFRAME9_REG, MM_PMC_CFRAME9_FDRI }, 620 { MM_PMC_CFRAME10_REG, MM_PMC_CFRAME10_FDRI }, 621 { MM_PMC_CFRAME11_REG, MM_PMC_CFRAME11_FDRI }, 622 { MM_PMC_CFRAME12_REG, MM_PMC_CFRAME12_FDRI }, 623 { MM_PMC_CFRAME13_REG, MM_PMC_CFRAME13_FDRI }, 624 { MM_PMC_CFRAME14_REG, MM_PMC_CFRAME14_FDRI }, 625 }; 626 const struct { 627 uint32_t blktype0_frames; 628 uint32_t blktype1_frames; 629 uint32_t blktype2_frames; 630 uint32_t blktype3_frames; 631 uint32_t blktype4_frames; 632 uint32_t blktype5_frames; 633 uint32_t blktype6_frames; 634 } cframe_cfg[] = { 635 [0] = { 34111, 3528, 12800, 11, 5, 1, 1 }, 636 [1] = { 38498, 3841, 15361, 13, 7, 3, 1 }, 637 [2] = { 38498, 3841, 15361, 13, 7, 3, 1 }, 638 [3] = { 38498, 3841, 15361, 13, 7, 3, 1 }, 639 }; 640 641 /* CFU FDRO */ 642 object_initialize_child(OBJECT(s), "cfu-fdro", &s->pmc.cfu_fdro, 643 TYPE_XLNX_VERSAL_CFU_FDRO); 644 sbd = SYS_BUS_DEVICE(&s->pmc.cfu_fdro); 645 646 sysbus_realize(sbd, &error_fatal); 647 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_FDRO, 648 sysbus_mmio_get_region(sbd, 0)); 649 650 /* CFRAME REG */ 651 for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) { 652 g_autofree char *name = g_strdup_printf("cframe%d", i); 653 654 object_initialize_child(OBJECT(s), name, &s->pmc.cframe[i], 655 TYPE_XLNX_VERSAL_CFRAME_REG); 656 657 sbd = SYS_BUS_DEVICE(&s->pmc.cframe[i]); 658 dev = DEVICE(&s->pmc.cframe[i]); 659 660 if (i < ARRAY_SIZE(cframe_cfg)) { 661 object_property_set_int(OBJECT(dev), "blktype0-frames", 662 cframe_cfg[i].blktype0_frames, 663 &error_abort); 664 object_property_set_int(OBJECT(dev), "blktype1-frames", 665 cframe_cfg[i].blktype1_frames, 666 &error_abort); 667 object_property_set_int(OBJECT(dev), "blktype2-frames", 668 cframe_cfg[i].blktype2_frames, 669 &error_abort); 670 object_property_set_int(OBJECT(dev), "blktype3-frames", 671 cframe_cfg[i].blktype3_frames, 672 &error_abort); 673 object_property_set_int(OBJECT(dev), "blktype4-frames", 674 cframe_cfg[i].blktype4_frames, 675 &error_abort); 676 object_property_set_int(OBJECT(dev), "blktype5-frames", 677 cframe_cfg[i].blktype5_frames, 678 &error_abort); 679 object_property_set_int(OBJECT(dev), "blktype6-frames", 680 cframe_cfg[i].blktype6_frames, 681 &error_abort); 682 } 683 object_property_set_link(OBJECT(dev), "cfu-fdro", 684 OBJECT(&s->pmc.cfu_fdro), &error_fatal); 685 686 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 687 688 memory_region_add_subregion(&s->mr_ps, cframe_addr[i].reg_base, 689 sysbus_mmio_get_region(sbd, 0)); 690 memory_region_add_subregion(&s->mr_ps, cframe_addr[i].fdri_base, 691 sysbus_mmio_get_region(sbd, 1)); 692 sysbus_connect_irq(sbd, 0, 693 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 694 3 + i)); 695 } 696 697 /* CFRAME BCAST */ 698 object_initialize_child(OBJECT(s), "cframe_bcast", &s->pmc.cframe_bcast, 699 TYPE_XLNX_VERSAL_CFRAME_BCAST_REG); 700 701 sbd = SYS_BUS_DEVICE(&s->pmc.cframe_bcast); 702 dev = DEVICE(&s->pmc.cframe_bcast); 703 704 for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) { 705 g_autofree char *propname = g_strdup_printf("cframe%d", i); 706 object_property_set_link(OBJECT(dev), propname, 707 OBJECT(&s->pmc.cframe[i]), &error_fatal); 708 } 709 710 sysbus_realize(sbd, &error_fatal); 711 712 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_REG, 713 sysbus_mmio_get_region(sbd, 0)); 714 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_FDRI, 715 sysbus_mmio_get_region(sbd, 1)); 716 717 /* CFU APB */ 718 object_initialize_child(OBJECT(s), "cfu-apb", &s->pmc.cfu_apb, 719 TYPE_XLNX_VERSAL_CFU_APB); 720 sbd = SYS_BUS_DEVICE(&s->pmc.cfu_apb); 721 dev = DEVICE(&s->pmc.cfu_apb); 722 723 for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) { 724 g_autofree char *propname = g_strdup_printf("cframe%d", i); 725 object_property_set_link(OBJECT(dev), propname, 726 OBJECT(&s->pmc.cframe[i]), &error_fatal); 727 } 728 729 sysbus_realize(sbd, &error_fatal); 730 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_APB, 731 sysbus_mmio_get_region(sbd, 0)); 732 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM, 733 sysbus_mmio_get_region(sbd, 1)); 734 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM_2, 735 sysbus_mmio_get_region(sbd, 2)); 736 sysbus_connect_irq(sbd, 0, pic[VERSAL_CFU_IRQ_0]); 737 738 /* CFU SFR */ 739 object_initialize_child(OBJECT(s), "cfu-sfr", &s->pmc.cfu_sfr, 740 TYPE_XLNX_VERSAL_CFU_SFR); 741 742 sbd = SYS_BUS_DEVICE(&s->pmc.cfu_sfr); 743 744 object_property_set_link(OBJECT(&s->pmc.cfu_sfr), 745 "cfu", OBJECT(&s->pmc.cfu_apb), &error_abort); 746 747 sysbus_realize(sbd, &error_fatal); 748 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_SFR, 749 sysbus_mmio_get_region(sbd, 0)); 750 } 751 752 static void versal_create_crl(Versal *s, qemu_irq *pic) 753 { 754 SysBusDevice *sbd; 755 int i; 756 757 object_initialize_child(OBJECT(s), "crl", &s->lpd.crl, 758 TYPE_XLNX_VERSAL_CRL); 759 sbd = SYS_BUS_DEVICE(&s->lpd.crl); 760 761 for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) { 762 g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i); 763 764 object_property_set_link(OBJECT(&s->lpd.crl), 765 name, OBJECT(&s->lpd.rpu.cpu[i]), 766 &error_abort); 767 } 768 769 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) { 770 g_autofree gchar *name = g_strdup_printf("gem[%d]", i); 771 772 object_property_set_link(OBJECT(&s->lpd.crl), 773 name, OBJECT(&s->lpd.iou.gem[i]), 774 &error_abort); 775 } 776 777 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) { 778 g_autofree gchar *name = g_strdup_printf("adma[%d]", i); 779 780 object_property_set_link(OBJECT(&s->lpd.crl), 781 name, OBJECT(&s->lpd.iou.adma[i]), 782 &error_abort); 783 } 784 785 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) { 786 g_autofree gchar *name = g_strdup_printf("uart[%d]", i); 787 788 object_property_set_link(OBJECT(&s->lpd.crl), 789 name, OBJECT(&s->lpd.iou.uart[i]), 790 &error_abort); 791 } 792 793 object_property_set_link(OBJECT(&s->lpd.crl), 794 "usb", OBJECT(&s->lpd.iou.usb), 795 &error_abort); 796 797 sysbus_realize(sbd, &error_fatal); 798 memory_region_add_subregion(&s->mr_ps, MM_CRL, 799 sysbus_mmio_get_region(sbd, 0)); 800 sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]); 801 } 802 803 /* This takes the board allocated linear DDR memory and creates aliases 804 * for each split DDR range/aperture on the Versal address map. 805 */ 806 static void versal_map_ddr(Versal *s) 807 { 808 uint64_t size = memory_region_size(s->cfg.mr_ddr); 809 /* Describes the various split DDR access regions. */ 810 static const struct { 811 uint64_t base; 812 uint64_t size; 813 } addr_ranges[] = { 814 { MM_TOP_DDR, MM_TOP_DDR_SIZE }, 815 { MM_TOP_DDR_2, MM_TOP_DDR_2_SIZE }, 816 { MM_TOP_DDR_3, MM_TOP_DDR_3_SIZE }, 817 { MM_TOP_DDR_4, MM_TOP_DDR_4_SIZE } 818 }; 819 uint64_t offset = 0; 820 int i; 821 822 assert(ARRAY_SIZE(addr_ranges) == ARRAY_SIZE(s->noc.mr_ddr_ranges)); 823 for (i = 0; i < ARRAY_SIZE(addr_ranges) && size; i++) { 824 char *name; 825 uint64_t mapsize; 826 827 mapsize = size < addr_ranges[i].size ? size : addr_ranges[i].size; 828 name = g_strdup_printf("noc-ddr-range%d", i); 829 /* Create the MR alias. */ 830 memory_region_init_alias(&s->noc.mr_ddr_ranges[i], OBJECT(s), 831 name, s->cfg.mr_ddr, 832 offset, mapsize); 833 834 /* Map it onto the NoC MR. */ 835 memory_region_add_subregion(&s->mr_ps, addr_ranges[i].base, 836 &s->noc.mr_ddr_ranges[i]); 837 offset += mapsize; 838 size -= mapsize; 839 g_free(name); 840 } 841 } 842 843 static void versal_unimp_area(Versal *s, const char *name, 844 MemoryRegion *mr, 845 hwaddr base, hwaddr size) 846 { 847 DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE); 848 MemoryRegion *mr_dev; 849 850 qdev_prop_set_string(dev, "name", name); 851 qdev_prop_set_uint64(dev, "size", size); 852 object_property_add_child(OBJECT(s), name, OBJECT(dev)); 853 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 854 855 mr_dev = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 856 memory_region_add_subregion(mr, base, mr_dev); 857 } 858 859 static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level) 860 { 861 qemu_log_mask(LOG_UNIMP, 862 "Selecting between enabling SD mode or eMMC mode on " 863 "controller %d is not yet implemented\n", n); 864 } 865 866 static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level) 867 { 868 qemu_log_mask(LOG_UNIMP, 869 "Selecting between enabling the QSPI or OSPI linear address " 870 "region is not yet implemented\n"); 871 } 872 873 static void versal_unimp_irq_parity_imr(void *opaque, int n, int level) 874 { 875 qemu_log_mask(LOG_UNIMP, 876 "PMC SLCR parity interrupt behaviour " 877 "is not yet implemented\n"); 878 } 879 880 static void versal_unimp(Versal *s) 881 { 882 qemu_irq gpio_in; 883 884 versal_unimp_area(s, "psm", &s->mr_ps, 885 MM_PSM_START, MM_PSM_END - MM_PSM_START); 886 versal_unimp_area(s, "crf", &s->mr_ps, 887 MM_FPD_CRF, MM_FPD_CRF_SIZE); 888 versal_unimp_area(s, "apu", &s->mr_ps, 889 MM_FPD_FPD_APU, MM_FPD_FPD_APU_SIZE); 890 versal_unimp_area(s, "crp", &s->mr_ps, 891 MM_PMC_CRP, MM_PMC_CRP_SIZE); 892 versal_unimp_area(s, "iou-scntr", &s->mr_ps, 893 MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE); 894 versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps, 895 MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE); 896 897 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel, 898 "sd-emmc-sel-dummy", 2); 899 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel, 900 "qspi-ospi-mux-sel-dummy", 1); 901 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr, 902 "irq-parity-imr-dummy", 1); 903 904 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0); 905 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 0, 906 gpio_in); 907 908 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1); 909 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 1, 910 gpio_in); 911 912 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 0); 913 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), 914 "qspi-ospi-mux-sel", 0, 915 gpio_in); 916 917 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0); 918 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), 919 SYSBUS_DEVICE_GPIO_IRQ, 0, 920 gpio_in); 921 } 922 923 static void versal_realize(DeviceState *dev, Error **errp) 924 { 925 Versal *s = XLNX_VERSAL(dev); 926 qemu_irq pic[XLNX_VERSAL_NR_IRQS]; 927 928 versal_create_apu_cpus(s); 929 versal_create_apu_gic(s, pic); 930 versal_create_rpu_cpus(s); 931 versal_create_uarts(s, pic); 932 versal_create_canfds(s, pic); 933 versal_create_usbs(s, pic); 934 versal_create_gems(s, pic); 935 versal_create_admas(s, pic); 936 versal_create_sds(s, pic); 937 versal_create_pmc_apb_irq_orgate(s, pic); 938 versal_create_rtc(s, pic); 939 versal_create_trng(s, pic); 940 versal_create_xrams(s, pic); 941 versal_create_bbram(s, pic); 942 versal_create_efuse(s, pic); 943 versal_create_pmc_iou_slcr(s, pic); 944 versal_create_ospi(s, pic); 945 versal_create_crl(s, pic); 946 versal_create_cfu(s, pic); 947 versal_map_ddr(s); 948 versal_unimp(s); 949 950 /* Create the On Chip Memory (OCM). */ 951 memory_region_init_ram(&s->lpd.mr_ocm, OBJECT(s), "ocm", 952 MM_OCM_SIZE, &error_fatal); 953 954 memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0); 955 memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0); 956 memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0, 957 &s->lpd.rpu.mr_ps_alias, 0); 958 } 959 960 static void versal_init(Object *obj) 961 { 962 Versal *s = XLNX_VERSAL(obj); 963 964 memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX); 965 memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX); 966 memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX); 967 memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s), 968 "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX); 969 } 970 971 static Property versal_properties[] = { 972 DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION, 973 MemoryRegion *), 974 DEFINE_PROP_LINK("canbus0", Versal, lpd.iou.canbus[0], 975 TYPE_CAN_BUS, CanBusState *), 976 DEFINE_PROP_LINK("canbus1", Versal, lpd.iou.canbus[1], 977 TYPE_CAN_BUS, CanBusState *), 978 DEFINE_PROP_END_OF_LIST() 979 }; 980 981 static void versal_class_init(ObjectClass *klass, void *data) 982 { 983 DeviceClass *dc = DEVICE_CLASS(klass); 984 985 dc->realize = versal_realize; 986 device_class_set_props(dc, versal_properties); 987 /* No VMSD since we haven't got any top-level SoC state to save. */ 988 } 989 990 static const TypeInfo versal_info = { 991 .name = TYPE_XLNX_VERSAL, 992 .parent = TYPE_SYS_BUS_DEVICE, 993 .instance_size = sizeof(Versal), 994 .instance_init = versal_init, 995 .class_init = versal_class_init, 996 }; 997 998 static void versal_register_types(void) 999 { 1000 type_register_static(&versal_info); 1001 } 1002 1003 type_init(versal_register_types); 1004