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_xrams(Versal *s, qemu_irq *pic) 377 { 378 int nr_xrams = ARRAY_SIZE(s->lpd.xram.ctrl); 379 DeviceState *orgate; 380 int i; 381 382 /* XRAM IRQs get ORed into a single line. */ 383 object_initialize_child(OBJECT(s), "xram-irq-orgate", 384 &s->lpd.xram.irq_orgate, TYPE_OR_IRQ); 385 orgate = DEVICE(&s->lpd.xram.irq_orgate); 386 object_property_set_int(OBJECT(orgate), 387 "num-lines", nr_xrams, &error_fatal); 388 qdev_realize(orgate, NULL, &error_fatal); 389 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_XRAM_IRQ_0]); 390 391 for (i = 0; i < ARRAY_SIZE(s->lpd.xram.ctrl); i++) { 392 SysBusDevice *sbd; 393 MemoryRegion *mr; 394 395 object_initialize_child(OBJECT(s), "xram[*]", &s->lpd.xram.ctrl[i], 396 TYPE_XLNX_XRAM_CTRL); 397 sbd = SYS_BUS_DEVICE(&s->lpd.xram.ctrl[i]); 398 sysbus_realize(sbd, &error_fatal); 399 400 mr = sysbus_mmio_get_region(sbd, 0); 401 memory_region_add_subregion(&s->mr_ps, 402 MM_XRAMC + i * MM_XRAMC_SIZE, mr); 403 mr = sysbus_mmio_get_region(sbd, 1); 404 memory_region_add_subregion(&s->mr_ps, MM_XRAM + i * MiB, mr); 405 406 sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(orgate, i)); 407 } 408 } 409 410 static void versal_create_bbram(Versal *s, qemu_irq *pic) 411 { 412 SysBusDevice *sbd; 413 414 object_initialize_child_with_props(OBJECT(s), "bbram", &s->pmc.bbram, 415 sizeof(s->pmc.bbram), TYPE_XLNX_BBRAM, 416 &error_fatal, 417 "crc-zpads", "0", 418 NULL); 419 sbd = SYS_BUS_DEVICE(&s->pmc.bbram); 420 421 sysbus_realize(sbd, &error_fatal); 422 memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL, 423 sysbus_mmio_get_region(sbd, 0)); 424 sysbus_connect_irq(sbd, 0, 425 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1)); 426 } 427 428 static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base) 429 { 430 SysBusDevice *part = SYS_BUS_DEVICE(dev); 431 432 object_property_set_link(OBJECT(part), "efuse", 433 OBJECT(&s->pmc.efuse), &error_abort); 434 435 sysbus_realize(part, &error_abort); 436 memory_region_add_subregion(&s->mr_ps, base, 437 sysbus_mmio_get_region(part, 0)); 438 } 439 440 static void versal_create_efuse(Versal *s, qemu_irq *pic) 441 { 442 Object *bits = OBJECT(&s->pmc.efuse); 443 Object *ctrl = OBJECT(&s->pmc.efuse_ctrl); 444 Object *cache = OBJECT(&s->pmc.efuse_cache); 445 446 object_initialize_child(OBJECT(s), "efuse-ctrl", &s->pmc.efuse_ctrl, 447 TYPE_XLNX_VERSAL_EFUSE_CTRL); 448 449 object_initialize_child(OBJECT(s), "efuse-cache", &s->pmc.efuse_cache, 450 TYPE_XLNX_VERSAL_EFUSE_CACHE); 451 452 object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits, 453 sizeof(s->pmc.efuse), 454 TYPE_XLNX_EFUSE, &error_abort, 455 "efuse-nr", "3", 456 "efuse-size", "8192", 457 NULL); 458 459 qdev_realize(DEVICE(bits), NULL, &error_abort); 460 versal_realize_efuse_part(s, ctrl, MM_PMC_EFUSE_CTRL); 461 versal_realize_efuse_part(s, cache, MM_PMC_EFUSE_CACHE); 462 463 sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]); 464 } 465 466 static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic) 467 { 468 SysBusDevice *sbd; 469 470 object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr, 471 TYPE_XILINX_VERSAL_PMC_IOU_SLCR); 472 473 sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr); 474 sysbus_realize(sbd, &error_fatal); 475 476 memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR, 477 sysbus_mmio_get_region(sbd, 0)); 478 479 sysbus_connect_irq(sbd, 0, 480 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2)); 481 } 482 483 static void versal_create_ospi(Versal *s, qemu_irq *pic) 484 { 485 SysBusDevice *sbd; 486 MemoryRegion *mr_dac; 487 qemu_irq ospi_mux_sel; 488 DeviceState *orgate; 489 490 memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s), 491 "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE); 492 493 object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi, 494 TYPE_XILINX_VERSAL_OSPI); 495 496 mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1); 497 memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac); 498 499 /* Create the OSPI destination DMA */ 500 object_initialize_child(OBJECT(s), "versal-ospi-dma-dst", 501 &s->pmc.iou.ospi.dma_dst, 502 TYPE_XLNX_CSU_DMA); 503 504 object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst), 505 "dma", OBJECT(get_system_memory()), 506 &error_abort); 507 508 sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst); 509 sysbus_realize(sbd, &error_fatal); 510 511 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST, 512 sysbus_mmio_get_region(sbd, 0)); 513 514 /* Create the OSPI source DMA */ 515 object_initialize_child(OBJECT(s), "versal-ospi-dma-src", 516 &s->pmc.iou.ospi.dma_src, 517 TYPE_XLNX_CSU_DMA); 518 519 object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst", 520 false, &error_abort); 521 522 object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src), 523 "dma", OBJECT(mr_dac), &error_abort); 524 525 object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src), 526 "stream-connected-dma", 527 OBJECT(&s->pmc.iou.ospi.dma_dst), 528 &error_abort); 529 530 sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src); 531 sysbus_realize(sbd, &error_fatal); 532 533 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC, 534 sysbus_mmio_get_region(sbd, 0)); 535 536 /* Realize the OSPI */ 537 object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src", 538 OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort); 539 540 sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi); 541 sysbus_realize(sbd, &error_fatal); 542 543 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI, 544 sysbus_mmio_get_region(sbd, 0)); 545 546 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC, 547 &s->pmc.iou.ospi.linear_mr); 548 549 /* ospi_mux_sel */ 550 ospi_mux_sel = qdev_get_gpio_in_named(DEVICE(&s->pmc.iou.ospi.ospi), 551 "ospi-mux-sel", 0); 552 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "ospi-mux-sel", 0, 553 ospi_mux_sel); 554 555 /* OSPI irq */ 556 object_initialize_child(OBJECT(s), "ospi-irq-orgate", 557 &s->pmc.iou.ospi.irq_orgate, TYPE_OR_IRQ); 558 object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq_orgate), 559 "num-lines", NUM_OSPI_IRQ_LINES, &error_fatal); 560 561 orgate = DEVICE(&s->pmc.iou.ospi.irq_orgate); 562 qdev_realize(orgate, NULL, &error_fatal); 563 564 sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0, 565 qdev_get_gpio_in(orgate, 0)); 566 sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0, 567 qdev_get_gpio_in(orgate, 1)); 568 sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0, 569 qdev_get_gpio_in(orgate, 2)); 570 571 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]); 572 } 573 574 static void versal_create_cfu(Versal *s, qemu_irq *pic) 575 { 576 SysBusDevice *sbd; 577 DeviceState *dev; 578 int i; 579 const struct { 580 uint64_t reg_base; 581 uint64_t fdri_base; 582 } cframe_addr[] = { 583 { MM_PMC_CFRAME0_REG, MM_PMC_CFRAME0_FDRI }, 584 { MM_PMC_CFRAME1_REG, MM_PMC_CFRAME1_FDRI }, 585 { MM_PMC_CFRAME2_REG, MM_PMC_CFRAME2_FDRI }, 586 { MM_PMC_CFRAME3_REG, MM_PMC_CFRAME3_FDRI }, 587 { MM_PMC_CFRAME4_REG, MM_PMC_CFRAME4_FDRI }, 588 { MM_PMC_CFRAME5_REG, MM_PMC_CFRAME5_FDRI }, 589 { MM_PMC_CFRAME6_REG, MM_PMC_CFRAME6_FDRI }, 590 { MM_PMC_CFRAME7_REG, MM_PMC_CFRAME7_FDRI }, 591 { MM_PMC_CFRAME8_REG, MM_PMC_CFRAME8_FDRI }, 592 { MM_PMC_CFRAME9_REG, MM_PMC_CFRAME9_FDRI }, 593 { MM_PMC_CFRAME10_REG, MM_PMC_CFRAME10_FDRI }, 594 { MM_PMC_CFRAME11_REG, MM_PMC_CFRAME11_FDRI }, 595 { MM_PMC_CFRAME12_REG, MM_PMC_CFRAME12_FDRI }, 596 { MM_PMC_CFRAME13_REG, MM_PMC_CFRAME13_FDRI }, 597 { MM_PMC_CFRAME14_REG, MM_PMC_CFRAME14_FDRI }, 598 }; 599 const struct { 600 uint32_t blktype0_frames; 601 uint32_t blktype1_frames; 602 uint32_t blktype2_frames; 603 uint32_t blktype3_frames; 604 uint32_t blktype4_frames; 605 uint32_t blktype5_frames; 606 uint32_t blktype6_frames; 607 } cframe_cfg[] = { 608 [0] = { 34111, 3528, 12800, 11, 5, 1, 1 }, 609 [1] = { 38498, 3841, 15361, 13, 7, 3, 1 }, 610 [2] = { 38498, 3841, 15361, 13, 7, 3, 1 }, 611 [3] = { 38498, 3841, 15361, 13, 7, 3, 1 }, 612 }; 613 614 /* CFU FDRO */ 615 object_initialize_child(OBJECT(s), "cfu-fdro", &s->pmc.cfu_fdro, 616 TYPE_XLNX_VERSAL_CFU_FDRO); 617 sbd = SYS_BUS_DEVICE(&s->pmc.cfu_fdro); 618 619 sysbus_realize(sbd, &error_fatal); 620 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_FDRO, 621 sysbus_mmio_get_region(sbd, 0)); 622 623 /* CFRAME REG */ 624 for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) { 625 g_autofree char *name = g_strdup_printf("cframe%d", i); 626 627 object_initialize_child(OBJECT(s), name, &s->pmc.cframe[i], 628 TYPE_XLNX_VERSAL_CFRAME_REG); 629 630 sbd = SYS_BUS_DEVICE(&s->pmc.cframe[i]); 631 dev = DEVICE(&s->pmc.cframe[i]); 632 633 if (i < ARRAY_SIZE(cframe_cfg)) { 634 object_property_set_int(OBJECT(dev), "blktype0-frames", 635 cframe_cfg[i].blktype0_frames, 636 &error_abort); 637 object_property_set_int(OBJECT(dev), "blktype1-frames", 638 cframe_cfg[i].blktype1_frames, 639 &error_abort); 640 object_property_set_int(OBJECT(dev), "blktype2-frames", 641 cframe_cfg[i].blktype2_frames, 642 &error_abort); 643 object_property_set_int(OBJECT(dev), "blktype3-frames", 644 cframe_cfg[i].blktype3_frames, 645 &error_abort); 646 object_property_set_int(OBJECT(dev), "blktype4-frames", 647 cframe_cfg[i].blktype4_frames, 648 &error_abort); 649 object_property_set_int(OBJECT(dev), "blktype5-frames", 650 cframe_cfg[i].blktype5_frames, 651 &error_abort); 652 object_property_set_int(OBJECT(dev), "blktype6-frames", 653 cframe_cfg[i].blktype6_frames, 654 &error_abort); 655 } 656 object_property_set_link(OBJECT(dev), "cfu-fdro", 657 OBJECT(&s->pmc.cfu_fdro), &error_fatal); 658 659 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 660 661 memory_region_add_subregion(&s->mr_ps, cframe_addr[i].reg_base, 662 sysbus_mmio_get_region(sbd, 0)); 663 memory_region_add_subregion(&s->mr_ps, cframe_addr[i].fdri_base, 664 sysbus_mmio_get_region(sbd, 1)); 665 sysbus_connect_irq(sbd, 0, 666 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 667 3 + i)); 668 } 669 670 /* CFRAME BCAST */ 671 object_initialize_child(OBJECT(s), "cframe_bcast", &s->pmc.cframe_bcast, 672 TYPE_XLNX_VERSAL_CFRAME_BCAST_REG); 673 674 sbd = SYS_BUS_DEVICE(&s->pmc.cframe_bcast); 675 dev = DEVICE(&s->pmc.cframe_bcast); 676 677 for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) { 678 g_autofree char *propname = g_strdup_printf("cframe%d", i); 679 object_property_set_link(OBJECT(dev), propname, 680 OBJECT(&s->pmc.cframe[i]), &error_fatal); 681 } 682 683 sysbus_realize(sbd, &error_fatal); 684 685 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_REG, 686 sysbus_mmio_get_region(sbd, 0)); 687 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_FDRI, 688 sysbus_mmio_get_region(sbd, 1)); 689 690 /* CFU APB */ 691 object_initialize_child(OBJECT(s), "cfu-apb", &s->pmc.cfu_apb, 692 TYPE_XLNX_VERSAL_CFU_APB); 693 sbd = SYS_BUS_DEVICE(&s->pmc.cfu_apb); 694 dev = DEVICE(&s->pmc.cfu_apb); 695 696 for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) { 697 g_autofree char *propname = g_strdup_printf("cframe%d", i); 698 object_property_set_link(OBJECT(dev), propname, 699 OBJECT(&s->pmc.cframe[i]), &error_fatal); 700 } 701 702 sysbus_realize(sbd, &error_fatal); 703 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_APB, 704 sysbus_mmio_get_region(sbd, 0)); 705 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM, 706 sysbus_mmio_get_region(sbd, 1)); 707 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM_2, 708 sysbus_mmio_get_region(sbd, 2)); 709 sysbus_connect_irq(sbd, 0, pic[VERSAL_CFU_IRQ_0]); 710 711 /* CFU SFR */ 712 object_initialize_child(OBJECT(s), "cfu-sfr", &s->pmc.cfu_sfr, 713 TYPE_XLNX_VERSAL_CFU_SFR); 714 715 sbd = SYS_BUS_DEVICE(&s->pmc.cfu_sfr); 716 717 object_property_set_link(OBJECT(&s->pmc.cfu_sfr), 718 "cfu", OBJECT(&s->pmc.cfu_apb), &error_abort); 719 720 sysbus_realize(sbd, &error_fatal); 721 memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_SFR, 722 sysbus_mmio_get_region(sbd, 0)); 723 } 724 725 static void versal_create_crl(Versal *s, qemu_irq *pic) 726 { 727 SysBusDevice *sbd; 728 int i; 729 730 object_initialize_child(OBJECT(s), "crl", &s->lpd.crl, 731 TYPE_XLNX_VERSAL_CRL); 732 sbd = SYS_BUS_DEVICE(&s->lpd.crl); 733 734 for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) { 735 g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i); 736 737 object_property_set_link(OBJECT(&s->lpd.crl), 738 name, OBJECT(&s->lpd.rpu.cpu[i]), 739 &error_abort); 740 } 741 742 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) { 743 g_autofree gchar *name = g_strdup_printf("gem[%d]", i); 744 745 object_property_set_link(OBJECT(&s->lpd.crl), 746 name, OBJECT(&s->lpd.iou.gem[i]), 747 &error_abort); 748 } 749 750 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) { 751 g_autofree gchar *name = g_strdup_printf("adma[%d]", i); 752 753 object_property_set_link(OBJECT(&s->lpd.crl), 754 name, OBJECT(&s->lpd.iou.adma[i]), 755 &error_abort); 756 } 757 758 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) { 759 g_autofree gchar *name = g_strdup_printf("uart[%d]", i); 760 761 object_property_set_link(OBJECT(&s->lpd.crl), 762 name, OBJECT(&s->lpd.iou.uart[i]), 763 &error_abort); 764 } 765 766 object_property_set_link(OBJECT(&s->lpd.crl), 767 "usb", OBJECT(&s->lpd.iou.usb), 768 &error_abort); 769 770 sysbus_realize(sbd, &error_fatal); 771 memory_region_add_subregion(&s->mr_ps, MM_CRL, 772 sysbus_mmio_get_region(sbd, 0)); 773 sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]); 774 } 775 776 /* This takes the board allocated linear DDR memory and creates aliases 777 * for each split DDR range/aperture on the Versal address map. 778 */ 779 static void versal_map_ddr(Versal *s) 780 { 781 uint64_t size = memory_region_size(s->cfg.mr_ddr); 782 /* Describes the various split DDR access regions. */ 783 static const struct { 784 uint64_t base; 785 uint64_t size; 786 } addr_ranges[] = { 787 { MM_TOP_DDR, MM_TOP_DDR_SIZE }, 788 { MM_TOP_DDR_2, MM_TOP_DDR_2_SIZE }, 789 { MM_TOP_DDR_3, MM_TOP_DDR_3_SIZE }, 790 { MM_TOP_DDR_4, MM_TOP_DDR_4_SIZE } 791 }; 792 uint64_t offset = 0; 793 int i; 794 795 assert(ARRAY_SIZE(addr_ranges) == ARRAY_SIZE(s->noc.mr_ddr_ranges)); 796 for (i = 0; i < ARRAY_SIZE(addr_ranges) && size; i++) { 797 char *name; 798 uint64_t mapsize; 799 800 mapsize = size < addr_ranges[i].size ? size : addr_ranges[i].size; 801 name = g_strdup_printf("noc-ddr-range%d", i); 802 /* Create the MR alias. */ 803 memory_region_init_alias(&s->noc.mr_ddr_ranges[i], OBJECT(s), 804 name, s->cfg.mr_ddr, 805 offset, mapsize); 806 807 /* Map it onto the NoC MR. */ 808 memory_region_add_subregion(&s->mr_ps, addr_ranges[i].base, 809 &s->noc.mr_ddr_ranges[i]); 810 offset += mapsize; 811 size -= mapsize; 812 g_free(name); 813 } 814 } 815 816 static void versal_unimp_area(Versal *s, const char *name, 817 MemoryRegion *mr, 818 hwaddr base, hwaddr size) 819 { 820 DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE); 821 MemoryRegion *mr_dev; 822 823 qdev_prop_set_string(dev, "name", name); 824 qdev_prop_set_uint64(dev, "size", size); 825 object_property_add_child(OBJECT(s), name, OBJECT(dev)); 826 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 827 828 mr_dev = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 829 memory_region_add_subregion(mr, base, mr_dev); 830 } 831 832 static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level) 833 { 834 qemu_log_mask(LOG_UNIMP, 835 "Selecting between enabling SD mode or eMMC mode on " 836 "controller %d is not yet implemented\n", n); 837 } 838 839 static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level) 840 { 841 qemu_log_mask(LOG_UNIMP, 842 "Selecting between enabling the QSPI or OSPI linear address " 843 "region is not yet implemented\n"); 844 } 845 846 static void versal_unimp_irq_parity_imr(void *opaque, int n, int level) 847 { 848 qemu_log_mask(LOG_UNIMP, 849 "PMC SLCR parity interrupt behaviour " 850 "is not yet implemented\n"); 851 } 852 853 static void versal_unimp(Versal *s) 854 { 855 qemu_irq gpio_in; 856 857 versal_unimp_area(s, "psm", &s->mr_ps, 858 MM_PSM_START, MM_PSM_END - MM_PSM_START); 859 versal_unimp_area(s, "crf", &s->mr_ps, 860 MM_FPD_CRF, MM_FPD_CRF_SIZE); 861 versal_unimp_area(s, "apu", &s->mr_ps, 862 MM_FPD_FPD_APU, MM_FPD_FPD_APU_SIZE); 863 versal_unimp_area(s, "crp", &s->mr_ps, 864 MM_PMC_CRP, MM_PMC_CRP_SIZE); 865 versal_unimp_area(s, "iou-scntr", &s->mr_ps, 866 MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE); 867 versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps, 868 MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE); 869 870 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel, 871 "sd-emmc-sel-dummy", 2); 872 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel, 873 "qspi-ospi-mux-sel-dummy", 1); 874 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr, 875 "irq-parity-imr-dummy", 1); 876 877 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0); 878 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 0, 879 gpio_in); 880 881 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1); 882 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 1, 883 gpio_in); 884 885 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 0); 886 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), 887 "qspi-ospi-mux-sel", 0, 888 gpio_in); 889 890 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0); 891 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), 892 SYSBUS_DEVICE_GPIO_IRQ, 0, 893 gpio_in); 894 } 895 896 static void versal_realize(DeviceState *dev, Error **errp) 897 { 898 Versal *s = XLNX_VERSAL(dev); 899 qemu_irq pic[XLNX_VERSAL_NR_IRQS]; 900 901 versal_create_apu_cpus(s); 902 versal_create_apu_gic(s, pic); 903 versal_create_rpu_cpus(s); 904 versal_create_uarts(s, pic); 905 versal_create_canfds(s, pic); 906 versal_create_usbs(s, pic); 907 versal_create_gems(s, pic); 908 versal_create_admas(s, pic); 909 versal_create_sds(s, pic); 910 versal_create_pmc_apb_irq_orgate(s, pic); 911 versal_create_rtc(s, pic); 912 versal_create_xrams(s, pic); 913 versal_create_bbram(s, pic); 914 versal_create_efuse(s, pic); 915 versal_create_pmc_iou_slcr(s, pic); 916 versal_create_ospi(s, pic); 917 versal_create_crl(s, pic); 918 versal_create_cfu(s, pic); 919 versal_map_ddr(s); 920 versal_unimp(s); 921 922 /* Create the On Chip Memory (OCM). */ 923 memory_region_init_ram(&s->lpd.mr_ocm, OBJECT(s), "ocm", 924 MM_OCM_SIZE, &error_fatal); 925 926 memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0); 927 memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0); 928 memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0, 929 &s->lpd.rpu.mr_ps_alias, 0); 930 } 931 932 static void versal_init(Object *obj) 933 { 934 Versal *s = XLNX_VERSAL(obj); 935 936 memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX); 937 memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX); 938 memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX); 939 memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s), 940 "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX); 941 } 942 943 static Property versal_properties[] = { 944 DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION, 945 MemoryRegion *), 946 DEFINE_PROP_LINK("canbus0", Versal, lpd.iou.canbus[0], 947 TYPE_CAN_BUS, CanBusState *), 948 DEFINE_PROP_LINK("canbus1", Versal, lpd.iou.canbus[1], 949 TYPE_CAN_BUS, CanBusState *), 950 DEFINE_PROP_END_OF_LIST() 951 }; 952 953 static void versal_class_init(ObjectClass *klass, void *data) 954 { 955 DeviceClass *dc = DEVICE_CLASS(klass); 956 957 dc->realize = versal_realize; 958 device_class_set_props(dc, versal_properties); 959 /* No VMSD since we haven't got any top-level SoC state to save. */ 960 } 961 962 static const TypeInfo versal_info = { 963 .name = TYPE_XLNX_VERSAL, 964 .parent = TYPE_SYS_BUS_DEVICE, 965 .instance_size = sizeof(Versal), 966 .instance_init = versal_init, 967 .class_init = versal_class_init, 968 }; 969 970 static void versal_register_types(void) 971 { 972 type_register_static(&versal_info); 973 } 974 975 type_init(versal_register_types); 976