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 #include "hw/sysbus.h" 26 27 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72") 28 #define GEM_REVISION 0x40070106 29 30 #define VERSAL_NUM_PMC_APB_IRQS 3 31 #define NUM_OSPI_IRQ_LINES 3 32 33 static void versal_create_apu_cpus(Versal *s) 34 { 35 int i; 36 37 for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) { 38 Object *obj; 39 40 object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i], 41 XLNX_VERSAL_ACPU_TYPE); 42 obj = OBJECT(&s->fpd.apu.cpu[i]); 43 object_property_set_int(obj, "psci-conduit", s->cfg.psci_conduit, 44 &error_abort); 45 if (i) { 46 /* Secondary CPUs start in PSCI powered-down state */ 47 object_property_set_bool(obj, "start-powered-off", true, 48 &error_abort); 49 } 50 51 object_property_set_int(obj, "core-count", ARRAY_SIZE(s->fpd.apu.cpu), 52 &error_abort); 53 object_property_set_link(obj, "memory", OBJECT(&s->fpd.apu.mr), 54 &error_abort); 55 qdev_realize(DEVICE(obj), NULL, &error_fatal); 56 } 57 } 58 59 static void versal_create_apu_gic(Versal *s, qemu_irq *pic) 60 { 61 static const uint64_t addrs[] = { 62 MM_GIC_APU_DIST_MAIN, 63 MM_GIC_APU_REDIST_0 64 }; 65 SysBusDevice *gicbusdev; 66 DeviceState *gicdev; 67 int nr_apu_cpus = ARRAY_SIZE(s->fpd.apu.cpu); 68 int i; 69 70 object_initialize_child(OBJECT(s), "apu-gic", &s->fpd.apu.gic, 71 gicv3_class_name()); 72 gicbusdev = SYS_BUS_DEVICE(&s->fpd.apu.gic); 73 gicdev = DEVICE(&s->fpd.apu.gic); 74 qdev_prop_set_uint32(gicdev, "revision", 3); 75 qdev_prop_set_uint32(gicdev, "num-cpu", nr_apu_cpus); 76 qdev_prop_set_uint32(gicdev, "num-irq", XLNX_VERSAL_NR_IRQS + 32); 77 qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1); 78 qdev_prop_set_uint32(gicdev, "redist-region-count[0]", nr_apu_cpus); 79 qdev_prop_set_bit(gicdev, "has-security-extensions", true); 80 81 sysbus_realize(SYS_BUS_DEVICE(&s->fpd.apu.gic), &error_fatal); 82 83 for (i = 0; i < ARRAY_SIZE(addrs); i++) { 84 MemoryRegion *mr; 85 86 mr = sysbus_mmio_get_region(gicbusdev, i); 87 memory_region_add_subregion(&s->fpd.apu.mr, addrs[i], mr); 88 } 89 90 for (i = 0; i < nr_apu_cpus; i++) { 91 DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]); 92 int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS; 93 qemu_irq maint_irq; 94 int ti; 95 /* Mapping from the output timer irq lines from the CPU to the 96 * GIC PPI inputs. 97 */ 98 const int timer_irq[] = { 99 [GTIMER_PHYS] = VERSAL_TIMER_NS_EL1_IRQ, 100 [GTIMER_VIRT] = VERSAL_TIMER_VIRT_IRQ, 101 [GTIMER_HYP] = VERSAL_TIMER_NS_EL2_IRQ, 102 [GTIMER_SEC] = VERSAL_TIMER_S_EL1_IRQ, 103 }; 104 105 for (ti = 0; ti < ARRAY_SIZE(timer_irq); ti++) { 106 qdev_connect_gpio_out(cpudev, ti, 107 qdev_get_gpio_in(gicdev, 108 ppibase + timer_irq[ti])); 109 } 110 maint_irq = qdev_get_gpio_in(gicdev, 111 ppibase + VERSAL_GIC_MAINT_IRQ); 112 qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 113 0, maint_irq); 114 sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); 115 sysbus_connect_irq(gicbusdev, i + nr_apu_cpus, 116 qdev_get_gpio_in(cpudev, ARM_CPU_FIQ)); 117 sysbus_connect_irq(gicbusdev, i + 2 * nr_apu_cpus, 118 qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ)); 119 sysbus_connect_irq(gicbusdev, i + 3 * nr_apu_cpus, 120 qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); 121 } 122 123 for (i = 0; i < XLNX_VERSAL_NR_IRQS; i++) { 124 pic[i] = qdev_get_gpio_in(gicdev, i); 125 } 126 } 127 128 static void versal_create_uarts(Versal *s, qemu_irq *pic) 129 { 130 int i; 131 132 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) { 133 static const int irqs[] = { VERSAL_UART0_IRQ_0, VERSAL_UART1_IRQ_0}; 134 static const uint64_t addrs[] = { MM_UART0, MM_UART1 }; 135 char *name = g_strdup_printf("uart%d", i); 136 DeviceState *dev; 137 MemoryRegion *mr; 138 139 object_initialize_child(OBJECT(s), name, &s->lpd.iou.uart[i], 140 TYPE_PL011); 141 dev = DEVICE(&s->lpd.iou.uart[i]); 142 qdev_prop_set_chr(dev, "chardev", serial_hd(i)); 143 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 144 145 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 146 memory_region_add_subregion(&s->mr_ps, addrs[i], mr); 147 148 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]); 149 g_free(name); 150 } 151 } 152 153 static void versal_create_usbs(Versal *s, qemu_irq *pic) 154 { 155 DeviceState *dev; 156 MemoryRegion *mr; 157 158 object_initialize_child(OBJECT(s), "usb2", &s->lpd.iou.usb, 159 TYPE_XILINX_VERSAL_USB2); 160 dev = DEVICE(&s->lpd.iou.usb); 161 162 object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps), 163 &error_abort); 164 qdev_prop_set_uint32(dev, "intrs", 1); 165 qdev_prop_set_uint32(dev, "slots", 2); 166 167 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 168 169 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 170 memory_region_add_subregion(&s->mr_ps, MM_USB_0, mr); 171 172 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_USB0_IRQ_0]); 173 174 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); 175 memory_region_add_subregion(&s->mr_ps, MM_USB2_CTRL_REGS, mr); 176 } 177 178 static void versal_create_gems(Versal *s, qemu_irq *pic) 179 { 180 int i; 181 182 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) { 183 static const int irqs[] = { VERSAL_GEM0_IRQ_0, VERSAL_GEM1_IRQ_0}; 184 static const uint64_t addrs[] = { MM_GEM0, MM_GEM1 }; 185 char *name = g_strdup_printf("gem%d", i); 186 NICInfo *nd = &nd_table[i]; 187 DeviceState *dev; 188 MemoryRegion *mr; 189 190 object_initialize_child(OBJECT(s), name, &s->lpd.iou.gem[i], 191 TYPE_CADENCE_GEM); 192 dev = DEVICE(&s->lpd.iou.gem[i]); 193 /* FIXME use qdev NIC properties instead of nd_table[] */ 194 if (nd->used) { 195 qemu_check_nic_model(nd, "cadence_gem"); 196 qdev_set_nic_properties(dev, nd); 197 } 198 object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort); 199 object_property_set_int(OBJECT(dev), "num-priority-queues", 2, 200 &error_abort); 201 object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps), 202 &error_abort); 203 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 204 205 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 206 memory_region_add_subregion(&s->mr_ps, addrs[i], mr); 207 208 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]); 209 g_free(name); 210 } 211 } 212 213 static void versal_create_admas(Versal *s, qemu_irq *pic) 214 { 215 int i; 216 217 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) { 218 char *name = g_strdup_printf("adma%d", i); 219 DeviceState *dev; 220 MemoryRegion *mr; 221 222 object_initialize_child(OBJECT(s), name, &s->lpd.iou.adma[i], 223 TYPE_XLNX_ZDMA); 224 dev = DEVICE(&s->lpd.iou.adma[i]); 225 object_property_set_int(OBJECT(dev), "bus-width", 128, &error_abort); 226 object_property_set_link(OBJECT(dev), "dma", 227 OBJECT(get_system_memory()), &error_fatal); 228 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 229 230 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 231 memory_region_add_subregion(&s->mr_ps, 232 MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr); 233 234 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]); 235 g_free(name); 236 } 237 } 238 239 #define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */ 240 static void versal_create_sds(Versal *s, qemu_irq *pic) 241 { 242 int i; 243 244 for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) { 245 DeviceState *dev; 246 MemoryRegion *mr; 247 248 object_initialize_child(OBJECT(s), "sd[*]", &s->pmc.iou.sd[i], 249 TYPE_SYSBUS_SDHCI); 250 dev = DEVICE(&s->pmc.iou.sd[i]); 251 252 object_property_set_uint(OBJECT(dev), "sd-spec-version", 3, 253 &error_fatal); 254 object_property_set_uint(OBJECT(dev), "capareg", SDHCI_CAPABILITIES, 255 &error_fatal); 256 object_property_set_uint(OBJECT(dev), "uhs", UHS_I, &error_fatal); 257 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 258 259 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 260 memory_region_add_subregion(&s->mr_ps, 261 MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr); 262 263 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, 264 pic[VERSAL_SD0_IRQ_0 + i * 2]); 265 } 266 } 267 268 static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic) 269 { 270 DeviceState *orgate; 271 272 /* 273 * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following 274 * models: 275 * - RTC 276 * - BBRAM 277 * - PMC SLCR 278 */ 279 object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate", 280 &s->pmc.apb_irq_orgate, TYPE_OR_IRQ); 281 orgate = DEVICE(&s->pmc.apb_irq_orgate); 282 object_property_set_int(OBJECT(orgate), 283 "num-lines", VERSAL_NUM_PMC_APB_IRQS, &error_fatal); 284 qdev_realize(orgate, NULL, &error_fatal); 285 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]); 286 } 287 288 static void versal_create_rtc(Versal *s, qemu_irq *pic) 289 { 290 SysBusDevice *sbd; 291 MemoryRegion *mr; 292 293 object_initialize_child(OBJECT(s), "rtc", &s->pmc.rtc, 294 TYPE_XLNX_ZYNQMP_RTC); 295 sbd = SYS_BUS_DEVICE(&s->pmc.rtc); 296 sysbus_realize(SYS_BUS_DEVICE(sbd), &error_fatal); 297 298 mr = sysbus_mmio_get_region(sbd, 0); 299 memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr); 300 301 /* 302 * TODO: Connect the ALARM and SECONDS interrupts once our RTC model 303 * supports them. 304 */ 305 sysbus_connect_irq(sbd, 1, 306 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 0)); 307 } 308 309 static void versal_create_xrams(Versal *s, qemu_irq *pic) 310 { 311 int nr_xrams = ARRAY_SIZE(s->lpd.xram.ctrl); 312 DeviceState *orgate; 313 int i; 314 315 /* XRAM IRQs get ORed into a single line. */ 316 object_initialize_child(OBJECT(s), "xram-irq-orgate", 317 &s->lpd.xram.irq_orgate, TYPE_OR_IRQ); 318 orgate = DEVICE(&s->lpd.xram.irq_orgate); 319 object_property_set_int(OBJECT(orgate), 320 "num-lines", nr_xrams, &error_fatal); 321 qdev_realize(orgate, NULL, &error_fatal); 322 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_XRAM_IRQ_0]); 323 324 for (i = 0; i < ARRAY_SIZE(s->lpd.xram.ctrl); i++) { 325 SysBusDevice *sbd; 326 MemoryRegion *mr; 327 328 object_initialize_child(OBJECT(s), "xram[*]", &s->lpd.xram.ctrl[i], 329 TYPE_XLNX_XRAM_CTRL); 330 sbd = SYS_BUS_DEVICE(&s->lpd.xram.ctrl[i]); 331 sysbus_realize(sbd, &error_fatal); 332 333 mr = sysbus_mmio_get_region(sbd, 0); 334 memory_region_add_subregion(&s->mr_ps, 335 MM_XRAMC + i * MM_XRAMC_SIZE, mr); 336 mr = sysbus_mmio_get_region(sbd, 1); 337 memory_region_add_subregion(&s->mr_ps, MM_XRAM + i * MiB, mr); 338 339 sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(orgate, i)); 340 } 341 } 342 343 static void versal_create_bbram(Versal *s, qemu_irq *pic) 344 { 345 SysBusDevice *sbd; 346 347 object_initialize_child_with_props(OBJECT(s), "bbram", &s->pmc.bbram, 348 sizeof(s->pmc.bbram), TYPE_XLNX_BBRAM, 349 &error_fatal, 350 "crc-zpads", "0", 351 NULL); 352 sbd = SYS_BUS_DEVICE(&s->pmc.bbram); 353 354 sysbus_realize(sbd, &error_fatal); 355 memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL, 356 sysbus_mmio_get_region(sbd, 0)); 357 sysbus_connect_irq(sbd, 0, 358 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1)); 359 } 360 361 static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base) 362 { 363 SysBusDevice *part = SYS_BUS_DEVICE(dev); 364 365 object_property_set_link(OBJECT(part), "efuse", 366 OBJECT(&s->pmc.efuse), &error_abort); 367 368 sysbus_realize(part, &error_abort); 369 memory_region_add_subregion(&s->mr_ps, base, 370 sysbus_mmio_get_region(part, 0)); 371 } 372 373 static void versal_create_efuse(Versal *s, qemu_irq *pic) 374 { 375 Object *bits = OBJECT(&s->pmc.efuse); 376 Object *ctrl = OBJECT(&s->pmc.efuse_ctrl); 377 Object *cache = OBJECT(&s->pmc.efuse_cache); 378 379 object_initialize_child(OBJECT(s), "efuse-ctrl", &s->pmc.efuse_ctrl, 380 TYPE_XLNX_VERSAL_EFUSE_CTRL); 381 382 object_initialize_child(OBJECT(s), "efuse-cache", &s->pmc.efuse_cache, 383 TYPE_XLNX_VERSAL_EFUSE_CACHE); 384 385 object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits, 386 sizeof(s->pmc.efuse), 387 TYPE_XLNX_EFUSE, &error_abort, 388 "efuse-nr", "3", 389 "efuse-size", "8192", 390 NULL); 391 392 qdev_realize(DEVICE(bits), NULL, &error_abort); 393 versal_realize_efuse_part(s, ctrl, MM_PMC_EFUSE_CTRL); 394 versal_realize_efuse_part(s, cache, MM_PMC_EFUSE_CACHE); 395 396 sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]); 397 } 398 399 static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic) 400 { 401 SysBusDevice *sbd; 402 403 object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr, 404 TYPE_XILINX_VERSAL_PMC_IOU_SLCR); 405 406 sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr); 407 sysbus_realize(sbd, &error_fatal); 408 409 memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR, 410 sysbus_mmio_get_region(sbd, 0)); 411 412 sysbus_connect_irq(sbd, 0, 413 qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2)); 414 } 415 416 static void versal_create_ospi(Versal *s, qemu_irq *pic) 417 { 418 SysBusDevice *sbd; 419 MemoryRegion *mr_dac; 420 qemu_irq ospi_mux_sel; 421 DeviceState *orgate; 422 423 memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s), 424 "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE); 425 426 object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi, 427 TYPE_XILINX_VERSAL_OSPI); 428 429 mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1); 430 memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac); 431 432 /* Create the OSPI destination DMA */ 433 object_initialize_child(OBJECT(s), "versal-ospi-dma-dst", 434 &s->pmc.iou.ospi.dma_dst, 435 TYPE_XLNX_CSU_DMA); 436 437 object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst), 438 "dma", OBJECT(get_system_memory()), 439 &error_abort); 440 441 sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst); 442 sysbus_realize(sbd, &error_fatal); 443 444 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST, 445 sysbus_mmio_get_region(sbd, 0)); 446 447 /* Create the OSPI source DMA */ 448 object_initialize_child(OBJECT(s), "versal-ospi-dma-src", 449 &s->pmc.iou.ospi.dma_src, 450 TYPE_XLNX_CSU_DMA); 451 452 object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst", 453 false, &error_abort); 454 455 object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src), 456 "dma", OBJECT(mr_dac), &error_abort); 457 458 object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src), 459 "stream-connected-dma", 460 OBJECT(&s->pmc.iou.ospi.dma_dst), 461 &error_abort); 462 463 sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src); 464 sysbus_realize(sbd, &error_fatal); 465 466 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC, 467 sysbus_mmio_get_region(sbd, 0)); 468 469 /* Realize the OSPI */ 470 object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src", 471 OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort); 472 473 sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi); 474 sysbus_realize(sbd, &error_fatal); 475 476 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI, 477 sysbus_mmio_get_region(sbd, 0)); 478 479 memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC, 480 &s->pmc.iou.ospi.linear_mr); 481 482 /* ospi_mux_sel */ 483 ospi_mux_sel = qdev_get_gpio_in_named(DEVICE(&s->pmc.iou.ospi.ospi), 484 "ospi-mux-sel", 0); 485 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "ospi-mux-sel", 0, 486 ospi_mux_sel); 487 488 /* OSPI irq */ 489 object_initialize_child(OBJECT(s), "ospi-irq-orgate", 490 &s->pmc.iou.ospi.irq_orgate, TYPE_OR_IRQ); 491 object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq_orgate), 492 "num-lines", NUM_OSPI_IRQ_LINES, &error_fatal); 493 494 orgate = DEVICE(&s->pmc.iou.ospi.irq_orgate); 495 qdev_realize(orgate, NULL, &error_fatal); 496 497 sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0, 498 qdev_get_gpio_in(orgate, 0)); 499 sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0, 500 qdev_get_gpio_in(orgate, 1)); 501 sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0, 502 qdev_get_gpio_in(orgate, 2)); 503 504 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]); 505 } 506 507 /* This takes the board allocated linear DDR memory and creates aliases 508 * for each split DDR range/aperture on the Versal address map. 509 */ 510 static void versal_map_ddr(Versal *s) 511 { 512 uint64_t size = memory_region_size(s->cfg.mr_ddr); 513 /* Describes the various split DDR access regions. */ 514 static const struct { 515 uint64_t base; 516 uint64_t size; 517 } addr_ranges[] = { 518 { MM_TOP_DDR, MM_TOP_DDR_SIZE }, 519 { MM_TOP_DDR_2, MM_TOP_DDR_2_SIZE }, 520 { MM_TOP_DDR_3, MM_TOP_DDR_3_SIZE }, 521 { MM_TOP_DDR_4, MM_TOP_DDR_4_SIZE } 522 }; 523 uint64_t offset = 0; 524 int i; 525 526 assert(ARRAY_SIZE(addr_ranges) == ARRAY_SIZE(s->noc.mr_ddr_ranges)); 527 for (i = 0; i < ARRAY_SIZE(addr_ranges) && size; i++) { 528 char *name; 529 uint64_t mapsize; 530 531 mapsize = size < addr_ranges[i].size ? size : addr_ranges[i].size; 532 name = g_strdup_printf("noc-ddr-range%d", i); 533 /* Create the MR alias. */ 534 memory_region_init_alias(&s->noc.mr_ddr_ranges[i], OBJECT(s), 535 name, s->cfg.mr_ddr, 536 offset, mapsize); 537 538 /* Map it onto the NoC MR. */ 539 memory_region_add_subregion(&s->mr_ps, addr_ranges[i].base, 540 &s->noc.mr_ddr_ranges[i]); 541 offset += mapsize; 542 size -= mapsize; 543 g_free(name); 544 } 545 } 546 547 static void versal_unimp_area(Versal *s, const char *name, 548 MemoryRegion *mr, 549 hwaddr base, hwaddr size) 550 { 551 DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE); 552 MemoryRegion *mr_dev; 553 554 qdev_prop_set_string(dev, "name", name); 555 qdev_prop_set_uint64(dev, "size", size); 556 object_property_add_child(OBJECT(s), name, OBJECT(dev)); 557 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 558 559 mr_dev = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 560 memory_region_add_subregion(mr, base, mr_dev); 561 } 562 563 static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level) 564 { 565 qemu_log_mask(LOG_UNIMP, 566 "Selecting between enabling SD mode or eMMC mode on " 567 "controller %d is not yet implemented\n", n); 568 } 569 570 static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level) 571 { 572 qemu_log_mask(LOG_UNIMP, 573 "Selecting between enabling the QSPI or OSPI linear address " 574 "region is not yet implemented\n"); 575 } 576 577 static void versal_unimp_irq_parity_imr(void *opaque, int n, int level) 578 { 579 qemu_log_mask(LOG_UNIMP, 580 "PMC SLCR parity interrupt behaviour " 581 "is not yet implemented\n"); 582 } 583 584 static void versal_unimp(Versal *s) 585 { 586 qemu_irq gpio_in; 587 588 versal_unimp_area(s, "psm", &s->mr_ps, 589 MM_PSM_START, MM_PSM_END - MM_PSM_START); 590 versal_unimp_area(s, "crl", &s->mr_ps, 591 MM_CRL, MM_CRL_SIZE); 592 versal_unimp_area(s, "crf", &s->mr_ps, 593 MM_FPD_CRF, MM_FPD_CRF_SIZE); 594 versal_unimp_area(s, "apu", &s->mr_ps, 595 MM_FPD_FPD_APU, MM_FPD_FPD_APU_SIZE); 596 versal_unimp_area(s, "crp", &s->mr_ps, 597 MM_PMC_CRP, MM_PMC_CRP_SIZE); 598 versal_unimp_area(s, "iou-scntr", &s->mr_ps, 599 MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE); 600 versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps, 601 MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE); 602 603 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel, 604 "sd-emmc-sel-dummy", 2); 605 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel, 606 "qspi-ospi-mux-sel-dummy", 1); 607 qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr, 608 "irq-parity-imr-dummy", 1); 609 610 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0); 611 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 0, 612 gpio_in); 613 614 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1); 615 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 1, 616 gpio_in); 617 618 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 0); 619 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), 620 "qspi-ospi-mux-sel", 0, 621 gpio_in); 622 623 gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0); 624 qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), 625 SYSBUS_DEVICE_GPIO_IRQ, 0, 626 gpio_in); 627 } 628 629 static void versal_realize(DeviceState *dev, Error **errp) 630 { 631 Versal *s = XLNX_VERSAL(dev); 632 qemu_irq pic[XLNX_VERSAL_NR_IRQS]; 633 634 versal_create_apu_cpus(s); 635 versal_create_apu_gic(s, pic); 636 versal_create_uarts(s, pic); 637 versal_create_usbs(s, pic); 638 versal_create_gems(s, pic); 639 versal_create_admas(s, pic); 640 versal_create_sds(s, pic); 641 versal_create_pmc_apb_irq_orgate(s, pic); 642 versal_create_rtc(s, pic); 643 versal_create_xrams(s, pic); 644 versal_create_bbram(s, pic); 645 versal_create_efuse(s, pic); 646 versal_create_pmc_iou_slcr(s, pic); 647 versal_create_ospi(s, pic); 648 versal_map_ddr(s); 649 versal_unimp(s); 650 651 /* Create the On Chip Memory (OCM). */ 652 memory_region_init_ram(&s->lpd.mr_ocm, OBJECT(s), "ocm", 653 MM_OCM_SIZE, &error_fatal); 654 655 memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0); 656 memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0); 657 } 658 659 static void versal_init(Object *obj) 660 { 661 Versal *s = XLNX_VERSAL(obj); 662 663 memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX); 664 memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX); 665 } 666 667 static Property versal_properties[] = { 668 DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION, 669 MemoryRegion *), 670 DEFINE_PROP_UINT32("psci-conduit", Versal, cfg.psci_conduit, 0), 671 DEFINE_PROP_END_OF_LIST() 672 }; 673 674 static void versal_class_init(ObjectClass *klass, void *data) 675 { 676 DeviceClass *dc = DEVICE_CLASS(klass); 677 678 dc->realize = versal_realize; 679 device_class_set_props(dc, versal_properties); 680 /* No VMSD since we haven't got any top-level SoC state to save. */ 681 } 682 683 static const TypeInfo versal_info = { 684 .name = TYPE_XLNX_VERSAL, 685 .parent = TYPE_SYS_BUS_DEVICE, 686 .instance_size = sizeof(Versal), 687 .instance_init = versal_init, 688 .class_init = versal_class_init, 689 }; 690 691 static void versal_register_types(void) 692 { 693 type_register_static(&versal_info); 694 } 695 696 type_init(versal_register_types); 697