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