xref: /openbmc/qemu/hw/arm/xlnx-versal.c (revision 40e62b903ab847eca9ec1f266d4a60c5a3279344)
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/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/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);
2161