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 "qapi/error.h" 14 #include "qemu/log.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 25 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72") 26 #define GEM_REVISION 0x40070106 27 28 static void versal_create_apu_cpus(Versal *s) 29 { 30 int i; 31 32 for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) { 33 Object *obj; 34 35 object_initialize_child(OBJECT(s), "apu-cpu[*]", 36 &s->fpd.apu.cpu[i], sizeof(s->fpd.apu.cpu[i]), 37 XLNX_VERSAL_ACPU_TYPE, &error_abort, NULL); 38 obj = OBJECT(&s->fpd.apu.cpu[i]); 39 object_property_set_int(obj, s->cfg.psci_conduit, 40 "psci-conduit", &error_abort); 41 if (i) { 42 /* Secondary CPUs start in PSCI powered-down state */ 43 object_property_set_bool(obj, true, 44 "start-powered-off", &error_abort); 45 } 46 47 object_property_set_int(obj, ARRAY_SIZE(s->fpd.apu.cpu), 48 "core-count", &error_abort); 49 object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory", 50 &error_abort); 51 object_property_set_bool(obj, true, "realized", &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 sysbus_init_child_obj(OBJECT(s), "apu-gic", 67 &s->fpd.apu.gic, sizeof(s->fpd.apu.gic), 68 gicv3_class_name()); 69 gicbusdev = SYS_BUS_DEVICE(&s->fpd.apu.gic); 70 gicdev = DEVICE(&s->fpd.apu.gic); 71 qdev_prop_set_uint32(gicdev, "revision", 3); 72 qdev_prop_set_uint32(gicdev, "num-cpu", 2); 73 qdev_prop_set_uint32(gicdev, "num-irq", XLNX_VERSAL_NR_IRQS + 32); 74 qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1); 75 qdev_prop_set_uint32(gicdev, "redist-region-count[0]", 2); 76 qdev_prop_set_bit(gicdev, "has-security-extensions", true); 77 78 object_property_set_bool(OBJECT(&s->fpd.apu.gic), true, "realized", 79 &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 sysbus_init_child_obj(OBJECT(s), name, 138 &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]), 139 TYPE_PL011); 140 dev = DEVICE(&s->lpd.iou.uart[i]); 141 qdev_prop_set_chr(dev, "chardev", serial_hd(i)); 142 qdev_init_nofail(dev); 143 144 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 145 memory_region_add_subregion(&s->mr_ps, addrs[i], mr); 146 147 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]); 148 g_free(name); 149 } 150 } 151 152 static void versal_create_gems(Versal *s, qemu_irq *pic) 153 { 154 int i; 155 156 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) { 157 static const int irqs[] = { VERSAL_GEM0_IRQ_0, VERSAL_GEM1_IRQ_0}; 158 static const uint64_t addrs[] = { MM_GEM0, MM_GEM1 }; 159 char *name = g_strdup_printf("gem%d", i); 160 NICInfo *nd = &nd_table[i]; 161 DeviceState *dev; 162 MemoryRegion *mr; 163 164 sysbus_init_child_obj(OBJECT(s), name, 165 &s->lpd.iou.gem[i], sizeof(s->lpd.iou.gem[i]), 166 TYPE_CADENCE_GEM); 167 dev = DEVICE(&s->lpd.iou.gem[i]); 168 if (nd->used) { 169 qemu_check_nic_model(nd, "cadence_gem"); 170 qdev_set_nic_properties(dev, nd); 171 } 172 object_property_set_int(OBJECT(dev), 173 2, "num-priority-queues", 174 &error_abort); 175 object_property_set_link(OBJECT(dev), 176 OBJECT(&s->mr_ps), "dma", 177 &error_abort); 178 qdev_init_nofail(dev); 179 180 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 181 memory_region_add_subregion(&s->mr_ps, addrs[i], mr); 182 183 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]); 184 g_free(name); 185 } 186 } 187 188 static void versal_create_admas(Versal *s, qemu_irq *pic) 189 { 190 int i; 191 192 for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) { 193 char *name = g_strdup_printf("adma%d", i); 194 DeviceState *dev; 195 MemoryRegion *mr; 196 197 sysbus_init_child_obj(OBJECT(s), name, 198 &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]), 199 TYPE_XLNX_ZDMA); 200 dev = DEVICE(&s->lpd.iou.adma[i]); 201 object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort); 202 qdev_init_nofail(dev); 203 204 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 205 memory_region_add_subregion(&s->mr_ps, 206 MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr); 207 208 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]); 209 g_free(name); 210 } 211 } 212 213 #define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */ 214 static void versal_create_sds(Versal *s, qemu_irq *pic) 215 { 216 int i; 217 218 for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) { 219 DeviceState *dev; 220 MemoryRegion *mr; 221 222 sysbus_init_child_obj(OBJECT(s), "sd[*]", 223 &s->pmc.iou.sd[i], sizeof(s->pmc.iou.sd[i]), 224 TYPE_SYSBUS_SDHCI); 225 dev = DEVICE(&s->pmc.iou.sd[i]); 226 227 object_property_set_uint(OBJECT(dev), 228 3, "sd-spec-version", &error_fatal); 229 object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg", 230 &error_fatal); 231 object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal); 232 qdev_init_nofail(dev); 233 234 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 235 memory_region_add_subregion(&s->mr_ps, 236 MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr); 237 238 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, 239 pic[VERSAL_SD0_IRQ_0 + i * 2]); 240 } 241 } 242 243 static void versal_create_rtc(Versal *s, qemu_irq *pic) 244 { 245 SysBusDevice *sbd; 246 MemoryRegion *mr; 247 248 sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc), 249 TYPE_XLNX_ZYNQMP_RTC); 250 sbd = SYS_BUS_DEVICE(&s->pmc.rtc); 251 qdev_init_nofail(DEVICE(sbd)); 252 253 mr = sysbus_mmio_get_region(sbd, 0); 254 memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr); 255 256 /* 257 * TODO: Connect the ALARM and SECONDS interrupts once our RTC model 258 * supports them. 259 */ 260 sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]); 261 } 262 263 /* This takes the board allocated linear DDR memory and creates aliases 264 * for each split DDR range/aperture on the Versal address map. 265 */ 266 static void versal_map_ddr(Versal *s) 267 { 268 uint64_t size = memory_region_size(s->cfg.mr_ddr); 269 /* Describes the various split DDR access regions. */ 270 static const struct { 271 uint64_t base; 272 uint64_t size; 273 } addr_ranges[] = { 274 { MM_TOP_DDR, MM_TOP_DDR_SIZE }, 275 { MM_TOP_DDR_2, MM_TOP_DDR_2_SIZE }, 276 { MM_TOP_DDR_3, MM_TOP_DDR_3_SIZE }, 277 { MM_TOP_DDR_4, MM_TOP_DDR_4_SIZE } 278 }; 279 uint64_t offset = 0; 280 int i; 281 282 assert(ARRAY_SIZE(addr_ranges) == ARRAY_SIZE(s->noc.mr_ddr_ranges)); 283 for (i = 0; i < ARRAY_SIZE(addr_ranges) && size; i++) { 284 char *name; 285 uint64_t mapsize; 286 287 mapsize = size < addr_ranges[i].size ? size : addr_ranges[i].size; 288 name = g_strdup_printf("noc-ddr-range%d", i); 289 /* Create the MR alias. */ 290 memory_region_init_alias(&s->noc.mr_ddr_ranges[i], OBJECT(s), 291 name, s->cfg.mr_ddr, 292 offset, mapsize); 293 294 /* Map it onto the NoC MR. */ 295 memory_region_add_subregion(&s->mr_ps, addr_ranges[i].base, 296 &s->noc.mr_ddr_ranges[i]); 297 offset += mapsize; 298 size -= mapsize; 299 g_free(name); 300 } 301 } 302 303 static void versal_unimp_area(Versal *s, const char *name, 304 MemoryRegion *mr, 305 hwaddr base, hwaddr size) 306 { 307 DeviceState *dev = qdev_create(NULL, TYPE_UNIMPLEMENTED_DEVICE); 308 MemoryRegion *mr_dev; 309 310 qdev_prop_set_string(dev, "name", name); 311 qdev_prop_set_uint64(dev, "size", size); 312 object_property_add_child(OBJECT(s), name, OBJECT(dev)); 313 qdev_init_nofail(dev); 314 315 mr_dev = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); 316 memory_region_add_subregion(mr, base, mr_dev); 317 } 318 319 static void versal_unimp(Versal *s) 320 { 321 versal_unimp_area(s, "psm", &s->mr_ps, 322 MM_PSM_START, MM_PSM_END - MM_PSM_START); 323 versal_unimp_area(s, "crl", &s->mr_ps, 324 MM_CRL, MM_CRL_SIZE); 325 versal_unimp_area(s, "crf", &s->mr_ps, 326 MM_FPD_CRF, MM_FPD_CRF_SIZE); 327 versal_unimp_area(s, "crp", &s->mr_ps, 328 MM_PMC_CRP, MM_PMC_CRP_SIZE); 329 versal_unimp_area(s, "iou-scntr", &s->mr_ps, 330 MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE); 331 versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps, 332 MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE); 333 } 334 335 static void versal_realize(DeviceState *dev, Error **errp) 336 { 337 Versal *s = XLNX_VERSAL(dev); 338 qemu_irq pic[XLNX_VERSAL_NR_IRQS]; 339 340 versal_create_apu_cpus(s); 341 versal_create_apu_gic(s, pic); 342 versal_create_uarts(s, pic); 343 versal_create_gems(s, pic); 344 versal_create_admas(s, pic); 345 versal_create_sds(s, pic); 346 versal_create_rtc(s, pic); 347 versal_map_ddr(s); 348 versal_unimp(s); 349 350 /* Create the On Chip Memory (OCM). */ 351 memory_region_init_ram(&s->lpd.mr_ocm, OBJECT(s), "ocm", 352 MM_OCM_SIZE, &error_fatal); 353 354 memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0); 355 memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0); 356 } 357 358 static void versal_init(Object *obj) 359 { 360 Versal *s = XLNX_VERSAL(obj); 361 362 memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX); 363 memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX); 364 } 365 366 static Property versal_properties[] = { 367 DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION, 368 MemoryRegion *), 369 DEFINE_PROP_UINT32("psci-conduit", Versal, cfg.psci_conduit, 0), 370 DEFINE_PROP_END_OF_LIST() 371 }; 372 373 static void versal_class_init(ObjectClass *klass, void *data) 374 { 375 DeviceClass *dc = DEVICE_CLASS(klass); 376 377 dc->realize = versal_realize; 378 device_class_set_props(dc, versal_properties); 379 /* No VMSD since we haven't got any top-level SoC state to save. */ 380 } 381 382 static const TypeInfo versal_info = { 383 .name = TYPE_XLNX_VERSAL, 384 .parent = TYPE_SYS_BUS_DEVICE, 385 .instance_size = sizeof(Versal), 386 .instance_init = versal_init, 387 .class_init = versal_class_init, 388 }; 389 390 static void versal_register_types(void) 391 { 392 type_register_static(&versal_info); 393 } 394 395 type_init(versal_register_types); 396