1 /* 2 * AMD/Xilinx Versal family SoC model. 3 * 4 * Copyright (c) 2018 Xilinx Inc. 5 * Copyright (c) 2025 Advanced Micro Devices, Inc. 6 * Written by Edgar E. Iglesias 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 or 10 * (at your option) any later version. 11 */ 12 13 #include "qemu/osdep.h" 14 #include "qemu/units.h" 15 #include "qapi/error.h" 16 #include "qobject/qlist.h" 17 #include "qemu/module.h" 18 #include "hw/sysbus.h" 19 #include "net/net.h" 20 #include "system/system.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 #include "system/device_tree.h" 27 #include "hw/arm/fdt.h" 28 #include "hw/char/pl011.h" 29 #include "hw/net/xlnx-versal-canfd.h" 30 #include "hw/sd/sdhci.h" 31 #include "hw/net/cadence_gem.h" 32 #include "hw/dma/xlnx-zdma.h" 33 #include "hw/misc/xlnx-versal-xramc.h" 34 #include "hw/usb/xlnx-usb-subsystem.h" 35 #include "hw/nvram/xlnx-versal-efuse.h" 36 #include "hw/ssi/xlnx-versal-ospi.h" 37 #include "hw/misc/xlnx-versal-pmc-iou-slcr.h" 38 #include "hw/nvram/xlnx-bbram.h" 39 #include "hw/misc/xlnx-versal-trng.h" 40 #include "hw/rtc/xlnx-zynqmp-rtc.h" 41 #include "hw/misc/xlnx-versal-cfu.h" 42 #include "hw/misc/xlnx-versal-cframe-reg.h" 43 #include "hw/or-irq.h" 44 #include "hw/misc/xlnx-versal-crl.h" 45 #include "hw/intc/arm_gicv3_common.h" 46 #include "hw/intc/arm_gicv3_its_common.h" 47 #include "hw/intc/arm_gic.h" 48 #include "hw/core/split-irq.h" 49 #include "target/arm/cpu.h" 50 #include "hw/cpu/cluster.h" 51 #include "hw/arm/bsa.h" 52 53 /* 54 * IRQ descriptor to catch the following cases: 55 * - An IRQ can either connect to the GICs, to the PPU1 intc, or the the EAM 56 * - Multiple devices can connect to the same IRQ. They are OR'ed together. 57 */ 58 FIELD(VERSAL_IRQ, IRQ, 0, 16) 59 FIELD(VERSAL_IRQ, TARGET, 16, 2) 60 FIELD(VERSAL_IRQ, ORED, 18, 1) 61 FIELD(VERSAL_IRQ, OR_IDX, 19, 4) /* input index on the IRQ OR gate */ 62 63 typedef enum VersalIrqTarget { 64 IRQ_TARGET_GIC, 65 IRQ_TARGET_PPU1, 66 IRQ_TARGET_EAM, 67 } VersalIrqTarget; 68 69 #define PPU1_IRQ(irq) ((IRQ_TARGET_PPU1 << R_VERSAL_IRQ_TARGET_SHIFT) | (irq)) 70 #define EAM_IRQ(irq) ((IRQ_TARGET_EAM << R_VERSAL_IRQ_TARGET_SHIFT) | (irq)) 71 #define OR_IRQ(irq, or_idx) \ 72 (R_VERSAL_IRQ_ORED_MASK | ((or_idx) << R_VERSAL_IRQ_OR_IDX_SHIFT) | (irq)) 73 #define PPU1_OR_IRQ(irq, or_idx) \ 74 ((IRQ_TARGET_PPU1 << R_VERSAL_IRQ_TARGET_SHIFT) | OR_IRQ(irq, or_idx)) 75 76 typedef struct VersalSimplePeriphMap { 77 uint64_t addr; 78 int irq; 79 } VersalSimplePeriphMap; 80 81 typedef struct VersalMemMap { 82 uint64_t addr; 83 uint64_t size; 84 } VersalMemMap; 85 86 typedef struct VersalGicMap { 87 int version; 88 uint64_t dist; 89 uint64_t redist; 90 uint64_t cpu_iface; 91 uint64_t its; 92 size_t num_irq; 93 bool has_its; 94 } VersalGicMap; 95 96 enum StartPoweredOffMode { 97 SPO_SECONDARIES, 98 SPO_ALL, 99 }; 100 101 typedef struct VersalCpuClusterMap { 102 VersalGicMap gic; 103 /* 104 * true: one GIC per cluster. 105 * false: one GIC for all CPUs 106 */ 107 bool per_cluster_gic; 108 109 const char *name; 110 const char *cpu_model; 111 size_t num_core; 112 size_t num_cluster; 113 uint32_t qemu_cluster_id; 114 bool dtb_expose; 115 116 struct { 117 uint64_t base; 118 uint64_t core_shift; 119 uint64_t cluster_shift; 120 } mp_affinity; 121 122 enum StartPoweredOffMode start_powered_off; 123 } VersalCpuClusterMap; 124 125 typedef struct VersalMap { 126 VersalMemMap ocm; 127 128 struct VersalDDRMap { 129 VersalMemMap chan[4]; 130 size_t num_chan; 131 } ddr; 132 133 VersalCpuClusterMap apu; 134 VersalCpuClusterMap rpu; 135 136 VersalSimplePeriphMap uart[2]; 137 size_t num_uart; 138 139 VersalSimplePeriphMap canfd[4]; 140 size_t num_canfd; 141 142 VersalSimplePeriphMap sdhci[2]; 143 size_t num_sdhci; 144 145 struct VersalGemMap { 146 VersalSimplePeriphMap map; 147 size_t num_prio_queue; 148 const char *phy_mode; 149 const uint32_t speed; 150 } gem[3]; 151 size_t num_gem; 152 153 struct VersalZDMAMap { 154 const char *name; 155 VersalSimplePeriphMap map; 156 size_t num_chan; 157 uint64_t chan_stride; 158 int irq_stride; 159 } zdma[2]; 160 size_t num_zdma; 161 162 struct VersalXramMap { 163 uint64_t mem; 164 uint64_t mem_stride; 165 uint64_t ctrl; 166 uint64_t ctrl_stride; 167 int irq; 168 size_t num; 169 } xram; 170 171 struct VersalUsbMap { 172 uint64_t xhci; 173 uint64_t ctrl; 174 int irq; 175 } usb[2]; 176 size_t num_usb; 177 178 struct VersalEfuseMap { 179 uint64_t ctrl; 180 uint64_t cache; 181 int irq; 182 } efuse; 183 184 struct VersalOspiMap { 185 uint64_t ctrl; 186 uint64_t dac; 187 uint64_t dac_sz; 188 uint64_t dma_src; 189 uint64_t dma_dst; 190 int irq; 191 } ospi; 192 193 VersalSimplePeriphMap pmc_iou_slcr; 194 VersalSimplePeriphMap bbram; 195 VersalSimplePeriphMap trng; 196 197 struct VersalRtcMap { 198 VersalSimplePeriphMap map; 199 int alarm_irq; 200 int second_irq; 201 } rtc; 202 203 struct VersalCfuMap { 204 uint64_t cframe_base; 205 uint64_t cframe_stride; 206 uint64_t cfu_fdro; 207 uint64_t cframe_bcast_reg; 208 uint64_t cframe_bcast_fdri; 209 uint64_t cfu_apb; 210 uint64_t cfu_stream; 211 uint64_t cfu_stream_2; 212 uint64_t cfu_sfr; 213 int cfu_apb_irq; 214 int cframe_irq; 215 size_t num_cframe; 216 struct VersalCfuCframeCfg { 217 uint32_t blktype_frames[7]; 218 } cframe_cfg[15]; 219 } cfu; 220 221 VersalSimplePeriphMap crl; 222 223 /* reserved MMIO/IRQ space that can safely be used for virtio devices */ 224 struct VersalReserved { 225 uint64_t mmio_start; 226 int irq_start; 227 int irq_num; 228 } reserved; 229 } VersalMap; 230 231 static const VersalMap VERSAL_MAP = { 232 .ocm = { 233 .addr = 0xfffc0000, 234 .size = 0x40000, 235 }, 236 237 .ddr = { 238 .chan[0] = { .addr = 0x0, .size = 2 * GiB }, 239 .chan[1] = { .addr = 0x800000000ull, .size = 32 * GiB }, 240 .chan[2] = { .addr = 0xc00000000ull, .size = 256 * GiB }, 241 .chan[3] = { .addr = 0x10000000000ull, .size = 734 * GiB }, 242 .num_chan = 4, 243 }, 244 245 .apu = { 246 .name = "apu", 247 .cpu_model = ARM_CPU_TYPE_NAME("cortex-a72"), 248 .num_cluster = 1, 249 .num_core = 2, 250 .qemu_cluster_id = 0, 251 .mp_affinity = { 252 .core_shift = ARM_AFF0_SHIFT, 253 .cluster_shift = ARM_AFF1_SHIFT, 254 }, 255 .start_powered_off = SPO_SECONDARIES, 256 .dtb_expose = true, 257 .gic = { 258 .version = 3, 259 .dist = 0xf9000000, 260 .redist = 0xf9080000, 261 .num_irq = 192, 262 .has_its = true, 263 .its = 0xf9020000, 264 }, 265 }, 266 267 .rpu = { 268 .name = "rpu", 269 .cpu_model = ARM_CPU_TYPE_NAME("cortex-r5f"), 270 .num_cluster = 1, 271 .num_core = 2, 272 .qemu_cluster_id = 1, 273 .mp_affinity = { 274 .base = 0x100, 275 .core_shift = ARM_AFF0_SHIFT, 276 .cluster_shift = ARM_AFF1_SHIFT, 277 }, 278 .start_powered_off = SPO_ALL, 279 .dtb_expose = false, 280 .gic = { 281 .version = 2, 282 .dist = 0xf9000000, 283 .cpu_iface = 0xf9001000, 284 .num_irq = 192, 285 }, 286 }, 287 288 .uart[0] = { 0xff000000, 18 }, 289 .uart[1] = { 0xff010000, 19 }, 290 .num_uart = 2, 291 292 .canfd[0] = { 0xff060000, 20 }, 293 .canfd[1] = { 0xff070000, 21 }, 294 .num_canfd = 2, 295 296 .sdhci[0] = { 0xf1040000, 126 }, 297 .sdhci[1] = { 0xf1050000, 128 }, 298 .num_sdhci = 2, 299 300 .gem[0] = { { 0xff0c0000, 56 }, 2, "rgmii-id", 1000 }, 301 .gem[1] = { { 0xff0d0000, 58 }, 2, "rgmii-id", 1000 }, 302 .num_gem = 2, 303 304 .zdma[0] = { "adma", { 0xffa80000, 60 }, 8, 0x10000, 1 }, 305 .num_zdma = 1, 306 307 .xram = { 308 .num = 4, 309 .mem = 0xfe800000, .mem_stride = 1 * MiB, 310 .ctrl = 0xff8e0000, .ctrl_stride = 0x10000, 311 .irq = 79, 312 }, 313 314 .usb[0] = { .xhci = 0xfe200000, .ctrl = 0xff9d0000, .irq = 22 }, 315 .num_usb = 1, 316 317 .efuse = { .ctrl = 0xf1240000, .cache = 0xf1250000, .irq = 139 }, 318 319 .ospi = { 320 .ctrl = 0xf1010000, 321 .dac = 0xc0000000, .dac_sz = 0x20000000, 322 .dma_src = 0xf1011000, .dma_dst = 0xf1011800, 323 .irq = 124, 324 }, 325 326 .pmc_iou_slcr = { 0xf1060000, OR_IRQ(121, 0) }, 327 .bbram = { 0xf11f0000, OR_IRQ(121, 1) }, 328 .trng = { 0xf1230000, 141 }, 329 .rtc = { 330 { 0xf12a0000, OR_IRQ(121, 2) }, 331 .alarm_irq = 142, .second_irq = 143 332 }, 333 334 .cfu = { 335 .cframe_base = 0xf12d0000, .cframe_stride = 0x1000, 336 .cframe_bcast_reg = 0xf12ee000, .cframe_bcast_fdri = 0xf12ef000, 337 .cfu_apb = 0xf12b0000, .cfu_sfr = 0xf12c1000, 338 .cfu_stream = 0xf12c0000, .cfu_stream_2 = 0xf1f80000, 339 .cfu_fdro = 0xf12c2000, 340 .cfu_apb_irq = 120, .cframe_irq = OR_IRQ(121, 3), 341 .num_cframe = 15, 342 .cframe_cfg = { 343 { { 34111, 3528, 12800, 11, 5, 1, 1 } }, 344 { { 38498, 3841, 15361, 13, 7, 3, 1 } }, 345 { { 38498, 3841, 15361, 13, 7, 3, 1 } }, 346 { { 38498, 3841, 15361, 13, 7, 3, 1 } }, 347 }, 348 }, 349 350 .crl = { 0xff5e0000, 10 }, 351 352 .reserved = { 0xa0000000, 111, 8 }, 353 }; 354 355 static const VersalMap VERSAL2_MAP = { 356 .ocm = { 357 .addr = 0xbbe00000, 358 .size = 2 * MiB, 359 }, 360 361 .ddr = { 362 .chan[0] = { .addr = 0x0, .size = 2046 * MiB }, 363 .chan[1] = { .addr = 0x800000000ull, .size = 32 * GiB }, 364 .chan[2] = { .addr = 0xc00000000ull, .size = 256 * GiB }, 365 .chan[3] = { .addr = 0x10000000000ull, .size = 734 * GiB }, 366 .num_chan = 4, 367 }, 368 369 .apu = { 370 .name = "apu", 371 .cpu_model = ARM_CPU_TYPE_NAME("cortex-a78ae"), 372 .num_cluster = 4, 373 .num_core = 2, 374 .qemu_cluster_id = 0, 375 .mp_affinity = { 376 .base = 0x0, /* TODO: the MT bit should be set */ 377 .core_shift = ARM_AFF1_SHIFT, 378 .cluster_shift = ARM_AFF2_SHIFT, 379 }, 380 .start_powered_off = SPO_SECONDARIES, 381 .dtb_expose = true, 382 .gic = { 383 .version = 3, 384 .dist = 0xe2000000, 385 .redist = 0xe2060000, 386 .num_irq = 544, 387 .has_its = true, 388 .its = 0xe2040000, 389 }, 390 }, 391 392 .rpu = { 393 .name = "rpu", 394 .cpu_model = ARM_CPU_TYPE_NAME("cortex-r52"), 395 .num_cluster = 5, 396 .num_core = 2, 397 .qemu_cluster_id = 1, 398 .mp_affinity = { 399 .core_shift = ARM_AFF0_SHIFT, 400 .cluster_shift = ARM_AFF1_SHIFT, 401 }, 402 .start_powered_off = SPO_ALL, 403 .dtb_expose = false, 404 .per_cluster_gic = true, 405 .gic = { 406 .version = 3, 407 .dist = 0x0, 408 .redist = 0x100000, 409 .num_irq = 288, 410 }, 411 }, 412 413 .uart[0] = { 0xf1920000, 25 }, 414 .uart[1] = { 0xf1930000, 26 }, 415 .num_uart = 2, 416 417 .canfd[0] = { 0xf19e0000, 27 }, 418 .canfd[1] = { 0xf19f0000, 28 }, 419 .canfd[2] = { 0xf1a00000, 95 }, 420 .canfd[3] = { 0xf1a10000, 96 }, 421 .num_canfd = 4, 422 423 .gem[0] = { { 0xf1a60000, 39 }, 2, "rgmii-id", 1000 }, 424 .gem[1] = { { 0xf1a70000, 41 }, 2, "rgmii-id", 1000 }, 425 .gem[2] = { { 0xed920000, 164 }, 4, "usxgmii", 10000 }, /* MMI 10Gb GEM */ 426 .num_gem = 3, 427 428 .zdma[0] = { "adma", { 0xebd00000, 72 }, 8, 0x10000, 1 }, 429 .zdma[1] = { "sdma", { 0xebd80000, 112 }, 8, 0x10000, 1 }, 430 .num_zdma = 2, 431 432 .usb[0] = { .xhci = 0xf1b00000, .ctrl = 0xf1ee0000, .irq = 29 }, 433 .usb[1] = { .xhci = 0xf1c00000, .ctrl = 0xf1ef0000, .irq = 34 }, 434 .num_usb = 2, 435 436 .efuse = { .ctrl = 0xf1240000, .cache = 0xf1250000, .irq = 230 }, 437 438 .ospi = { 439 .ctrl = 0xf1010000, 440 .dac = 0xc0000000, .dac_sz = 0x20000000, 441 .dma_src = 0xf1011000, .dma_dst = 0xf1011800, 442 .irq = 216, 443 }, 444 445 .sdhci[0] = { 0xf1040000, 218 }, 446 .sdhci[1] = { 0xf1050000, 220 }, /* eMMC */ 447 .num_sdhci = 2, 448 449 .pmc_iou_slcr = { 0xf1060000, 222 }, 450 .bbram = { 0xf11f0000, PPU1_OR_IRQ(18, 0) }, 451 .crl = { 0xeb5e0000 }, 452 .trng = { 0xf1230000, 233 }, 453 .rtc = { 454 { 0xf12a0000, PPU1_OR_IRQ(18, 1) }, 455 .alarm_irq = 200, .second_irq = 201 456 }, 457 458 .cfu = { 459 .cframe_base = 0xf12d0000, .cframe_stride = 0x1000, 460 .cframe_bcast_reg = 0xf12ee000, .cframe_bcast_fdri = 0xf12ef000, 461 .cfu_apb = 0xf12b0000, .cfu_sfr = 0xf12c1000, 462 .cfu_stream = 0xf12c0000, .cfu_stream_2 = 0xf1f80000, 463 .cfu_fdro = 0xf12c2000, 464 .cfu_apb_irq = 235, .cframe_irq = EAM_IRQ(7), 465 }, 466 467 .reserved = { 0xf5e00000, 270, 8 }, 468 }; 469 470 static const VersalMap *VERSION_TO_MAP[] = { 471 [VERSAL_VER_VERSAL] = &VERSAL_MAP, 472 [VERSAL_VER_VERSAL2] = &VERSAL2_MAP, 473 }; 474 475 static inline VersalVersion versal_get_version(Versal *s) 476 { 477 return XLNX_VERSAL_BASE_GET_CLASS(s)->version; 478 } 479 480 static inline const VersalMap *versal_get_map(Versal *s) 481 { 482 return VERSION_TO_MAP[versal_get_version(s)]; 483 } 484 485 static inline Object *versal_get_child(Versal *s, const char *child) 486 { 487 return object_resolve_path_at(OBJECT(s), child); 488 } 489 490 static inline Object *versal_get_child_idx(Versal *s, const char *child, 491 size_t idx) 492 { 493 g_autofree char *n = g_strdup_printf("%s[%zu]", child, idx); 494 495 return versal_get_child(s, n); 496 } 497 498 /* 499 * The SoC embeds multiple GICs. They all receives the same IRQ lines at the 500 * same index. This function creates a TYPE_SPLIT_IRQ device to fan out the 501 * given IRQ input to all the GICs. 502 * 503 * The TYPE_SPLIT_IRQ devices lie in the /soc/irq-splits QOM container 504 */ 505 static qemu_irq versal_get_gic_irq(Versal *s, int irq_idx) 506 { 507 DeviceState *split; 508 Object *container = versal_get_child(s, "irq-splits"); 509 int idx = FIELD_EX32(irq_idx, VERSAL_IRQ, IRQ); 510 g_autofree char *name = g_strdup_printf("irq[%d]", idx); 511 512 split = DEVICE(object_resolve_path_at(container, name)); 513 514 if (split == NULL) { 515 size_t i; 516 517 split = qdev_new(TYPE_SPLIT_IRQ); 518 qdev_prop_set_uint16(split, "num-lines", s->intc->len); 519 object_property_add_child(container, name, OBJECT(split)); 520 qdev_realize_and_unref(split, NULL, &error_abort); 521 522 for (i = 0; i < s->intc->len; i++) { 523 DeviceState *gic; 524 525 gic = g_array_index(s->intc, DeviceState *, i); 526 qdev_connect_gpio_out(split, i, qdev_get_gpio_in(gic, idx)); 527 } 528 } else { 529 g_assert(FIELD_EX32(irq_idx, VERSAL_IRQ, ORED)); 530 } 531 532 return qdev_get_gpio_in(split, 0); 533 } 534 535 /* 536 * When the R_VERSAL_IRQ_ORED flag is set on an IRQ descriptor, this function is 537 * used to return the corresponding or gate input IRQ. The or gate is created if 538 * not already existant. 539 * 540 * Or gates are placed under the /soc/irq-or-gates QOM container. 541 */ 542 static qemu_irq versal_get_irq_or_gate_in(Versal *s, int irq_idx, 543 qemu_irq target_irq) 544 { 545 static const char *TARGET_STR[] = { 546 [IRQ_TARGET_GIC] = "gic", 547 [IRQ_TARGET_PPU1] = "ppu1", 548 [IRQ_TARGET_EAM] = "eam", 549 }; 550 551 VersalIrqTarget target; 552 Object *container = versal_get_child(s, "irq-or-gates"); 553 DeviceState *dev; 554 g_autofree char *name; 555 int idx, or_idx; 556 557 idx = FIELD_EX32(irq_idx, VERSAL_IRQ, IRQ); 558 or_idx = FIELD_EX32(irq_idx, VERSAL_IRQ, OR_IDX); 559 target = FIELD_EX32(irq_idx, VERSAL_IRQ, TARGET); 560 561 name = g_strdup_printf("%s-irq[%d]", TARGET_STR[target], idx); 562 dev = DEVICE(object_resolve_path_at(container, name)); 563 564 if (dev == NULL) { 565 dev = qdev_new(TYPE_OR_IRQ); 566 object_property_add_child(container, name, OBJECT(dev)); 567 qdev_prop_set_uint16(dev, "num-lines", 1 << R_VERSAL_IRQ_OR_IDX_LENGTH); 568 qdev_realize_and_unref(dev, NULL, &error_abort); 569 qdev_connect_gpio_out(dev, 0, target_irq); 570 } 571 572 return qdev_get_gpio_in(dev, or_idx); 573 } 574 575 static qemu_irq versal_get_irq(Versal *s, int irq_idx) 576 { 577 VersalIrqTarget target; 578 qemu_irq irq; 579 bool ored; 580 581 target = FIELD_EX32(irq_idx, VERSAL_IRQ, TARGET); 582 ored = FIELD_EX32(irq_idx, VERSAL_IRQ, ORED); 583 584 switch (target) { 585 case IRQ_TARGET_EAM: 586 /* EAM not implemented */ 587 return NULL; 588 589 case IRQ_TARGET_PPU1: 590 /* PPU1 CPU not implemented */ 591 return NULL; 592 593 case IRQ_TARGET_GIC: 594 irq = versal_get_gic_irq(s, irq_idx); 595 break; 596 597 default: 598 g_assert_not_reached(); 599 } 600 601 if (ored) { 602 irq = versal_get_irq_or_gate_in(s, irq_idx, irq); 603 } 604 605 return irq; 606 } 607 608 static void versal_sysbus_connect_irq(Versal *s, SysBusDevice *sbd, 609 int sbd_idx, int irq_idx) 610 { 611 qemu_irq irq = versal_get_irq(s, irq_idx); 612 613 if (irq == NULL) { 614 return; 615 } 616 617 sysbus_connect_irq(sbd, sbd_idx, irq); 618 } 619 620 static void versal_qdev_connect_gpio_out(Versal *s, DeviceState *dev, 621 int dev_idx, int irq_idx) 622 { 623 qemu_irq irq = versal_get_irq(s, irq_idx); 624 625 if (irq == NULL) { 626 return; 627 } 628 629 qdev_connect_gpio_out(dev, dev_idx, irq); 630 } 631 632 static inline char *versal_fdt_add_subnode(Versal *s, const char *path, 633 uint64_t at, const char *compat, 634 size_t compat_sz) 635 { 636 char *p; 637 638 p = g_strdup_printf("%s@%" PRIx64, path, at); 639 qemu_fdt_add_subnode(s->cfg.fdt, p); 640 641 if (!strncmp(compat, "memory", compat_sz)) { 642 qemu_fdt_setprop(s->cfg.fdt, p, "device_type", compat, compat_sz); 643 } else { 644 qemu_fdt_setprop(s->cfg.fdt, p, "compatible", compat, compat_sz); 645 } 646 647 return p; 648 } 649 650 static inline char *versal_fdt_add_simple_subnode(Versal *s, const char *path, 651 uint64_t addr, uint64_t len, 652 const char *compat, 653 size_t compat_sz) 654 { 655 char *p = versal_fdt_add_subnode(s, path, addr, compat, compat_sz); 656 657 qemu_fdt_setprop_sized_cells(s->cfg.fdt, p, "reg", 2, addr, 2, len); 658 return p; 659 } 660 661 static inline DeviceState *create_or_gate(Versal *s, Object *parent, 662 const char *name, uint16_t num_lines, 663 int irq_idx) 664 { 665 DeviceState *or; 666 667 or = qdev_new(TYPE_OR_IRQ); 668 qdev_prop_set_uint16(or, "num-lines", num_lines); 669 object_property_add_child(parent, name, OBJECT(or)); 670 qdev_realize_and_unref(or, NULL, &error_abort); 671 versal_qdev_connect_gpio_out(s, or, 0, irq_idx); 672 673 return or; 674 } 675 676 static MemoryRegion *create_cpu_mr(Versal *s, DeviceState *cluster, 677 const VersalCpuClusterMap *map) 678 { 679 MemoryRegion *mr, *root_alias; 680 char *name; 681 682 mr = g_new(MemoryRegion, 1); 683 name = g_strdup_printf("%s-mr", map->name); 684 memory_region_init(mr, OBJECT(cluster), name, UINT64_MAX); 685 g_free(name); 686 687 root_alias = g_new(MemoryRegion, 1); 688 name = g_strdup_printf("ps-alias-for-%s", map->name); 689 memory_region_init_alias(root_alias, OBJECT(cluster), name, 690 &s->mr_ps, 0, UINT64_MAX); 691 g_free(name); 692 memory_region_add_subregion(mr, 0, root_alias); 693 694 return mr; 695 } 696 697 static void versal_create_gic_its(Versal *s, 698 const VersalCpuClusterMap *map, 699 DeviceState *gic, 700 MemoryRegion *mr, 701 char *gic_node) 702 { 703 DeviceState *dev; 704 SysBusDevice *sbd; 705 g_autofree char *node_pat = NULL, *node = NULL; 706 const char compatible[] = "arm,gic-v3-its"; 707 708 if (map->gic.version != 3) { 709 return; 710 } 711 712 if (!map->gic.has_its) { 713 return; 714 } 715 716 dev = qdev_new(TYPE_ARM_GICV3_ITS); 717 sbd = SYS_BUS_DEVICE(dev); 718 719 object_property_add_child(OBJECT(gic), "its", OBJECT(dev)); 720 object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(gic), 721 &error_abort); 722 723 sysbus_realize_and_unref(sbd, &error_abort); 724 725 memory_region_add_subregion(mr, map->gic.its, 726 sysbus_mmio_get_region(sbd, 0)); 727 728 if (!map->dtb_expose) { 729 return; 730 } 731 732 qemu_fdt_setprop(s->cfg.fdt, gic_node, "ranges", NULL, 0); 733 qemu_fdt_setprop_cell(s->cfg.fdt, gic_node, "#address-cells", 2); 734 qemu_fdt_setprop_cell(s->cfg.fdt, gic_node, "#size-cells", 2); 735 736 node_pat = g_strdup_printf("%s/its", gic_node); 737 node = versal_fdt_add_simple_subnode(s, node_pat, map->gic.its, 0x20000, 738 compatible, sizeof(compatible)); 739 qemu_fdt_setprop(s->cfg.fdt, node, "msi-controller", NULL, 0); 740 qemu_fdt_setprop_cell(s->cfg.fdt, node, "#msi-cells", 1); 741 } 742 743 static DeviceState *versal_create_gic(Versal *s, 744 const VersalCpuClusterMap *map, 745 MemoryRegion *mr, 746 int first_cpu_idx, 747 size_t num_cpu) 748 { 749 DeviceState *dev; 750 SysBusDevice *sbd; 751 g_autofree char *node = NULL; 752 g_autofree char *name = NULL; 753 const char gicv3_compat[] = "arm,gic-v3"; 754 const char gicv2_compat[] = "arm,cortex-a15-gic"; 755 756 switch (map->gic.version) { 757 case 2: 758 dev = qdev_new(gic_class_name()); 759 break; 760 761 case 3: 762 dev = qdev_new(gicv3_class_name()); 763 break; 764 765 default: 766 g_assert_not_reached(); 767 } 768 769 name = g_strdup_printf("%s-gic[*]", map->name); 770 object_property_add_child(OBJECT(s), name, OBJECT(dev)); 771 sbd = SYS_BUS_DEVICE(dev); 772 qdev_prop_set_uint32(dev, "revision", map->gic.version); 773 qdev_prop_set_uint32(dev, "num-cpu", num_cpu); 774 qdev_prop_set_uint32(dev, "num-irq", map->gic.num_irq + 32); 775 qdev_prop_set_bit(dev, "has-security-extensions", true); 776 qdev_prop_set_uint32(dev, "first-cpu-index", first_cpu_idx); 777 778 if (map->gic.version == 3) { 779 QList *redist_region_count; 780 781 redist_region_count = qlist_new(); 782 qlist_append_int(redist_region_count, num_cpu); 783 qdev_prop_set_array(dev, "redist-region-count", redist_region_count); 784 qdev_prop_set_bit(dev, "has-lpi", map->gic.has_its); 785 object_property_set_link(OBJECT(dev), "sysmem", OBJECT(mr), 786 &error_abort); 787 788 } 789 790 sysbus_realize_and_unref(sbd, &error_fatal); 791 792 memory_region_add_subregion(mr, map->gic.dist, 793 sysbus_mmio_get_region(sbd, 0)); 794 795 if (map->gic.version == 3) { 796 memory_region_add_subregion(mr, map->gic.redist, 797 sysbus_mmio_get_region(sbd, 1)); 798 } else { 799 memory_region_add_subregion(mr, map->gic.cpu_iface, 800 sysbus_mmio_get_region(sbd, 1)); 801 } 802 803 if (map->dtb_expose) { 804 if (map->gic.version == 3) { 805 node = versal_fdt_add_subnode(s, "/gic", map->gic.dist, 806 gicv3_compat, 807 sizeof(gicv3_compat)); 808 qemu_fdt_setprop_sized_cells(s->cfg.fdt, node, "reg", 809 2, map->gic.dist, 810 2, 0x10000, 811 2, map->gic.redist, 812 2, GICV3_REDIST_SIZE * num_cpu); 813 } else { 814 node = versal_fdt_add_subnode(s, "/gic", map->gic.dist, 815 gicv2_compat, 816 sizeof(gicv2_compat)); 817 qemu_fdt_setprop_sized_cells(s->cfg.fdt, node, "reg", 818 2, map->gic.dist, 819 2, 0x1000, 820 2, map->gic.cpu_iface, 821 2, 0x1000); 822 } 823 824 qemu_fdt_setprop_cell(s->cfg.fdt, node, "phandle", s->phandle.gic); 825 qemu_fdt_setprop_cell(s->cfg.fdt, node, "#interrupt-cells", 3); 826 qemu_fdt_setprop_cells(s->cfg.fdt, node, "interrupts", 827 GIC_FDT_IRQ_TYPE_PPI, 828 INTID_TO_PPI(ARCH_GIC_MAINT_IRQ), 829 GIC_FDT_IRQ_FLAGS_LEVEL_HI); 830 qemu_fdt_setprop(s->cfg.fdt, node, "interrupt-controller", NULL, 0); 831 } 832 833 versal_create_gic_its(s, map, dev, mr, node); 834 835 g_array_append_val(s->intc, dev); 836 837 return dev; 838 } 839 840 static void connect_gic_to_cpu(const VersalCpuClusterMap *map, 841 DeviceState *gic, DeviceState *cpu, size_t idx, 842 size_t num_cpu) 843 { 844 SysBusDevice *sbd = SYS_BUS_DEVICE(gic); 845 int ppibase = map->gic.num_irq + idx * GIC_INTERNAL + GIC_NR_SGIS; 846 int ti; 847 bool has_gtimer; 848 /* 849 * Mapping from the output timer irq lines from the CPU to the 850 * GIC PPI inputs. 851 */ 852 const int timer_irq[] = { 853 [GTIMER_PHYS] = INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), 854 [GTIMER_VIRT] = INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), 855 [GTIMER_HYP] = INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), 856 [GTIMER_SEC] = INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), 857 }; 858 859 has_gtimer = arm_feature(&ARM_CPU(cpu)->env, ARM_FEATURE_GENERIC_TIMER); 860 861 if (has_gtimer) { 862 for (ti = 0; ti < ARRAY_SIZE(timer_irq); ti++) { 863 qdev_connect_gpio_out(cpu, ti, 864 qdev_get_gpio_in(gic, 865 ppibase + timer_irq[ti])); 866 } 867 } 868 869 if (map->gic.version == 3) { 870 qemu_irq maint_irq; 871 int maint_idx = ppibase + INTID_TO_PPI(ARCH_GIC_MAINT_IRQ); 872 873 maint_irq = qdev_get_gpio_in(gic, maint_idx); 874 qdev_connect_gpio_out_named(cpu, "gicv3-maintenance-interrupt", 875 0, maint_irq); 876 } 877 878 sysbus_connect_irq(sbd, idx, qdev_get_gpio_in(cpu, ARM_CPU_IRQ)); 879 sysbus_connect_irq(sbd, idx + num_cpu, 880 qdev_get_gpio_in(cpu, ARM_CPU_FIQ)); 881 sysbus_connect_irq(sbd, idx + 2 * num_cpu, 882 qdev_get_gpio_in(cpu, ARM_CPU_VIRQ)); 883 sysbus_connect_irq(sbd, idx + 3 * num_cpu, 884 qdev_get_gpio_in(cpu, ARM_CPU_VFIQ)); 885 } 886 887 static inline void versal_create_and_connect_gic(Versal *s, 888 const VersalCpuClusterMap *map, 889 MemoryRegion *mr, 890 DeviceState **cpus, 891 size_t num_cpu) 892 { 893 DeviceState *gic; 894 int first_cpu_idx; 895 size_t i; 896 897 first_cpu_idx = CPU(cpus[0])->cpu_index; 898 gic = versal_create_gic(s, map, mr, first_cpu_idx, num_cpu); 899 900 for (i = 0; i < num_cpu; i++) { 901 connect_gic_to_cpu(map, gic, cpus[i], i, num_cpu); 902 } 903 } 904 905 static DeviceState *versal_create_cpu(Versal *s, 906 const VersalCpuClusterMap *map, 907 DeviceState *qemu_cluster, 908 MemoryRegion *cpu_mr, 909 size_t cluster_idx, 910 size_t core_idx) 911 { 912 DeviceState *cpu = qdev_new(map->cpu_model); 913 ARMCPU *arm_cpu = ARM_CPU(cpu); 914 Object *obj = OBJECT(cpu); 915 uint64_t affinity; 916 bool start_off; 917 size_t idx = cluster_idx * map->num_core + core_idx; 918 g_autofree char *name; 919 g_autofree char *node = NULL; 920 921 affinity = map->mp_affinity.base; 922 affinity |= (cluster_idx & 0xff) << map->mp_affinity.cluster_shift; 923 affinity |= (core_idx & 0xff) << map->mp_affinity.core_shift; 924 925 start_off = map->start_powered_off == SPO_ALL 926 || ((map->start_powered_off == SPO_SECONDARIES) 927 && (cluster_idx || core_idx)); 928 929 name = g_strdup_printf("%s[*]", map->name); 930 object_property_add_child(OBJECT(qemu_cluster), name, obj); 931 object_property_set_bool(obj, "start-powered-off", start_off, 932 &error_abort); 933 qdev_prop_set_uint64(cpu, "mp-affinity", affinity); 934 qdev_prop_set_int32(cpu, "core-count", map->num_core); 935 object_property_set_link(obj, "memory", OBJECT(cpu_mr), &error_abort); 936 qdev_realize_and_unref(cpu, NULL, &error_fatal); 937 938 if (!map->dtb_expose) { 939 return cpu; 940 } 941 942 node = versal_fdt_add_subnode(s, "/cpus/cpu", idx, 943 arm_cpu->dtb_compatible, 944 strlen(arm_cpu->dtb_compatible) + 1); 945 qemu_fdt_setprop_cell(s->cfg.fdt, node, "reg", 946 arm_cpu_mp_affinity(arm_cpu) & ARM64_AFFINITY_MASK); 947 qemu_fdt_setprop_string(s->cfg.fdt, node, "device_type", "cpu"); 948 qemu_fdt_setprop_string(s->cfg.fdt, node, "enable-method", "psci"); 949 950 return cpu; 951 } 952 953 static void versal_create_cpu_cluster(Versal *s, const VersalCpuClusterMap *map) 954 { 955 size_t i, j; 956 DeviceState *cluster; 957 MemoryRegion *mr; 958 char *name; 959 g_autofree DeviceState **cpus; 960 const char compatible[] = "arm,armv8-timer"; 961 bool has_gtimer; 962 963 cluster = qdev_new(TYPE_CPU_CLUSTER); 964 name = g_strdup_printf("%s-cluster", map->name); 965 object_property_add_child(OBJECT(s), name, OBJECT(cluster)); 966 g_free(name); 967 qdev_prop_set_uint32(cluster, "cluster-id", map->qemu_cluster_id); 968 969 mr = create_cpu_mr(s, cluster, map); 970 971 cpus = g_new(DeviceState *, map->num_cluster * map->num_core); 972 973 if (map->dtb_expose) { 974 qemu_fdt_add_subnode(s->cfg.fdt, "/cpus"); 975 qemu_fdt_setprop_cell(s->cfg.fdt, "/cpus", "#size-cells", 0); 976 qemu_fdt_setprop_cell(s->cfg.fdt, "/cpus", "#address-cells", 1); 977 } 978 979 for (i = 0; i < map->num_cluster; i++) { 980 for (j = 0; j < map->num_core; j++) { 981 DeviceState *cpu = versal_create_cpu(s, map, cluster, mr, i, j); 982 983 cpus[i * map->num_core + j] = cpu; 984 } 985 986 if (map->per_cluster_gic) { 987 versal_create_and_connect_gic(s, map, mr, &cpus[i * map->num_core], 988 map->num_core); 989 } 990 } 991 992 qdev_realize_and_unref(cluster, NULL, &error_fatal); 993 994 if (!map->per_cluster_gic) { 995 versal_create_and_connect_gic(s, map, mr, cpus, 996 map->num_cluster * map->num_core); 997 } 998 999 has_gtimer = arm_feature(&ARM_CPU(cpus[0])->env, ARM_FEATURE_GENERIC_TIMER); 1000 if (map->dtb_expose && has_gtimer) { 1001 qemu_fdt_add_subnode(s->cfg.fdt, "/timer"); 1002 qemu_fdt_setprop_cells(s->cfg.fdt, "/timer", "interrupts", 1003 GIC_FDT_IRQ_TYPE_PPI, 1004 INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), 1005 GIC_FDT_IRQ_FLAGS_LEVEL_HI, 1006 GIC_FDT_IRQ_TYPE_PPI, 1007 INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), 1008 GIC_FDT_IRQ_FLAGS_LEVEL_HI, 1009 GIC_FDT_IRQ_TYPE_PPI, 1010 INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), 1011 GIC_FDT_IRQ_FLAGS_LEVEL_HI, 1012 GIC_FDT_IRQ_TYPE_PPI, 1013 INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), 1014 GIC_FDT_IRQ_FLAGS_LEVEL_HI); 1015 qemu_fdt_setprop(s->cfg.fdt, "/timer", "compatible", 1016 compatible, sizeof(compatible)); 1017 } 1018 } 1019 1020 static void versal_create_uart(Versal *s, 1021 const VersalSimplePeriphMap *map, 1022 int chardev_idx) 1023 { 1024 DeviceState *dev; 1025 MemoryRegion *mr; 1026 g_autofree char *node; 1027 g_autofree char *alias; 1028 const char compatible[] = "arm,pl011\0arm,sbsa-uart"; 1029 const char clocknames[] = "uartclk\0apb_pclk"; 1030 1031 dev = qdev_new(TYPE_PL011); 1032 object_property_add_child(OBJECT(s), "uart[*]", OBJECT(dev)); 1033 qdev_prop_set_chr(dev, "chardev", serial_hd(chardev_idx)); 1034 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 1035 1036 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 1037 memory_region_add_subregion(&s->mr_ps, map->addr, mr); 1038 1039 versal_sysbus_connect_irq(s, SYS_BUS_DEVICE(dev), 0, map->irq); 1040 1041 node = versal_fdt_add_simple_subnode(s, "/uart", map->addr, 0x1000, 1042 compatible, sizeof(compatible)); 1043 qemu_fdt_setprop_cell(s->cfg.fdt, node, "current-speed", 115200); 1044 qemu_fdt_setprop_cells(s->cfg.fdt, node, "clocks", 1045 s->phandle.clk_125mhz, s->phandle.clk_125mhz); 1046 qemu_fdt_setprop(s->cfg.fdt, node, "clock-names", clocknames, 1047 sizeof(clocknames)); 1048 qemu_fdt_setprop_cells(s->cfg.fdt, node, "interrupts", 1049 GIC_FDT_IRQ_TYPE_SPI, map->irq, 1050 GIC_FDT_IRQ_FLAGS_LEVEL_HI); 1051 qemu_fdt_setprop(s->cfg.fdt, node, "u-boot,dm-pre-reloc", NULL, 0); 1052 1053 alias = g_strdup_printf("serial%d", chardev_idx); 1054 qemu_fdt_setprop_string(s->cfg.fdt, "/aliases", alias, node); 1055 1056 if (chardev_idx == 0) { 1057 qemu_fdt_setprop_string(s->cfg.fdt, "/chosen", "stdout-path", node); 1058 } 1059 } 1060 1061 static void versal_create_canfd(Versal *s, const VersalSimplePeriphMap *map, 1062 CanBusState *bus) 1063 { 1064 SysBusDevice *sbd; 1065 MemoryRegion *mr; 1066 g_autofree char *node; 1067 const char compatible[] = "xlnx,canfd-2.0"; 1068 const char clocknames[] = "can_clk\0s_axi_aclk"; 1069 1070 sbd = SYS_BUS_DEVICE(qdev_new(TYPE_XILINX_CANFD)); 1071 object_property_add_child(OBJECT(s), "canfd[*]", OBJECT(sbd)); 1072 1073 object_property_set_int(OBJECT(sbd), "ext_clk_freq", 1074 25 * 1000 * 1000 , &error_abort); 1075 1076 object_property_set_link(OBJECT(sbd), "canfdbus", OBJECT(bus), 1077 &error_abort); 1078 1079 sysbus_realize_and_unref(sbd, &error_fatal); 1080 1081 mr = sysbus_mmio_get_region(sbd, 0); 1082 memory_region_add_subregion(&s->mr_ps, map->addr, mr); 1083 1084 versal_sysbus_connect_irq(s, sbd, 0, map->irq); 1085 1086 node = versal_fdt_add_simple_subnode(s, "/canfd", map->addr, 0x10000, 1087 compatible, sizeof(compatible)); 1088 qemu_fdt_setprop_cell(s->cfg.fdt, node, "rx-fifo-depth", 0x40); 1089 qemu_fdt_setprop_cell(s->cfg.fdt, node, "tx-mailbox-count", 0x20); 1090 qemu_fdt_setprop_cells(s->cfg.fdt, node, "clocks", 1091 s->phandle.clk_25mhz, s->phandle.clk_25mhz); 1092 qemu_fdt_setprop(s->cfg.fdt, node, "clock-names", 1093 clocknames, sizeof(clocknames)); 1094 qemu_fdt_setprop_cells(s->cfg.fdt, node, "interrupts", 1095 GIC_FDT_IRQ_TYPE_SPI, map->irq, 1096 GIC_FDT_IRQ_FLAGS_LEVEL_HI); 1097 } 1098 1099 static void versal_create_usb(Versal *s, 1100 const struct VersalUsbMap *map) 1101 { 1102 DeviceState *dev; 1103 MemoryRegion *mr; 1104 g_autofree char *node, *subnode; 1105 const char clocknames[] = "bus_clk\0ref_clk"; 1106 const char irq_name[] = "dwc_usb3"; 1107 const char compat_versal_dwc3[] = "xlnx,versal-dwc3"; 1108 const char compat_dwc3[] = "snps,dwc3"; 1109 1110 dev = qdev_new(TYPE_XILINX_VERSAL_USB2); 1111 object_property_add_child(OBJECT(s), "usb[*]", OBJECT(dev)); 1112 1113 object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps), 1114 &error_abort); 1115 qdev_prop_set_uint32(dev, "intrs", 1); 1116 qdev_prop_set_uint32(dev, "slots", 2); 1117 1118 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 1119 1120 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 1121 memory_region_add_subregion(&s->mr_ps, map->xhci, mr); 1122 1123 versal_sysbus_connect_irq(s, SYS_BUS_DEVICE(dev), 0, map->irq); 1124 1125 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); 1126 memory_region_add_subregion(&s->mr_ps, map->ctrl, mr); 1127 1128 node = versal_fdt_add_simple_subnode(s, "/usb", map->ctrl, 0x10000, 1129 compat_versal_dwc3, 1130 sizeof(compat_versal_dwc3)); 1131 qemu_fdt_setprop(s->cfg.fdt, node, "clock-names", 1132 clocknames, sizeof(clocknames)); 1133 qemu_fdt_setprop_cells(s->cfg.fdt, node, "clocks", 1134 s->phandle.clk_25mhz, s->phandle.clk_125mhz); 1135 qemu_fdt_setprop(s->cfg.fdt, node, "ranges", NULL, 0); 1136 qemu_fdt_setprop_cell(s->cfg.fdt, node, "#address-cells", 2); 1137 qemu_fdt_setprop_cell(s->cfg.fdt, node, "#size-cells", 2); 1138 1139 subnode = g_strdup_printf("/%s/dwc3", node); 1140 g_free(node); 1141 1142 node = versal_fdt_add_simple_subnode(s, subnode, map->xhci, 0x10000, 1143 compat_dwc3, 1144 sizeof(compat_dwc3)); 1145 qemu_fdt_setprop(s->cfg.fdt, node, "interrupt-names", 1146 irq_name, sizeof(irq_name)); 1147 qemu_fdt_setprop_cells(s->cfg.fdt, node, "interrupts", 1148 GIC_FDT_IRQ_TYPE_SPI, map->irq, 1149 GIC_FDT_IRQ_FLAGS_LEVEL_HI); 1150 qemu_fdt_setprop_cell(s->cfg.fdt, node, 1151 "snps,quirk-frame-length-adjustment", 0x20); 1152 qemu_fdt_setprop_cells(s->cfg.fdt, node, "#stream-id-cells", 1); 1153 qemu_fdt_setprop_string(s->cfg.fdt, node, "dr_mode", "host"); 1154 qemu_fdt_setprop_string(s->cfg.fdt, node, "phy-names", "usb3-phy"); 1155 qemu_fdt_setprop(s->cfg.fdt, node, "snps,dis_u2_susphy_quirk", NULL, 0); 1156 qemu_fdt_setprop(s->cfg.fdt, node, "snps,dis_u3_susphy_quirk", NULL, 0); 1157 qemu_fdt_setprop(s->cfg.fdt, node, "snps,refclk_fladj", NULL, 0); 1158 qemu_fdt_setprop(s->cfg.fdt, node, "snps,mask_phy_reset", NULL, 0); 1159 qemu_fdt_setprop_string(s->cfg.fdt, node, "maximum-speed", "high-speed"); 1160 } 1161 1162 static void versal_create_gem(Versal *s, 1163 const struct VersalGemMap *map) 1164 { 1165 DeviceState *dev; 1166 MemoryRegion *mr; 1167 DeviceState *or; 1168 int i; 1169 1170 dev = qdev_new(TYPE_CADENCE_GEM); 1171 object_property_add_child(OBJECT(s), "gem[*]", OBJECT(dev)); 1172 1173 qemu_configure_nic_device(dev, true, NULL); 1174 object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort); 1175 object_property_set_int(OBJECT(dev), "num-priority-queues", 1176 map->num_prio_queue, &error_abort); 1177 1178 object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps), 1179 &error_abort); 1180 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 1181 1182 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 1183 memory_region_add_subregion(&s->mr_ps, map->map.addr, mr); 1184 1185 /* 1186 * The GEM controller exposes one IRQ line per priority queue. In Versal 1187 * family devices, those are OR'ed together. 1188 */ 1189 or = create_or_gate(s, OBJECT(dev), "irq-orgate", 1190 map->num_prio_queue, map->map.irq); 1191 1192 for (i = 0; i < map->num_prio_queue; i++) { 1193 sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, qdev_get_gpio_in(or, i)); 1194 } 1195 } 1196 1197 static void versal_create_gem_fdt(Versal *s, 1198 const struct VersalGemMap *map) 1199 { 1200 int i; 1201 g_autofree char *node; 1202 g_autofree char *phy_node; 1203 int phy_phandle; 1204 const char compatible[] = "cdns,zynqmp-gem\0cdns,gem"; 1205 const char clocknames[] = "pclk\0hclk\0tx_clk\0rx_clk"; 1206 g_autofree uint32_t *irq_prop; 1207 1208 node = versal_fdt_add_simple_subnode(s, "/ethernet", map->map.addr, 0x1000, 1209 compatible, sizeof(compatible)); 1210 phy_node = g_strdup_printf("%s/fixed-link", node); 1211 phy_phandle = qemu_fdt_alloc_phandle(s->cfg.fdt); 1212 1213 /* Fixed link PHY node */ 1214 qemu_fdt_add_subnode(s->cfg.fdt, phy_node); 1215 qemu_fdt_setprop_cell(s->cfg.fdt, phy_node, "phandle", phy_phandle); 1216 qemu_fdt_setprop(s->cfg.fdt, phy_node, "full-duplex", NULL, 0); 1217 qemu_fdt_setprop_cell(s->cfg.fdt, phy_node, "speed", map->speed); 1218 1219 qemu_fdt_setprop_string(s->cfg.fdt, node, "phy-mode", map->phy_mode); 1220 qemu_fdt_setprop_cell(s->cfg.fdt, node, "phy-handle", phy_phandle); 1221 qemu_fdt_setprop_cells(s->cfg.fdt, node, "clocks", 1222 s->phandle.clk_25mhz, s->phandle.clk_25mhz, 1223 s->phandle.clk_125mhz, s->phandle.clk_125mhz); 1224 qemu_fdt_setprop(s->cfg.fdt, node, "clock-names", 1225 clocknames, sizeof(clocknames)); 1226 1227 irq_prop = g_new(uint32_t, map->num_prio_queue * 3); 1228 for (i = 0; i < map->num_prio_queue; i++) { 1229 irq_prop[3 * i] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI); 1230 irq_prop[3 * i + 1] = cpu_to_be32(map->map.irq); 1231 irq_prop[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_HI); 1232 } 1233 qemu_fdt_setprop(s->cfg.fdt, node, "interrupts", irq_prop, 1234 sizeof(uint32_t) * map->num_prio_queue * 3); 1235 } 1236 1237 static void versal_create_zdma(Versal *s, 1238 const struct VersalZDMAMap *map) 1239 { 1240 DeviceState *dev; 1241 MemoryRegion *mr; 1242 g_autofree char *name; 1243 const char compatible[] = "xlnx,zynqmp-dma-1.0"; 1244 const char clocknames[] = "clk_main\0clk_apb"; 1245 size_t i; 1246 1247 name = g_strdup_printf("%s[*]", map->name); 1248 1249 for (i = 0; i < map->num_chan; i++) { 1250 uint64_t addr = map->map.addr + map->chan_stride * i; 1251 int irq = map->map.irq + map->irq_stride * i; 1252 g_autofree char *node; 1253 1254 dev = qdev_new(TYPE_XLNX_ZDMA); 1255 object_property_add_child(OBJECT(s), name, OBJECT(dev)); 1256 object_property_set_int(OBJECT(dev), "bus-width", 128, &error_abort); 1257 object_property_set_link(OBJECT(dev), "dma", 1258 OBJECT(get_system_memory()), &error_fatal); 1259 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 1260 1261 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 1262 memory_region_add_subregion(&s->mr_ps, addr, mr); 1263 1264 versal_sysbus_connect_irq(s, SYS_BUS_DEVICE(dev), 0, irq); 1265 1266 node = versal_fdt_add_simple_subnode(s, "/dma", addr, 0x1000, 1267 compatible, sizeof(compatible)); 1268 qemu_fdt_setprop_cell(s->cfg.fdt, node, "xlnx,bus-width", 64); 1269 qemu_fdt_setprop_cells(s->cfg.fdt, node, "clocks", 1270 s->phandle.clk_25mhz, s->phandle.clk_25mhz); 1271 qemu_fdt_setprop(s->cfg.fdt, node, "clock-names", 1272 clocknames, sizeof(clocknames)); 1273 qemu_fdt_setprop_cells(s->cfg.fdt, node, "interrupts", 1274 GIC_FDT_IRQ_TYPE_SPI, irq, 1275 GIC_FDT_IRQ_FLAGS_LEVEL_HI); 1276 } 1277 } 1278 1279 #define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */ 1280 static void versal_create_sdhci(Versal *s, 1281 const VersalSimplePeriphMap *map) 1282 { 1283 DeviceState *dev; 1284 MemoryRegion *mr; 1285 g_autofree char *node; 1286 const char compatible[] = "arasan,sdhci-8.9a"; 1287 const char clocknames[] = "clk_xin\0clk_ahb"; 1288 1289 dev = qdev_new(TYPE_SYSBUS_SDHCI); 1290 object_property_add_child(OBJECT(s), "sdhci[*]", OBJECT(dev)); 1291 1292 object_property_set_uint(OBJECT(dev), "sd-spec-version", 3, 1293 &error_fatal); 1294 object_property_set_uint(OBJECT(dev), "capareg", SDHCI_CAPABILITIES, 1295 &error_fatal); 1296 object_property_set_uint(OBJECT(dev), "uhs", UHS_I, &error_fatal); 1297 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 1298 1299 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 1300 memory_region_add_subregion(&s->mr_ps, map->addr, mr); 1301 1302 versal_sysbus_connect_irq(s, SYS_BUS_DEVICE(dev), 0, map->irq); 1303 1304 node = versal_fdt_add_simple_subnode(s, "/sdhci", map->addr, 0x10000, 1305 compatible, sizeof(compatible)); 1306 qemu_fdt_setprop_cells(s->cfg.fdt, node, "clocks", 1307 s->phandle.clk_25mhz, s->phandle.clk_25mhz); 1308 qemu_fdt_setprop(s->cfg.fdt, node, "clock-names", 1309 clocknames, sizeof(clocknames)); 1310 qemu_fdt_setprop_cells(s->cfg.fdt, node, "interrupts", 1311 GIC_FDT_IRQ_TYPE_SPI, map->irq, 1312 GIC_FDT_IRQ_FLAGS_LEVEL_HI); 1313 } 1314 1315 static void versal_create_rtc(Versal *s, const struct VersalRtcMap *map) 1316 { 1317 SysBusDevice *sbd; 1318 MemoryRegion *mr; 1319 g_autofree char *node; 1320 const char compatible[] = "xlnx,zynqmp-rtc"; 1321 const char interrupt_names[] = "alarm\0sec"; 1322 1323 sbd = SYS_BUS_DEVICE(qdev_new(TYPE_XLNX_ZYNQMP_RTC)); 1324 object_property_add_child(OBJECT(s), "rtc", OBJECT(sbd)); 1325 sysbus_realize_and_unref(sbd, &error_abort); 1326 1327 mr = sysbus_mmio_get_region(sbd, 0); 1328 memory_region_add_subregion(&s->mr_ps, map->map.addr, mr); 1329 1330 /* 1331 * TODO: Connect the ALARM and SECONDS interrupts once our RTC model 1332 * supports them. 1333 */ 1334 versal_sysbus_connect_irq(s, sbd, 0, map->map.irq); 1335 1336 node = versal_fdt_add_simple_subnode(s, "/rtc", map->map.addr, 0x10000, 1337 compatible, sizeof(compatible)); 1338 qemu_fdt_setprop_cells(s->cfg.fdt, node, "interrupts", 1339 GIC_FDT_IRQ_TYPE_SPI, map->alarm_irq, 1340 GIC_FDT_IRQ_FLAGS_LEVEL_HI, 1341 GIC_FDT_IRQ_TYPE_SPI, map->second_irq, 1342 GIC_FDT_IRQ_FLAGS_LEVEL_HI); 1343 qemu_fdt_setprop(s->cfg.fdt, node, "interrupt-names", 1344 interrupt_names, sizeof(interrupt_names)); 1345 } 1346 1347 static void versal_create_trng(Versal *s, const VersalSimplePeriphMap *map) 1348 { 1349 SysBusDevice *sbd; 1350 MemoryRegion *mr; 1351 1352 sbd = SYS_BUS_DEVICE(qdev_new(TYPE_XLNX_VERSAL_TRNG)); 1353 object_property_add_child(OBJECT(s), "trng", OBJECT(sbd)); 1354 sysbus_realize_and_unref(sbd, &error_abort); 1355 1356 mr = sysbus_mmio_get_region(sbd, 0); 1357 memory_region_add_subregion(&s->mr_ps, map->addr, mr); 1358 versal_sysbus_connect_irq(s, sbd, 0, map->irq); 1359 } 1360 1361 static void versal_create_xrams(Versal *s, const struct VersalXramMap *map) 1362 { 1363 SysBusDevice *sbd; 1364 MemoryRegion *mr; 1365 DeviceState *or; 1366 size_t i; 1367 1368 or = create_or_gate(s, OBJECT(s), "xram-orgate", map->num, map->irq); 1369 1370 for (i = 0; i < map->num; i++) { 1371 hwaddr ctrl, mem; 1372 1373 sbd = SYS_BUS_DEVICE(qdev_new(TYPE_XLNX_XRAM_CTRL)); 1374 object_property_add_child(OBJECT(s), "xram[*]", OBJECT(sbd)); 1375 sysbus_realize_and_unref(sbd, &error_fatal); 1376 1377 ctrl = map->ctrl + map->ctrl_stride * i; 1378 mem = map->mem + map->mem_stride * i; 1379 1380 mr = sysbus_mmio_get_region(sbd, 0); 1381 memory_region_add_subregion(&s->mr_ps, ctrl, mr); 1382 mr = sysbus_mmio_get_region(sbd, 1); 1383 memory_region_add_subregion(&s->mr_ps, mem, mr); 1384 1385 sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(or, i)); 1386 } 1387 } 1388 1389 static void versal_create_bbram(Versal *s, 1390 const VersalSimplePeriphMap *map) 1391 { 1392 DeviceState *dev; 1393 SysBusDevice *sbd; 1394 1395 dev = qdev_new(TYPE_XLNX_BBRAM); 1396 sbd = SYS_BUS_DEVICE(dev); 1397 1398 object_property_add_child(OBJECT(s), "bbram", OBJECT(dev)); 1399 qdev_prop_set_uint32(dev, "crc-zpads", 0); 1400 sysbus_realize_and_unref(sbd, &error_abort); 1401 memory_region_add_subregion(&s->mr_ps, map->addr, 1402 sysbus_mmio_get_region(sbd, 0)); 1403 versal_sysbus_connect_irq(s, sbd, 0, map->irq); 1404 } 1405 1406 static void versal_create_efuse(Versal *s, 1407 const struct VersalEfuseMap *map) 1408 { 1409 DeviceState *bits; 1410 DeviceState *ctrl; 1411 DeviceState *cache; 1412 1413 if (versal_get_version(s) != VERSAL_VER_VERSAL) { 1414 /* TODO for versal2 */ 1415 return; 1416 } 1417 1418 ctrl = qdev_new(TYPE_XLNX_VERSAL_EFUSE_CTRL); 1419 cache = qdev_new(TYPE_XLNX_VERSAL_EFUSE_CACHE); 1420 bits = qdev_new(TYPE_XLNX_EFUSE); 1421 1422 qdev_prop_set_uint32(bits, "efuse-nr", 3); 1423 qdev_prop_set_uint32(bits, "efuse-size", 8192); 1424 1425 object_property_add_child(OBJECT(s), "efuse", OBJECT(bits)); 1426 qdev_realize_and_unref(bits, NULL, &error_abort); 1427 1428 object_property_set_link(OBJECT(ctrl), "efuse", OBJECT(bits), &error_abort); 1429 1430 object_property_set_link(OBJECT(cache), "efuse", OBJECT(bits), 1431 &error_abort); 1432 1433 object_property_add_child(OBJECT(s), "efuse-cache", OBJECT(cache)); 1434 sysbus_realize_and_unref(SYS_BUS_DEVICE(cache), &error_abort); 1435 1436 object_property_add_child(OBJECT(s), "efuse-ctrl", OBJECT(ctrl)); 1437 sysbus_realize_and_unref(SYS_BUS_DEVICE(ctrl), &error_abort); 1438 1439 memory_region_add_subregion(&s->mr_ps, map->ctrl, 1440 sysbus_mmio_get_region(SYS_BUS_DEVICE(ctrl), 1441 0)); 1442 memory_region_add_subregion(&s->mr_ps, map->cache, 1443 sysbus_mmio_get_region(SYS_BUS_DEVICE(cache), 1444 0)); 1445 versal_sysbus_connect_irq(s, SYS_BUS_DEVICE(ctrl), 0, map->irq); 1446 } 1447 1448 static DeviceState *versal_create_pmc_iou_slcr(Versal *s, 1449 const VersalSimplePeriphMap *map) 1450 { 1451 SysBusDevice *sbd; 1452 DeviceState *dev; 1453 1454 dev = qdev_new(TYPE_XILINX_VERSAL_PMC_IOU_SLCR); 1455 object_property_add_child(OBJECT(s), "pmc-iou-slcr", OBJECT(dev)); 1456 1457 sbd = SYS_BUS_DEVICE(dev); 1458 sysbus_realize_and_unref(sbd, &error_fatal); 1459 1460 memory_region_add_subregion(&s->mr_ps, map->addr, 1461 sysbus_mmio_get_region(sbd, 0)); 1462 1463 versal_sysbus_connect_irq(s, sbd, 0, map->irq); 1464 1465 return dev; 1466 } 1467 1468 static DeviceState *versal_create_ospi(Versal *s, 1469 const struct VersalOspiMap *map) 1470 { 1471 SysBusDevice *sbd; 1472 MemoryRegion *mr_dac; 1473 DeviceState *dev, *dma_dst, *dma_src, *orgate; 1474 MemoryRegion *linear_mr = g_new(MemoryRegion, 1); 1475 1476 dev = qdev_new(TYPE_XILINX_VERSAL_OSPI); 1477 object_property_add_child(OBJECT(s), "ospi", OBJECT(dev)); 1478 1479 memory_region_init(linear_mr, OBJECT(dev), "linear-mr", map->dac_sz); 1480 1481 mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); 1482 memory_region_add_subregion(linear_mr, 0x0, mr_dac); 1483 1484 /* Create the OSPI destination DMA */ 1485 dma_dst = qdev_new(TYPE_XLNX_CSU_DMA); 1486 object_property_add_child(OBJECT(dev), "dma-dst-dev", OBJECT(dma_dst)); 1487 object_property_set_link(OBJECT(dma_dst), "dma", 1488 OBJECT(get_system_memory()), &error_abort); 1489 1490 sbd = SYS_BUS_DEVICE(dma_dst); 1491 sysbus_realize_and_unref(sbd, &error_fatal); 1492 1493 memory_region_add_subregion(&s->mr_ps, map->dma_dst, 1494 sysbus_mmio_get_region(sbd, 0)); 1495 1496 /* Create the OSPI source DMA */ 1497 dma_src = qdev_new(TYPE_XLNX_CSU_DMA); 1498 object_property_add_child(OBJECT(dev), "dma-src-dev", OBJECT(dma_src)); 1499 1500 object_property_set_bool(OBJECT(dma_src), "is-dst", false, &error_abort); 1501 1502 object_property_set_link(OBJECT(dma_src), "dma", OBJECT(mr_dac), 1503 &error_abort); 1504 1505 object_property_set_link(OBJECT(dma_src), "stream-connected-dma", 1506 OBJECT(dma_dst), &error_abort); 1507 1508 sbd = SYS_BUS_DEVICE(dma_src); 1509 sysbus_realize_and_unref(sbd, &error_fatal); 1510 1511 memory_region_add_subregion(&s->mr_ps, map->dma_src, 1512 sysbus_mmio_get_region(sbd, 0)); 1513 1514 /* Realize the OSPI */ 1515 object_property_set_link(OBJECT(dev), "dma-src", 1516 OBJECT(dma_src), &error_abort); 1517 1518 sbd = SYS_BUS_DEVICE(dev); 1519 sysbus_realize_and_unref(sbd, &error_fatal); 1520 1521 memory_region_add_subregion(&s->mr_ps, map->ctrl, 1522 sysbus_mmio_get_region(sbd, 0)); 1523 1524 memory_region_add_subregion(&s->mr_ps, map->dac, 1525 linear_mr); 1526 1527 /* OSPI irq */ 1528 orgate = create_or_gate(s, OBJECT(dev), "irq-orgate", 3, 1529 map->irq); 1530 1531 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(orgate, 0)); 1532 sysbus_connect_irq(SYS_BUS_DEVICE(dma_src), 0, qdev_get_gpio_in(orgate, 1)); 1533 sysbus_connect_irq(SYS_BUS_DEVICE(dma_dst), 0, qdev_get_gpio_in(orgate, 2)); 1534 1535 return dev; 1536 } 1537 1538 static void versal_create_cfu(Versal *s, const struct VersalCfuMap *map) 1539 { 1540 SysBusDevice *sbd; 1541 Object *container; 1542 DeviceState *cfu_fdro, *cfu_apb, *cfu_sfr, *cframe_bcast; 1543 DeviceState *cframe_irq_or; 1544 int i; 1545 1546 container = object_new(TYPE_CONTAINER); 1547 object_property_add_child(OBJECT(s), "cfu", container); 1548 object_unref(container); 1549 1550 /* CFU FDRO */ 1551 cfu_fdro = qdev_new(TYPE_XLNX_VERSAL_CFU_FDRO); 1552 object_property_add_child(container, "cfu-fdro", OBJECT(cfu_fdro)); 1553 sbd = SYS_BUS_DEVICE(cfu_fdro); 1554 1555 sysbus_realize_and_unref(sbd, &error_fatal); 1556 memory_region_add_subregion(&s->mr_ps, map->cfu_fdro, 1557 sysbus_mmio_get_region(sbd, 0)); 1558 1559 /* cframe bcast */ 1560 cframe_bcast = qdev_new(TYPE_XLNX_VERSAL_CFRAME_BCAST_REG); 1561 object_property_add_child(container, "cframe-bcast", OBJECT(cframe_bcast)); 1562 1563 /* CFU APB */ 1564 cfu_apb = qdev_new(TYPE_XLNX_VERSAL_CFU_APB); 1565 object_property_add_child(container, "cfu-apb", OBJECT(cfu_apb)); 1566 1567 /* IRQ or gate for cframes */ 1568 cframe_irq_or = qdev_new(TYPE_OR_IRQ); 1569 object_property_add_child(container, "cframe-irq-or-gate", 1570 OBJECT(cframe_irq_or)); 1571 qdev_prop_set_uint16(cframe_irq_or, "num-lines", map->num_cframe); 1572 qdev_realize_and_unref(cframe_irq_or, NULL, &error_abort); 1573 versal_qdev_connect_gpio_out(s, cframe_irq_or, 0, map->cframe_irq); 1574 1575 /* cframe reg */ 1576 for (i = 0; i < map->num_cframe; i++) { 1577 uint64_t reg_base; 1578 uint64_t fdri_base; 1579 DeviceState *dev; 1580 g_autofree char *prop_name; 1581 size_t j; 1582 1583 dev = qdev_new(TYPE_XLNX_VERSAL_CFRAME_REG); 1584 object_property_add_child(container, "cframe[*]", OBJECT(dev)); 1585 1586 sbd = SYS_BUS_DEVICE(dev); 1587 1588 for (j = 0; j < ARRAY_SIZE(map->cframe_cfg[i].blktype_frames); j++) { 1589 g_autofree char *blktype_prop_name; 1590 1591 blktype_prop_name = g_strdup_printf("blktype%zu-frames", j); 1592 object_property_set_int(OBJECT(dev), blktype_prop_name, 1593 map->cframe_cfg[i].blktype_frames[j], 1594 &error_abort); 1595 } 1596 1597 object_property_set_link(OBJECT(dev), "cfu-fdro", 1598 OBJECT(cfu_fdro), &error_abort); 1599 1600 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_abort); 1601 1602 reg_base = map->cframe_base + i * map->cframe_stride * 2; 1603 fdri_base = reg_base + map->cframe_stride; 1604 memory_region_add_subregion(&s->mr_ps, reg_base, 1605 sysbus_mmio_get_region(sbd, 0)); 1606 memory_region_add_subregion(&s->mr_ps, fdri_base, 1607 sysbus_mmio_get_region(sbd, 1)); 1608 sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(cframe_irq_or, i)); 1609 1610 prop_name = g_strdup_printf("cframe%d", i); 1611 object_property_set_link(OBJECT(cframe_bcast), prop_name, 1612 OBJECT(dev), &error_abort); 1613 object_property_set_link(OBJECT(cfu_apb), prop_name, 1614 OBJECT(dev), &error_abort); 1615 } 1616 1617 sbd = SYS_BUS_DEVICE(cframe_bcast); 1618 sysbus_realize_and_unref(sbd, &error_abort); 1619 memory_region_add_subregion(&s->mr_ps, map->cframe_bcast_reg, 1620 sysbus_mmio_get_region(sbd, 0)); 1621 memory_region_add_subregion(&s->mr_ps, map->cframe_bcast_fdri, 1622 sysbus_mmio_get_region(sbd, 1)); 1623 1624 sbd = SYS_BUS_DEVICE(cfu_apb); 1625 sysbus_realize_and_unref(sbd, &error_fatal); 1626 memory_region_add_subregion(&s->mr_ps, map->cfu_apb, 1627 sysbus_mmio_get_region(sbd, 0)); 1628 memory_region_add_subregion(&s->mr_ps, map->cfu_stream, 1629 sysbus_mmio_get_region(sbd, 1)); 1630 memory_region_add_subregion(&s->mr_ps, map->cfu_stream_2, 1631 sysbus_mmio_get_region(sbd, 2)); 1632 versal_sysbus_connect_irq(s, sbd, 0, map->cfu_apb_irq); 1633 1634 /* CFU SFR */ 1635 cfu_sfr = qdev_new(TYPE_XLNX_VERSAL_CFU_SFR); 1636 object_property_add_child(container, "cfu-sfr", OBJECT(cfu_sfr)); 1637 sbd = SYS_BUS_DEVICE(cfu_sfr); 1638 1639 object_property_set_link(OBJECT(cfu_sfr), 1640 "cfu", OBJECT(cfu_apb), &error_abort); 1641 sysbus_realize_and_unref(sbd, &error_fatal); 1642 memory_region_add_subregion(&s->mr_ps, map->cfu_sfr, 1643 sysbus_mmio_get_region(sbd, 0)); 1644 } 1645 1646 static inline void crl_connect_dev(Object *crl, Object *dev) 1647 { 1648 const char *prop = object_get_canonical_path_component(dev); 1649 1650 /* The component part of the device path matches the CRL property name */ 1651 object_property_set_link(crl, prop, dev, &error_abort); 1652 } 1653 1654 static inline void crl_connect_dev_by_name(Versal *s, Object *crl, 1655 const char *name, size_t num) 1656 { 1657 size_t i; 1658 1659 for (i = 0; i < num; i++) { 1660 Object *dev = versal_get_child_idx(s, name, i); 1661 1662 crl_connect_dev(crl, dev); 1663 } 1664 } 1665 1666 static inline void versal_create_crl(Versal *s) 1667 { 1668 const VersalMap *map; 1669 VersalVersion ver; 1670 const char *crl_class; 1671 DeviceState *dev; 1672 size_t num_gem; 1673 Object *obj; 1674 1675 map = versal_get_map(s); 1676 ver = versal_get_version(s); 1677 1678 crl_class = xlnx_versal_crl_class_name(ver); 1679 dev = qdev_new(crl_class); 1680 obj = OBJECT(dev); 1681 object_property_add_child(OBJECT(s), "crl", obj); 1682 1683 /* 1684 * The 3rd GEM controller on versal2 is in the MMI subsystem. 1685 * Its reset line is not connected to the CRL. Consider only the first two 1686 * ones. 1687 */ 1688 num_gem = ver == VERSAL_VER_VERSAL2 ? 2 : map->num_gem; 1689 1690 crl_connect_dev_by_name(s, obj, "rpu-cluster/rpu", 1691 map->rpu.num_cluster * map->rpu.num_core); 1692 crl_connect_dev_by_name(s, obj, map->zdma[0].name, map->zdma[0].num_chan); 1693 crl_connect_dev_by_name(s, obj, "uart", map->num_uart); 1694 crl_connect_dev_by_name(s, obj, "gem", num_gem); 1695 crl_connect_dev_by_name(s, obj, "usb", map->num_usb); 1696 1697 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_abort); 1698 1699 memory_region_add_subregion(&s->mr_ps, map->crl.addr, 1700 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0)); 1701 1702 if (ver == VERSAL_VER_VERSAL) { 1703 /* CRL IRQ line has been removed in versal2 */ 1704 versal_sysbus_connect_irq(s, SYS_BUS_DEVICE(dev), 0, map->crl.irq); 1705 } 1706 } 1707 1708 /* 1709 * This takes the board allocated linear DDR memory and creates aliases 1710 * for each split DDR range/aperture on the Versal address map. 1711 */ 1712 static void versal_map_ddr(Versal *s, const struct VersalDDRMap *map) 1713 { 1714 uint64_t size = memory_region_size(s->cfg.mr_ddr); 1715 uint64_t offset = 0; 1716 int i; 1717 1718 for (i = 0; i < map->num_chan && size; i++) { 1719 uint64_t mapsize; 1720 MemoryRegion *alias; 1721 1722 mapsize = MIN(size, map->chan[i].size); 1723 1724 /* Create the MR alias. */ 1725 alias = g_new(MemoryRegion, 1); 1726 memory_region_init_alias(alias, OBJECT(s), "noc-ddr-range", 1727 s->cfg.mr_ddr, offset, mapsize); 1728 1729 /* Map it onto the NoC MR. */ 1730 memory_region_add_subregion(&s->mr_ps, map->chan[i].addr, alias); 1731 offset += mapsize; 1732 size -= mapsize; 1733 } 1734 } 1735 1736 void versal_fdt_add_memory_nodes(Versal *s, uint64_t size) 1737 { 1738 const struct VersalDDRMap *map = &versal_get_map(s)->ddr; 1739 g_autofree char *node; 1740 g_autofree uint64_t *reg; 1741 int i; 1742 1743 reg = g_new(uint64_t, map->num_chan * 2); 1744 1745 for (i = 0; i < map->num_chan && size; i++) { 1746 uint64_t mapsize; 1747 1748 mapsize = MIN(size, map->chan[i].size); 1749 1750 reg[i * 2] = cpu_to_be64(map->chan[i].addr); 1751 reg[i * 2 + 1] = cpu_to_be64(mapsize); 1752 1753 size -= mapsize; 1754 } 1755 1756 node = versal_fdt_add_subnode(s, "/memory", 0, "memory", sizeof("memory")); 1757 qemu_fdt_setprop(s->cfg.fdt, node, "reg", reg, sizeof(uint64_t) * i * 2); 1758 } 1759 1760 static void versal_unimp_area(Versal *s, const char *name, 1761 MemoryRegion *mr, 1762 hwaddr base, hwaddr size) 1763 { 1764 DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE); 1765 MemoryRegion *mr_dev; 1766 1767 qdev_prop_set_string(dev, "name", name); 1768 qdev_prop_set_uint64(dev, "size", size); 1769 object_property_add_child(OBJECT(s), name, OBJECT(dev)); 1770 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 1771 1772 mr_dev = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 1773 memory_region_add_subregion(mr, base, mr_dev); 1774 } 1775 1776 static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level) 1777 { 1778 qemu_log_mask(LOG_UNIMP, 1779 "Selecting between enabling SD mode or eMMC mode on " 1780 "controller %d is not yet implemented\n", n); 1781 } 1782 1783 static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level) 1784 { 1785 qemu_log_mask(LOG_UNIMP, 1786 "Selecting between enabling the QSPI or OSPI linear address " 1787 "region is not yet implemented\n"); 1788 } 1789 1790 static void versal_unimp_irq_parity_imr(void *opaque, int n, int level) 1791 { 1792 qemu_log_mask(LOG_UNIMP, 1793 "PMC SLCR parity interrupt behaviour " 1794 "is not yet implemented\n"); 1795 } 1796 1797 static void versal_unimp_common(Versal *s) 1798 { 1799 DeviceState *slcr; 1800 qemu_irq gpio_in; 1801 1802 versal_unimp_area(s, "crp", &s->mr_ps, 0xf1260000, 0x10000); 1803 1804 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel, 1805 "sd-emmc-sel-dummy", 2); 1806 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel, 1807 "qspi-ospi-mux-sel-dummy", 1); 1808 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr, 1809 "irq-parity-imr-dummy", 1); 1810 1811 slcr = DEVICE(versal_get_child(s, "pmc-iou-slcr")); 1812 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0); 1813 qdev_connect_gpio_out_named(slcr, "sd-emmc-sel", 0, gpio_in); 1814 1815 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1); 1816 qdev_connect_gpio_out_named(slcr, "sd-emmc-sel", 1, gpio_in); 1817 1818 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 0); 1819 qdev_connect_gpio_out_named(slcr, "qspi-ospi-mux-sel", 0, gpio_in); 1820 1821 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0); 1822 qdev_connect_gpio_out_named(slcr, SYSBUS_DEVICE_GPIO_IRQ, 0, gpio_in); 1823 } 1824 1825 static void versal_unimp(Versal *s) 1826 { 1827 versal_unimp_area(s, "psm", &s->mr_ps, 0xffc80000, 0x70000); 1828 versal_unimp_area(s, "crf", &s->mr_ps, 0xfd1a0000, 0x140000); 1829 versal_unimp_area(s, "apu", &s->mr_ps, 0xfd5c0000, 0x100); 1830 versal_unimp_area(s, "iou-scntr", &s->mr_ps, 0xff130000, 0x10000); 1831 versal_unimp_area(s, "iou-scntr-secure", &s->mr_ps, 0xff140000, 0x10000); 1832 1833 versal_unimp_common(s); 1834 } 1835 1836 static void versal2_unimp(Versal *s) 1837 { 1838 versal_unimp_area(s, "fpd-systmr-ctrl", &s->mr_ps, 0xec920000, 0x1000); 1839 versal_unimp_area(s, "crf", &s->mr_ps, 0xec200000, 0x100000); 1840 1841 versal_unimp_common(s); 1842 } 1843 1844 static uint32_t fdt_add_clk_node(Versal *s, const char *name, 1845 unsigned int freq_hz) 1846 { 1847 uint32_t phandle; 1848 1849 phandle = qemu_fdt_alloc_phandle(s->cfg.fdt); 1850 1851 qemu_fdt_add_subnode(s->cfg.fdt, name); 1852 qemu_fdt_setprop_cell(s->cfg.fdt, name, "phandle", phandle); 1853 qemu_fdt_setprop_cell(s->cfg.fdt, name, "clock-frequency", freq_hz); 1854 qemu_fdt_setprop_cell(s->cfg.fdt, name, "#clock-cells", 0x0); 1855 qemu_fdt_setprop_string(s->cfg.fdt, name, "compatible", "fixed-clock"); 1856 qemu_fdt_setprop(s->cfg.fdt, name, "u-boot,dm-pre-reloc", NULL, 0); 1857 1858 return phandle; 1859 } 1860 1861 static void versal_realize_common(Versal *s) 1862 { 1863 DeviceState *slcr, *ospi; 1864 MemoryRegion *ocm; 1865 Object *container; 1866 const VersalMap *map = versal_get_map(s); 1867 size_t i; 1868 1869 g_assert(s->cfg.fdt != NULL); 1870 1871 s->phandle.clk_25mhz = fdt_add_clk_node(s, "/clk25", 25 * 1000 * 1000); 1872 s->phandle.clk_125mhz = fdt_add_clk_node(s, "/clk125", 125 * 1000 * 1000); 1873 s->phandle.gic = qemu_fdt_alloc_phandle(s->cfg.fdt); 1874 1875 container = object_new(TYPE_CONTAINER); 1876 object_property_add_child(OBJECT(s), "irq-splits", container); 1877 object_unref(container); 1878 1879 container = object_new(TYPE_CONTAINER); 1880 object_property_add_child(OBJECT(s), "irq-or-gates", container); 1881 object_unref(container); 1882 1883 qemu_fdt_setprop_cell(s->cfg.fdt, "/", "interrupt-parent", s->phandle.gic); 1884 qemu_fdt_setprop_cell(s->cfg.fdt, "/", "#size-cells", 0x2); 1885 qemu_fdt_setprop_cell(s->cfg.fdt, "/", "#address-cells", 0x2); 1886 1887 versal_create_cpu_cluster(s, &map->apu); 1888 versal_create_cpu_cluster(s, &map->rpu); 1889 1890 for (i = 0; i < map->num_uart; i++) { 1891 versal_create_uart(s, &map->uart[i], i); 1892 } 1893 1894 for (i = 0; i < map->num_canfd; i++) { 1895 versal_create_canfd(s, &map->canfd[i], s->cfg.canbus[i]); 1896 } 1897 1898 for (i = 0; i < map->num_sdhci; i++) { 1899 versal_create_sdhci(s, &map->sdhci[i]); 1900 } 1901 1902 for (i = 0; i < map->num_gem; i++) { 1903 versal_create_gem(s, &map->gem[i]); 1904 /* 1905 * Create fdt node in reverse order to keep backward compatibility with 1906 * previous versions of the generated FDT. This affects Linux kernel 1907 * interface naming order when persistent naming scheme is not in use. 1908 */ 1909 versal_create_gem_fdt(s, &map->gem[map->num_gem - 1 - i]); 1910 } 1911 1912 for (i = 0; i < map->num_zdma; i++) { 1913 versal_create_zdma(s, &map->zdma[i]); 1914 } 1915 1916 versal_create_xrams(s, &map->xram); 1917 1918 for (i = 0; i < map->num_usb; i++) { 1919 versal_create_usb(s, &map->usb[i]); 1920 } 1921 1922 versal_create_efuse(s, &map->efuse); 1923 ospi = versal_create_ospi(s, &map->ospi); 1924 slcr = versal_create_pmc_iou_slcr(s, &map->pmc_iou_slcr); 1925 1926 qdev_connect_gpio_out_named(slcr, "ospi-mux-sel", 0, 1927 qdev_get_gpio_in_named(ospi, 1928 "ospi-mux-sel", 0)); 1929 1930 versal_create_bbram(s, &map->bbram); 1931 versal_create_trng(s, &map->trng); 1932 versal_create_rtc(s, &map->rtc); 1933 versal_create_cfu(s, &map->cfu); 1934 versal_create_crl(s); 1935 1936 versal_map_ddr(s, &map->ddr); 1937 1938 /* Create the On Chip Memory (OCM). */ 1939 ocm = g_new(MemoryRegion, 1); 1940 memory_region_init_ram(ocm, OBJECT(s), "ocm", map->ocm.size, &error_fatal); 1941 memory_region_add_subregion_overlap(&s->mr_ps, map->ocm.addr, ocm, 0); 1942 } 1943 1944 static void versal_realize(DeviceState *dev, Error **errp) 1945 { 1946 Versal *s = XLNX_VERSAL_BASE(dev); 1947 1948 versal_realize_common(s); 1949 versal_unimp(s); 1950 } 1951 1952 static void versal2_realize(DeviceState *dev, Error **errp) 1953 { 1954 Versal *s = XLNX_VERSAL_BASE(dev); 1955 1956 versal_realize_common(s); 1957 versal2_unimp(s); 1958 } 1959 1960 DeviceState *versal_get_boot_cpu(Versal *s) 1961 { 1962 return DEVICE(versal_get_child_idx(s, "apu-cluster/apu", 0)); 1963 } 1964 1965 void versal_sdhci_plug_card(Versal *s, int sd_idx, BlockBackend *blk) 1966 { 1967 DeviceState *sdhci, *card; 1968 1969 sdhci = DEVICE(versal_get_child_idx(s, "sdhci", sd_idx)); 1970 1971 if (sdhci == NULL) { 1972 return; 1973 } 1974 1975 card = qdev_new(TYPE_SD_CARD); 1976 object_property_add_child(OBJECT(sdhci), "card[*]", OBJECT(card)); 1977 qdev_prop_set_drive_err(card, "drive", blk, &error_fatal); 1978 qdev_realize_and_unref(card, qdev_get_child_bus(DEVICE(sdhci), "sd-bus"), 1979 &error_fatal); 1980 } 1981 1982 void versal_efuse_attach_drive(Versal *s, BlockBackend *blk) 1983 { 1984 DeviceState *efuse; 1985 1986 efuse = DEVICE(versal_get_child(s, "efuse")); 1987 1988 if (efuse == NULL) { 1989 return; 1990 } 1991 1992 qdev_prop_set_drive(efuse, "drive", blk); 1993 } 1994 1995 void versal_bbram_attach_drive(Versal *s, BlockBackend *blk) 1996 { 1997 DeviceState *bbram; 1998 1999 bbram = DEVICE(versal_get_child(s, "bbram")); 2000 2001 if (bbram == NULL) { 2002 return; 2003 } 2004 2005 qdev_prop_set_drive(bbram, "drive", blk); 2006 } 2007 2008 void versal_ospi_create_flash(Versal *s, int flash_idx, const char *flash_mdl, 2009 BlockBackend *blk) 2010 { 2011 BusState *spi_bus; 2012 DeviceState *flash, *ospi; 2013 qemu_irq cs_line; 2014 2015 ospi = DEVICE(versal_get_child(s, "ospi")); 2016 spi_bus = qdev_get_child_bus(ospi, "spi0"); 2017 2018 flash = qdev_new(flash_mdl); 2019 2020 if (blk) { 2021 qdev_prop_set_drive_err(flash, "drive", blk, &error_fatal); 2022 } 2023 qdev_prop_set_uint8(flash, "cs", flash_idx); 2024 qdev_realize_and_unref(flash, spi_bus, &error_fatal); 2025 2026 cs_line = qdev_get_gpio_in_named(flash, SSI_GPIO_CS, 0); 2027 2028 sysbus_connect_irq(SYS_BUS_DEVICE(ospi), 2029 flash_idx + 1, cs_line); 2030 } 2031 2032 qemu_irq versal_get_reserved_irq(Versal *s, int idx, int *dtb_idx) 2033 { 2034 const VersalMap *map = versal_get_map(s); 2035 2036 g_assert(idx < map->reserved.irq_num); 2037 2038 *dtb_idx = map->reserved.irq_start + idx; 2039 return versal_get_irq(s, *dtb_idx); 2040 } 2041 2042 hwaddr versal_get_reserved_mmio_addr(Versal *s) 2043 { 2044 const VersalMap *map = versal_get_map(s); 2045 2046 return map->reserved.mmio_start; 2047 } 2048 2049 int versal_get_num_cpu(VersalVersion version) 2050 { 2051 const VersalMap *map = VERSION_TO_MAP[version]; 2052 2053 return map->apu.num_cluster * map->apu.num_core 2054 + map->rpu.num_cluster * map->rpu.num_core; 2055 } 2056 2057 int versal_get_num_can(VersalVersion version) 2058 { 2059 const VersalMap *map = VERSION_TO_MAP[version]; 2060 2061 return map->num_canfd; 2062 } 2063 2064 int versal_get_num_sdhci(VersalVersion version) 2065 { 2066 const VersalMap *map = VERSION_TO_MAP[version]; 2067 2068 return map->num_sdhci; 2069 } 2070 2071 static void versal_base_init(Object *obj) 2072 { 2073 Versal *s = XLNX_VERSAL_BASE(obj); 2074 size_t i, num_can; 2075 2076 memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX); 2077 s->intc = g_array_new(false, false, sizeof(DeviceState *)); 2078 2079 num_can = versal_get_map(s)->num_canfd; 2080 s->cfg.canbus = g_new0(CanBusState *, num_can); 2081 2082 for (i = 0; i < num_can; i++) { 2083 g_autofree char *prop_name = g_strdup_printf("canbus%zu", i); 2084 2085 object_property_add_link(obj, prop_name, TYPE_CAN_BUS, 2086 (Object **) &s->cfg.canbus[i], 2087 object_property_allow_set_link, 0); 2088 } 2089 } 2090 2091 static void versal_base_finalize(Object *obj) 2092 { 2093 Versal *s = XLNX_VERSAL_BASE(obj); 2094 2095 g_array_free(s->intc, true); 2096 g_free(s->cfg.canbus); 2097 } 2098 2099 static const Property versal_properties[] = { 2100 DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION, 2101 MemoryRegion *), 2102 }; 2103 2104 static void versal_base_class_init(ObjectClass *klass, const void *data) 2105 { 2106 DeviceClass *dc = DEVICE_CLASS(klass); 2107 2108 device_class_set_props(dc, versal_properties); 2109 /* No VMSD since we haven't got any top-level SoC state to save. */ 2110 } 2111 2112 static void versal_class_init(ObjectClass *klass, const void *data) 2113 { 2114 VersalClass *vc = XLNX_VERSAL_BASE_CLASS(klass); 2115 DeviceClass *dc = DEVICE_CLASS(klass); 2116 2117 vc->version = VERSAL_VER_VERSAL; 2118 dc->realize = versal_realize; 2119 } 2120 2121 static void versal2_class_init(ObjectClass *klass, const void *data) 2122 { 2123 VersalClass *vc = XLNX_VERSAL_BASE_CLASS(klass); 2124 DeviceClass *dc = DEVICE_CLASS(klass); 2125 2126 vc->version = VERSAL_VER_VERSAL2; 2127 dc->realize = versal2_realize; 2128 } 2129 2130 static const TypeInfo versal_base_info = { 2131 .name = TYPE_XLNX_VERSAL_BASE, 2132 .parent = TYPE_SYS_BUS_DEVICE, 2133 .instance_size = sizeof(Versal), 2134 .instance_init = versal_base_init, 2135 .instance_finalize = versal_base_finalize, 2136 .class_init = versal_base_class_init, 2137 .class_size = sizeof(VersalClass), 2138 .abstract = true, 2139 }; 2140 2141 static const TypeInfo versal_info = { 2142 .name = TYPE_XLNX_VERSAL, 2143 .parent = TYPE_XLNX_VERSAL_BASE, 2144 .class_init = versal_class_init, 2145 }; 2146 2147 static const TypeInfo versal2_info = { 2148 .name = TYPE_XLNX_VERSAL2, 2149 .parent = TYPE_XLNX_VERSAL_BASE, 2150 .class_init = versal2_class_init, 2151 }; 2152 2153 static void versal_register_types(void) 2154 { 2155 type_register_static(&versal_base_info); 2156 type_register_static(&versal_info); 2157 type_register_static(&versal2_info); 2158 } 2159 2160 type_init(versal_register_types); 2161