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