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/log.h" 16 #include "qemu/module.h" 17 #include "hw/sysbus.h" 18 #include "net/net.h" 19 #include "sysemu/sysemu.h" 20 #include "sysemu/kvm.h" 21 #include "hw/arm/boot.h" 22 #include "kvm_arm.h" 23 #include "hw/misc/unimp.h" 24 #include "hw/arm/xlnx-versal.h" 25 26 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72") 27 #define GEM_REVISION 0x40070106 28 29 static void versal_create_apu_cpus(Versal *s) 30 { 31 int i; 32 33 for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) { 34 Object *obj; 35 36 object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i], 37 XLNX_VERSAL_ACPU_TYPE); 38 obj = OBJECT(&s->fpd.apu.cpu[i]); 39 object_property_set_int(obj, "psci-conduit", s->cfg.psci_conduit, 40 &error_abort); 41 if (i) { 42 /* Secondary CPUs start in PSCI powered-down state */ 43 object_property_set_bool(obj, "start-powered-off", true, 44 &error_abort); 45 } 46 47 object_property_set_int(obj, "core-count", ARRAY_SIZE(s->fpd.apu.cpu), 48 &error_abort); 49 object_property_set_link(obj, "memory", OBJECT(&s->fpd.apu.mr), 50 &error_abort); 51 qdev_realize(DEVICE(obj), NULL, &error_fatal); 52 } 53 } 54 55 static void versal_create_apu_gic(Versal *s, qemu_irq *pic) 56 { 57 static const uint64_t addrs[] = { 58 MM_GIC_APU_DIST_MAIN, 59 MM_GIC_APU_REDIST_0 60 }; 61 SysBusDevice *gicbusdev; 62 DeviceState *gicdev; 63 int nr_apu_cpus = ARRAY_SIZE(s->fpd.apu.cpu); 64 int i; 65 66 object_initialize_child(OBJECT(s), "apu-gic", &s->fpd.apu.gic, 67 gicv3_class_name()); 68 gicbusdev = SYS_BUS_DEVICE(&s->fpd.apu.gic); 69 gicdev = DEVICE(&s->fpd.apu.gic); 70 qdev_prop_set_uint32(gicdev, "revision", 3); 71 qdev_prop_set_uint32(gicdev, "num-cpu", nr_apu_cpus); 72 qdev_prop_set_uint32(gicdev, "num-irq", XLNX_VERSAL_NR_IRQS + 32); 73 qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1); 74 qdev_prop_set_uint32(gicdev, "redist-region-count[0]", nr_apu_cpus); 75 qdev_prop_set_bit(gicdev, "has-security-extensions", true); 76 77 sysbus_realize(SYS_BUS_DEVICE(&s->fpd.apu.gic), &error_fatal); 78 79 for (i = 0; i < ARRAY_SIZE(addrs); i++) { 80 MemoryRegion *mr; 81 82 mr = sysbus_mmio_get_region(gicbusdev, i); 83 memory_region_add_subregion(&s->fpd.apu.mr, addrs[i], mr); 84 } 85 86 for (i = 0; i < nr_apu_cpus; i++) { 87 DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]); 88 int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS; 89 qemu_irq maint_irq; 90 int ti; 91 /* Mapping from the output timer irq lines from the CPU to the 92 * GIC PPI inputs. 93 */ 94 const int timer_irq[] = { 95 [GTIMER_PHYS] = VERSAL_TIMER_NS_EL1_IRQ, 96 [GTIMER_VIRT] = VERSAL_TIMER_VIRT_IRQ, 97 [GTIMER_HYP] = VERSAL_TIMER_NS_EL2_IRQ, 98 [GTIMER_SEC] = VERSAL_TIMER_S_EL1_IRQ, 99 }; 100 101 for (ti = 0; ti < ARRAY_SIZE(timer_irq); ti++) { 102 qdev_connect_gpio_out(cpudev, ti, 103 qdev_get_gpio_in(gicdev, 104 ppibase + timer_irq[ti])); 105 } 106 maint_irq = qdev_get_gpio_in(gicdev, 107 ppibase + VERSAL_GIC_MAINT_IRQ); 108 qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 109 0, maint_irq); 110 sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); 111 sysbus_connect_irq(gicbusdev, i + nr_apu_cpus, 112 qdev_get_gpio_in(cpudev, ARM_CPU_FIQ)); 113 sysbus_connect_irq(gicbusdev, i + 2 * nr_apu_cpus, 114 qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ)); 115 sysbus_connect_irq(gicbusdev, i + 3 * nr_apu_cpus, 116 qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); 117 } 118 119 for (i = 0; i < XLNX_VERSAL_NR_IRQS; i++) { 120 pic[i] = qdev_get_gpio_in(gicdev, i); 121 } 122 } 123 124 static void versal_create_uarts(Versal *s, qemu_irq *pic) 125 { 126 int i; 127 128 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) { 129 static const int irqs[] = { VERSAL_UART0_IRQ_0, VERSAL_UART1_IRQ_0}; 130 static const uint64_t addrs[] = { MM_UART0, MM_UART1 }; 131 char *name = g_strdup_printf("uart%d", i); 132 DeviceState *dev; 133 MemoryRegion *mr; 134 135 object_initialize_child(OBJECT(s), name, &s->lpd.iou.uart[i], 136 TYPE_PL011); 137 dev = DEVICE(&s->lpd.iou.uart[i]); 138 qdev_prop_set_chr(dev, "chardev", serial_hd(i)); 139 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 140 141 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 142 memory_region_add_subregion(&s->mr_ps, addrs[i], mr); 143 144 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]); 145 g_free(name); 146 } 147 } 148 149 static void versal_create_usbs(Versal *s, qemu_irq *pic) 150 { 151 DeviceState *dev; 152 MemoryRegion *mr; 153 154 object_initialize_child(OBJECT(s), "usb2", &s->lpd.iou.usb, 155 TYPE_XILINX_VERSAL_USB2); 156 dev = DEVICE(&s->lpd.iou.usb); 157 158 object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps), 159 &error_abort); 160 qdev_prop_set_uint32(dev, "intrs", 1); 161 qdev_prop_set_uint32(dev, "slots", 2); 162 163 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 164 165 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 166 memory_region_add_subregion(&s->mr_ps, MM_USB_0, mr); 167 168 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_USB0_IRQ_0]); 169 170 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); 171 memory_region_add_subregion(&s->mr_ps, MM_USB2_CTRL_REGS, mr); 172 } 173 174 static void versal_create_gems(Versal *s, qemu_irq *pic) 175 { 176 int i; 177 178 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) { 179 static const int irqs[] = { VERSAL_GEM0_IRQ_0, VERSAL_GEM1_IRQ_0}; 180 static const uint64_t addrs[] = { MM_GEM0, MM_GEM1 }; 181 char *name = g_strdup_printf("gem%d", i); 182 NICInfo *nd = &nd_table[i]; 183 DeviceState *dev; 184 MemoryRegion *mr; 185 186 object_initialize_child(OBJECT(s), name, &s->lpd.iou.gem[i], 187 TYPE_CADENCE_GEM); 188 dev = DEVICE(&s->lpd.iou.gem[i]); 189 /* FIXME use qdev NIC properties instead of nd_table[] */ 190 if (nd->used) { 191 qemu_check_nic_model(nd, "cadence_gem"); 192 qdev_set_nic_properties(dev, nd); 193 } 194 object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort); 195 object_property_set_int(OBJECT(dev), "num-priority-queues", 2, 196 &error_abort); 197 object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps), 198 &error_abort); 199 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 200 201 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 202 memory_region_add_subregion(&s->mr_ps, addrs[i], mr); 203 204 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]); 205 g_free(name); 206 } 207 } 208 209 static void versal_create_admas(Versal *s, qemu_irq *pic) 210 { 211 int i; 212 213 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) { 214 char *name = g_strdup_printf("adma%d", i); 215 DeviceState *dev; 216 MemoryRegion *mr; 217 218 object_initialize_child(OBJECT(s), name, &s->lpd.iou.adma[i], 219 TYPE_XLNX_ZDMA); 220 dev = DEVICE(&s->lpd.iou.adma[i]); 221 object_property_set_int(OBJECT(dev), "bus-width", 128, &error_abort); 222 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 223 224 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 225 memory_region_add_subregion(&s->mr_ps, 226 MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr); 227 228 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]); 229 g_free(name); 230 } 231 } 232 233 #define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */ 234 static void versal_create_sds(Versal *s, qemu_irq *pic) 235 { 236 int i; 237 238 for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) { 239 DeviceState *dev; 240 MemoryRegion *mr; 241 242 object_initialize_child(OBJECT(s), "sd[*]", &s->pmc.iou.sd[i], 243 TYPE_SYSBUS_SDHCI); 244 dev = DEVICE(&s->pmc.iou.sd[i]); 245 246 object_property_set_uint(OBJECT(dev), "sd-spec-version", 3, 247 &error_fatal); 248 object_property_set_uint(OBJECT(dev), "capareg", SDHCI_CAPABILITIES, 249 &error_fatal); 250 object_property_set_uint(OBJECT(dev), "uhs", UHS_I, &error_fatal); 251 sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal); 252 253 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 254 memory_region_add_subregion(&s->mr_ps, 255 MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr); 256 257 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, 258 pic[VERSAL_SD0_IRQ_0 + i * 2]); 259 } 260 } 261 262 static void versal_create_rtc(Versal *s, qemu_irq *pic) 263 { 264 SysBusDevice *sbd; 265 MemoryRegion *mr; 266 267 object_initialize_child(OBJECT(s), "rtc", &s->pmc.rtc, 268 TYPE_XLNX_ZYNQMP_RTC); 269 sbd = SYS_BUS_DEVICE(&s->pmc.rtc); 270 sysbus_realize(SYS_BUS_DEVICE(sbd), &error_fatal); 271 272 mr = sysbus_mmio_get_region(sbd, 0); 273 memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr); 274 275 /* 276 * TODO: Connect the ALARM and SECONDS interrupts once our RTC model 277 * supports them. 278 */ 279 sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]); 280 } 281 282 static void versal_create_xrams(Versal *s, qemu_irq *pic) 283 { 284 int nr_xrams = ARRAY_SIZE(s->lpd.xram.ctrl); 285 DeviceState *orgate; 286 int i; 287 288 /* XRAM IRQs get ORed into a single line. */ 289 object_initialize_child(OBJECT(s), "xram-irq-orgate", 290 &s->lpd.xram.irq_orgate, TYPE_OR_IRQ); 291 orgate = DEVICE(&s->lpd.xram.irq_orgate); 292 object_property_set_int(OBJECT(orgate), 293 "num-lines", nr_xrams, &error_fatal); 294 qdev_realize(orgate, NULL, &error_fatal); 295 qdev_connect_gpio_out(orgate, 0, pic[VERSAL_XRAM_IRQ_0]); 296 297 for (i = 0; i < ARRAY_SIZE(s->lpd.xram.ctrl); i++) { 298 SysBusDevice *sbd; 299 MemoryRegion *mr; 300 301 object_initialize_child(OBJECT(s), "xram[*]", &s->lpd.xram.ctrl[i], 302 TYPE_XLNX_XRAM_CTRL); 303 sbd = SYS_BUS_DEVICE(&s->lpd.xram.ctrl[i]); 304 sysbus_realize(sbd, &error_fatal); 305 306 mr = sysbus_mmio_get_region(sbd, 0); 307 memory_region_add_subregion(&s->mr_ps, 308 MM_XRAMC + i * MM_XRAMC_SIZE, mr); 309 mr = sysbus_mmio_get_region(sbd, 1); 310 memory_region_add_subregion(&s->mr_ps, MM_XRAM + i * MiB, mr); 311 312 sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(orgate, i)); 313 } 314 } 315 316 /* This takes the board allocated linear DDR memory and creates aliases 317 * for each split DDR range/aperture on the Versal address map. 318 */ 319 static void versal_map_ddr(Versal *s) 320 { 321 uint64_t size = memory_region_size(s->cfg.mr_ddr); 322 /* Describes the various split DDR access regions. */ 323 static const struct { 324 uint64_t base; 325 uint64_t size; 326 } addr_ranges[] = { 327 { MM_TOP_DDR, MM_TOP_DDR_SIZE }, 328 { MM_TOP_DDR_2, MM_TOP_DDR_2_SIZE }, 329 { MM_TOP_DDR_3, MM_TOP_DDR_3_SIZE }, 330 { MM_TOP_DDR_4, MM_TOP_DDR_4_SIZE } 331 }; 332 uint64_t offset = 0; 333 int i; 334 335 assert(ARRAY_SIZE(addr_ranges) == ARRAY_SIZE(s->noc.mr_ddr_ranges)); 336 for (i = 0; i < ARRAY_SIZE(addr_ranges) && size; i++) { 337 char *name; 338 uint64_t mapsize; 339 340 mapsize = size < addr_ranges[i].size ? size : addr_ranges[i].size; 341 name = g_strdup_printf("noc-ddr-range%d", i); 342 /* Create the MR alias. */ 343 memory_region_init_alias(&s->noc.mr_ddr_ranges[i], OBJECT(s), 344 name, s->cfg.mr_ddr, 345 offset, mapsize); 346 347 /* Map it onto the NoC MR. */ 348 memory_region_add_subregion(&s->mr_ps, addr_ranges[i].base, 349 &s->noc.mr_ddr_ranges[i]); 350 offset += mapsize; 351 size -= mapsize; 352 g_free(name); 353 } 354 } 355 356 static void versal_unimp_area(Versal *s, const char *name, 357 MemoryRegion *mr, 358 hwaddr base, hwaddr size) 359 { 360 DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE); 361 MemoryRegion *mr_dev; 362 363 qdev_prop_set_string(dev, "name", name); 364 qdev_prop_set_uint64(dev, "size", size); 365 object_property_add_child(OBJECT(s), name, OBJECT(dev)); 366 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 367 368 mr_dev = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 369 memory_region_add_subregion(mr, base, mr_dev); 370 } 371 372 static void versal_unimp(Versal *s) 373 { 374 versal_unimp_area(s, "psm", &s->mr_ps, 375 MM_PSM_START, MM_PSM_END - MM_PSM_START); 376 versal_unimp_area(s, "crl", &s->mr_ps, 377 MM_CRL, MM_CRL_SIZE); 378 versal_unimp_area(s, "crf", &s->mr_ps, 379 MM_FPD_CRF, MM_FPD_CRF_SIZE); 380 versal_unimp_area(s, "crp", &s->mr_ps, 381 MM_PMC_CRP, MM_PMC_CRP_SIZE); 382 versal_unimp_area(s, "iou-scntr", &s->mr_ps, 383 MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE); 384 versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps, 385 MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE); 386 } 387 388 static void versal_realize(DeviceState *dev, Error **errp) 389 { 390 Versal *s = XLNX_VERSAL(dev); 391 qemu_irq pic[XLNX_VERSAL_NR_IRQS]; 392 393 versal_create_apu_cpus(s); 394 versal_create_apu_gic(s, pic); 395 versal_create_uarts(s, pic); 396 versal_create_usbs(s, pic); 397 versal_create_gems(s, pic); 398 versal_create_admas(s, pic); 399 versal_create_sds(s, pic); 400 versal_create_rtc(s, pic); 401 versal_create_xrams(s, pic); 402 versal_map_ddr(s); 403 versal_unimp(s); 404 405 /* Create the On Chip Memory (OCM). */ 406 memory_region_init_ram(&s->lpd.mr_ocm, OBJECT(s), "ocm", 407 MM_OCM_SIZE, &error_fatal); 408 409 memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0); 410 memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0); 411 } 412 413 static void versal_init(Object *obj) 414 { 415 Versal *s = XLNX_VERSAL(obj); 416 417 memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX); 418 memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX); 419 } 420 421 static Property versal_properties[] = { 422 DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION, 423 MemoryRegion *), 424 DEFINE_PROP_UINT32("psci-conduit", Versal, cfg.psci_conduit, 0), 425 DEFINE_PROP_END_OF_LIST() 426 }; 427 428 static void versal_class_init(ObjectClass *klass, void *data) 429 { 430 DeviceClass *dc = DEVICE_CLASS(klass); 431 432 dc->realize = versal_realize; 433 device_class_set_props(dc, versal_properties); 434 /* No VMSD since we haven't got any top-level SoC state to save. */ 435 } 436 437 static const TypeInfo versal_info = { 438 .name = TYPE_XLNX_VERSAL, 439 .parent = TYPE_SYS_BUS_DEVICE, 440 .instance_size = sizeof(Versal), 441 .instance_init = versal_init, 442 .class_init = versal_class_init, 443 }; 444 445 static void versal_register_types(void) 446 { 447 type_register_static(&versal_info); 448 } 449 450 type_init(versal_register_types); 451