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