master
c 2,160 lines 70.1 KB
Raw
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/core/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/core/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);