xref: /qemu/hw/arm/xlnx-versal.c (revision c07c0c37ad45c6cd1cd9ef94988a4790bb78e287)
1b89de436SEdgar E. Iglesias /*
2b89de436SEdgar E. Iglesias  * Xilinx Versal SoC model.
3b89de436SEdgar E. Iglesias  *
4b89de436SEdgar E. Iglesias  * Copyright (c) 2018 Xilinx Inc.
5b89de436SEdgar E. Iglesias  * Written by Edgar E. Iglesias
6b89de436SEdgar E. Iglesias  *
7b89de436SEdgar E. Iglesias  * This program is free software; you can redistribute it and/or modify
8b89de436SEdgar E. Iglesias  * it under the terms of the GNU General Public License version 2 or
9b89de436SEdgar E. Iglesias  * (at your option) any later version.
10b89de436SEdgar E. Iglesias  */
11b89de436SEdgar E. Iglesias 
12b89de436SEdgar E. Iglesias #include "qemu/osdep.h"
13b89de436SEdgar E. Iglesias #include "qapi/error.h"
14b89de436SEdgar E. Iglesias #include "qemu/log.h"
150b8fa32fSMarkus Armbruster #include "qemu/module.h"
16b89de436SEdgar E. Iglesias #include "hw/sysbus.h"
17b89de436SEdgar E. Iglesias #include "net/net.h"
18b89de436SEdgar E. Iglesias #include "sysemu/sysemu.h"
19b89de436SEdgar E. Iglesias #include "sysemu/kvm.h"
2012ec8bd5SPeter Maydell #include "hw/arm/boot.h"
21b89de436SEdgar E. Iglesias #include "kvm_arm.h"
22b89de436SEdgar E. Iglesias #include "hw/misc/unimp.h"
23b89de436SEdgar E. Iglesias #include "hw/arm/xlnx-versal.h"
24d8f6d15fSGavin Shan #include "hw/char/pl011.h"
25b89de436SEdgar E. Iglesias 
26b89de436SEdgar E. Iglesias #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
27b89de436SEdgar E. Iglesias #define GEM_REVISION        0x40070106
28b89de436SEdgar E. Iglesias 
29b89de436SEdgar E. Iglesias static void versal_create_apu_cpus(Versal *s)
30b89de436SEdgar E. Iglesias {
31b89de436SEdgar E. Iglesias     int i;
32b89de436SEdgar E. Iglesias 
33b89de436SEdgar E. Iglesias     for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
34b89de436SEdgar E. Iglesias         Object *obj;
35b89de436SEdgar E. Iglesias         char *name;
36b89de436SEdgar E. Iglesias 
37b89de436SEdgar E. Iglesias         obj = object_new(XLNX_VERSAL_ACPU_TYPE);
38b89de436SEdgar E. Iglesias         if (!obj) {
39b89de436SEdgar E. Iglesias             error_report("Unable to create apu.cpu[%d] of type %s",
40b89de436SEdgar E. Iglesias                          i, XLNX_VERSAL_ACPU_TYPE);
41b89de436SEdgar E. Iglesias             exit(EXIT_FAILURE);
42b89de436SEdgar E. Iglesias         }
43b89de436SEdgar E. Iglesias 
44b89de436SEdgar E. Iglesias         name = g_strdup_printf("apu-cpu[%d]", i);
45b89de436SEdgar E. Iglesias         object_property_add_child(OBJECT(s), name, obj, &error_fatal);
46b89de436SEdgar E. Iglesias         g_free(name);
47b89de436SEdgar E. Iglesias 
48b89de436SEdgar E. Iglesias         object_property_set_int(obj, s->cfg.psci_conduit,
49b89de436SEdgar E. Iglesias                                 "psci-conduit", &error_abort);
50b89de436SEdgar E. Iglesias         if (i) {
51*c07c0c37SEdgar E. Iglesias             /* Secondary CPUs start in PSCI powered-down state */
52b89de436SEdgar E. Iglesias             object_property_set_bool(obj, true,
53b89de436SEdgar E. Iglesias                                      "start-powered-off", &error_abort);
54b89de436SEdgar E. Iglesias         }
55b89de436SEdgar E. Iglesias 
56b89de436SEdgar E. Iglesias         object_property_set_int(obj, ARRAY_SIZE(s->fpd.apu.cpu),
57b89de436SEdgar E. Iglesias                                 "core-count", &error_abort);
58b89de436SEdgar E. Iglesias         object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory",
59b89de436SEdgar E. Iglesias                                  &error_abort);
60b89de436SEdgar E. Iglesias         object_property_set_bool(obj, true, "realized", &error_fatal);
61b89de436SEdgar E. Iglesias         s->fpd.apu.cpu[i] = ARM_CPU(obj);
62b89de436SEdgar E. Iglesias     }
63b89de436SEdgar E. Iglesias }
64b89de436SEdgar E. Iglesias 
65b89de436SEdgar E. Iglesias static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
66b89de436SEdgar E. Iglesias {
67b89de436SEdgar E. Iglesias     static const uint64_t addrs[] = {
68b89de436SEdgar E. Iglesias         MM_GIC_APU_DIST_MAIN,
69b89de436SEdgar E. Iglesias         MM_GIC_APU_REDIST_0
70b89de436SEdgar E. Iglesias     };
71b89de436SEdgar E. Iglesias     SysBusDevice *gicbusdev;
72b89de436SEdgar E. Iglesias     DeviceState *gicdev;
73b89de436SEdgar E. Iglesias     int nr_apu_cpus = ARRAY_SIZE(s->fpd.apu.cpu);
74b89de436SEdgar E. Iglesias     int i;
75b89de436SEdgar E. Iglesias 
76b89de436SEdgar E. Iglesias     sysbus_init_child_obj(OBJECT(s), "apu-gic",
77b89de436SEdgar E. Iglesias                           &s->fpd.apu.gic, sizeof(s->fpd.apu.gic),
78b89de436SEdgar E. Iglesias                           gicv3_class_name());
79b89de436SEdgar E. Iglesias     gicbusdev = SYS_BUS_DEVICE(&s->fpd.apu.gic);
80b89de436SEdgar E. Iglesias     gicdev = DEVICE(&s->fpd.apu.gic);
81b89de436SEdgar E. Iglesias     qdev_prop_set_uint32(gicdev, "revision", 3);
82b89de436SEdgar E. Iglesias     qdev_prop_set_uint32(gicdev, "num-cpu", 2);
83b89de436SEdgar E. Iglesias     qdev_prop_set_uint32(gicdev, "num-irq", XLNX_VERSAL_NR_IRQS + 32);
84b89de436SEdgar E. Iglesias     qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
85b89de436SEdgar E. Iglesias     qdev_prop_set_uint32(gicdev, "redist-region-count[0]", 2);
86b89de436SEdgar E. Iglesias     qdev_prop_set_bit(gicdev, "has-security-extensions", true);
87b89de436SEdgar E. Iglesias 
88b89de436SEdgar E. Iglesias     object_property_set_bool(OBJECT(&s->fpd.apu.gic), true, "realized",
89b89de436SEdgar E. Iglesias                                     &error_fatal);
90b89de436SEdgar E. Iglesias 
91b89de436SEdgar E. Iglesias     for (i = 0; i < ARRAY_SIZE(addrs); i++) {
92b89de436SEdgar E. Iglesias         MemoryRegion *mr;
93b89de436SEdgar E. Iglesias 
94b89de436SEdgar E. Iglesias         mr = sysbus_mmio_get_region(gicbusdev, i);
95b89de436SEdgar E. Iglesias         memory_region_add_subregion(&s->fpd.apu.mr, addrs[i], mr);
96b89de436SEdgar E. Iglesias     }
97b89de436SEdgar E. Iglesias 
98b89de436SEdgar E. Iglesias     for (i = 0; i < nr_apu_cpus; i++) {
99b89de436SEdgar E. Iglesias         DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
100b89de436SEdgar E. Iglesias         int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
101b89de436SEdgar E. Iglesias         qemu_irq maint_irq;
102b89de436SEdgar E. Iglesias         int ti;
103b89de436SEdgar E. Iglesias         /* Mapping from the output timer irq lines from the CPU to the
104b89de436SEdgar E. Iglesias          * GIC PPI inputs.
105b89de436SEdgar E. Iglesias          */
106b89de436SEdgar E. Iglesias         const int timer_irq[] = {
107b89de436SEdgar E. Iglesias             [GTIMER_PHYS] = VERSAL_TIMER_NS_EL1_IRQ,
108b89de436SEdgar E. Iglesias             [GTIMER_VIRT] = VERSAL_TIMER_VIRT_IRQ,
109b89de436SEdgar E. Iglesias             [GTIMER_HYP]  = VERSAL_TIMER_NS_EL2_IRQ,
110b89de436SEdgar E. Iglesias             [GTIMER_SEC]  = VERSAL_TIMER_S_EL1_IRQ,
111b89de436SEdgar E. Iglesias         };
112b89de436SEdgar E. Iglesias 
113b89de436SEdgar E. Iglesias         for (ti = 0; ti < ARRAY_SIZE(timer_irq); ti++) {
114b89de436SEdgar E. Iglesias             qdev_connect_gpio_out(cpudev, ti,
115b89de436SEdgar E. Iglesias                                   qdev_get_gpio_in(gicdev,
116b89de436SEdgar E. Iglesias                                                    ppibase + timer_irq[ti]));
117b89de436SEdgar E. Iglesias         }
118b89de436SEdgar E. Iglesias         maint_irq = qdev_get_gpio_in(gicdev,
119b89de436SEdgar E. Iglesias                                         ppibase + VERSAL_GIC_MAINT_IRQ);
120b89de436SEdgar E. Iglesias         qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
121b89de436SEdgar E. Iglesias                                     0, maint_irq);
122b89de436SEdgar E. Iglesias         sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
123b89de436SEdgar E. Iglesias         sysbus_connect_irq(gicbusdev, i + nr_apu_cpus,
124b89de436SEdgar E. Iglesias                            qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
125b89de436SEdgar E. Iglesias         sysbus_connect_irq(gicbusdev, i + 2 * nr_apu_cpus,
126b89de436SEdgar E. Iglesias                            qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
127b89de436SEdgar E. Iglesias         sysbus_connect_irq(gicbusdev, i + 3 * nr_apu_cpus,
128b89de436SEdgar E. Iglesias                            qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
129b89de436SEdgar E. Iglesias     }
130b89de436SEdgar E. Iglesias 
131b89de436SEdgar E. Iglesias     for (i = 0; i < XLNX_VERSAL_NR_IRQS; i++) {
132b89de436SEdgar E. Iglesias         pic[i] = qdev_get_gpio_in(gicdev, i);
133b89de436SEdgar E. Iglesias     }
134b89de436SEdgar E. Iglesias }
135b89de436SEdgar E. Iglesias 
136b89de436SEdgar E. Iglesias static void versal_create_uarts(Versal *s, qemu_irq *pic)
137b89de436SEdgar E. Iglesias {
138b89de436SEdgar E. Iglesias     int i;
139b89de436SEdgar E. Iglesias 
140b89de436SEdgar E. Iglesias     for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
141b89de436SEdgar E. Iglesias         static const int irqs[] = { VERSAL_UART0_IRQ_0, VERSAL_UART1_IRQ_0};
142b89de436SEdgar E. Iglesias         static const uint64_t addrs[] = { MM_UART0, MM_UART1 };
143b89de436SEdgar E. Iglesias         char *name = g_strdup_printf("uart%d", i);
144b89de436SEdgar E. Iglesias         DeviceState *dev;
145b89de436SEdgar E. Iglesias         MemoryRegion *mr;
146b89de436SEdgar E. Iglesias 
147d8f6d15fSGavin Shan         dev = qdev_create(NULL, TYPE_PL011);
148b89de436SEdgar E. Iglesias         s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
149b89de436SEdgar E. Iglesias         qdev_prop_set_chr(dev, "chardev", serial_hd(i));
150b89de436SEdgar E. Iglesias         object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
151b89de436SEdgar E. Iglesias         qdev_init_nofail(dev);
152b89de436SEdgar E. Iglesias 
153b89de436SEdgar E. Iglesias         mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
154b89de436SEdgar E. Iglesias         memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
155b89de436SEdgar E. Iglesias 
156b89de436SEdgar E. Iglesias         sysbus_connect_irq(s->lpd.iou.uart[i], 0, pic[irqs[i]]);
157b89de436SEdgar E. Iglesias         g_free(name);
158b89de436SEdgar E. Iglesias     }
159b89de436SEdgar E. Iglesias }
160b89de436SEdgar E. Iglesias 
161b89de436SEdgar E. Iglesias static void versal_create_gems(Versal *s, qemu_irq *pic)
162b89de436SEdgar E. Iglesias {
163b89de436SEdgar E. Iglesias     int i;
164b89de436SEdgar E. Iglesias 
165b89de436SEdgar E. Iglesias     for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
166b89de436SEdgar E. Iglesias         static const int irqs[] = { VERSAL_GEM0_IRQ_0, VERSAL_GEM1_IRQ_0};
167b89de436SEdgar E. Iglesias         static const uint64_t addrs[] = { MM_GEM0, MM_GEM1 };
168b89de436SEdgar E. Iglesias         char *name = g_strdup_printf("gem%d", i);
169b89de436SEdgar E. Iglesias         NICInfo *nd = &nd_table[i];
170b89de436SEdgar E. Iglesias         DeviceState *dev;
171b89de436SEdgar E. Iglesias         MemoryRegion *mr;
172b89de436SEdgar E. Iglesias 
173b89de436SEdgar E. Iglesias         dev = qdev_create(NULL, "cadence_gem");
174b89de436SEdgar E. Iglesias         s->lpd.iou.gem[i] = SYS_BUS_DEVICE(dev);
175b89de436SEdgar E. Iglesias         object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
176b89de436SEdgar E. Iglesias         if (nd->used) {
177b89de436SEdgar E. Iglesias             qemu_check_nic_model(nd, "cadence_gem");
178b89de436SEdgar E. Iglesias             qdev_set_nic_properties(dev, nd);
179b89de436SEdgar E. Iglesias         }
180b89de436SEdgar E. Iglesias         object_property_set_int(OBJECT(s->lpd.iou.gem[i]),
181b89de436SEdgar E. Iglesias                                 2, "num-priority-queues",
182b89de436SEdgar E. Iglesias                                 &error_abort);
183b89de436SEdgar E. Iglesias         object_property_set_link(OBJECT(s->lpd.iou.gem[i]),
184b89de436SEdgar E. Iglesias                                  OBJECT(&s->mr_ps), "dma",
185b89de436SEdgar E. Iglesias                                  &error_abort);
186b89de436SEdgar E. Iglesias         qdev_init_nofail(dev);
187b89de436SEdgar E. Iglesias 
188b89de436SEdgar E. Iglesias         mr = sysbus_mmio_get_region(s->lpd.iou.gem[i], 0);
189b89de436SEdgar E. Iglesias         memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
190b89de436SEdgar E. Iglesias 
191b89de436SEdgar E. Iglesias         sysbus_connect_irq(s->lpd.iou.gem[i], 0, pic[irqs[i]]);
192b89de436SEdgar E. Iglesias         g_free(name);
193b89de436SEdgar E. Iglesias     }
194b89de436SEdgar E. Iglesias }
195b89de436SEdgar E. Iglesias 
1968a218651SEdgar E. Iglesias static void versal_create_admas(Versal *s, qemu_irq *pic)
1978a218651SEdgar E. Iglesias {
1988a218651SEdgar E. Iglesias     int i;
1998a218651SEdgar E. Iglesias 
2008a218651SEdgar E. Iglesias     for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
2018a218651SEdgar E. Iglesias         char *name = g_strdup_printf("adma%d", i);
2028a218651SEdgar E. Iglesias         DeviceState *dev;
2038a218651SEdgar E. Iglesias         MemoryRegion *mr;
2048a218651SEdgar E. Iglesias 
2058a218651SEdgar E. Iglesias         dev = qdev_create(NULL, "xlnx.zdma");
2068a218651SEdgar E. Iglesias         s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
207681b5bc3SEdgar E. Iglesias         object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
208681b5bc3SEdgar E. Iglesias                                 &error_abort);
2098a218651SEdgar E. Iglesias         object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
2108a218651SEdgar E. Iglesias         qdev_init_nofail(dev);
2118a218651SEdgar E. Iglesias 
2128a218651SEdgar E. Iglesias         mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
2138a218651SEdgar E. Iglesias         memory_region_add_subregion(&s->mr_ps,
2148a218651SEdgar E. Iglesias                                     MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
2158a218651SEdgar E. Iglesias 
2168a218651SEdgar E. Iglesias         sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
2178a218651SEdgar E. Iglesias         g_free(name);
2188a218651SEdgar E. Iglesias     }
2198a218651SEdgar E. Iglesias }
2208a218651SEdgar E. Iglesias 
221b89de436SEdgar E. Iglesias /* This takes the board allocated linear DDR memory and creates aliases
222b89de436SEdgar E. Iglesias  * for each split DDR range/aperture on the Versal address map.
223b89de436SEdgar E. Iglesias  */
224b89de436SEdgar E. Iglesias static void versal_map_ddr(Versal *s)
225b89de436SEdgar E. Iglesias {
226b89de436SEdgar E. Iglesias     uint64_t size = memory_region_size(s->cfg.mr_ddr);
227b89de436SEdgar E. Iglesias     /* Describes the various split DDR access regions.  */
228b89de436SEdgar E. Iglesias     static const struct {
229b89de436SEdgar E. Iglesias         uint64_t base;
230b89de436SEdgar E. Iglesias         uint64_t size;
231b89de436SEdgar E. Iglesias     } addr_ranges[] = {
232b89de436SEdgar E. Iglesias         { MM_TOP_DDR, MM_TOP_DDR_SIZE },
233b89de436SEdgar E. Iglesias         { MM_TOP_DDR_2, MM_TOP_DDR_2_SIZE },
234b89de436SEdgar E. Iglesias         { MM_TOP_DDR_3, MM_TOP_DDR_3_SIZE },
235b89de436SEdgar E. Iglesias         { MM_TOP_DDR_4, MM_TOP_DDR_4_SIZE }
236b89de436SEdgar E. Iglesias     };
237b89de436SEdgar E. Iglesias     uint64_t offset = 0;
238b89de436SEdgar E. Iglesias     int i;
239b89de436SEdgar E. Iglesias 
240b89de436SEdgar E. Iglesias     assert(ARRAY_SIZE(addr_ranges) == ARRAY_SIZE(s->noc.mr_ddr_ranges));
241b89de436SEdgar E. Iglesias     for (i = 0; i < ARRAY_SIZE(addr_ranges) && size; i++) {
242b89de436SEdgar E. Iglesias         char *name;
243b89de436SEdgar E. Iglesias         uint64_t mapsize;
244b89de436SEdgar E. Iglesias 
245b89de436SEdgar E. Iglesias         mapsize = size < addr_ranges[i].size ? size : addr_ranges[i].size;
246b89de436SEdgar E. Iglesias         name = g_strdup_printf("noc-ddr-range%d", i);
247b89de436SEdgar E. Iglesias         /* Create the MR alias.  */
248b89de436SEdgar E. Iglesias         memory_region_init_alias(&s->noc.mr_ddr_ranges[i], OBJECT(s),
249b89de436SEdgar E. Iglesias                                  name, s->cfg.mr_ddr,
250b89de436SEdgar E. Iglesias                                  offset, mapsize);
251b89de436SEdgar E. Iglesias 
252b89de436SEdgar E. Iglesias         /* Map it onto the NoC MR.  */
253b89de436SEdgar E. Iglesias         memory_region_add_subregion(&s->mr_ps, addr_ranges[i].base,
254b89de436SEdgar E. Iglesias                                     &s->noc.mr_ddr_ranges[i]);
255b89de436SEdgar E. Iglesias         offset += mapsize;
256b89de436SEdgar E. Iglesias         size -= mapsize;
257b89de436SEdgar E. Iglesias         g_free(name);
258b89de436SEdgar E. Iglesias     }
259b89de436SEdgar E. Iglesias }
260b89de436SEdgar E. Iglesias 
261b89de436SEdgar E. Iglesias static void versal_unimp_area(Versal *s, const char *name,
262b89de436SEdgar E. Iglesias                                 MemoryRegion *mr,
263b89de436SEdgar E. Iglesias                                 hwaddr base, hwaddr size)
264b89de436SEdgar E. Iglesias {
265b89de436SEdgar E. Iglesias     DeviceState *dev = qdev_create(NULL, TYPE_UNIMPLEMENTED_DEVICE);
266b89de436SEdgar E. Iglesias     MemoryRegion *mr_dev;
267b89de436SEdgar E. Iglesias 
268b89de436SEdgar E. Iglesias     qdev_prop_set_string(dev, "name", name);
269b89de436SEdgar E. Iglesias     qdev_prop_set_uint64(dev, "size", size);
270b89de436SEdgar E. Iglesias     object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
271b89de436SEdgar E. Iglesias     qdev_init_nofail(dev);
272b89de436SEdgar E. Iglesias 
273b89de436SEdgar E. Iglesias     mr_dev = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
274b89de436SEdgar E. Iglesias     memory_region_add_subregion(mr, base, mr_dev);
275b89de436SEdgar E. Iglesias }
276b89de436SEdgar E. Iglesias 
277b89de436SEdgar E. Iglesias static void versal_unimp(Versal *s)
278b89de436SEdgar E. Iglesias {
279b89de436SEdgar E. Iglesias     versal_unimp_area(s, "psm", &s->mr_ps,
280b89de436SEdgar E. Iglesias                         MM_PSM_START, MM_PSM_END - MM_PSM_START);
281b89de436SEdgar E. Iglesias     versal_unimp_area(s, "crl", &s->mr_ps,
282b89de436SEdgar E. Iglesias                         MM_CRL, MM_CRL_SIZE);
283b89de436SEdgar E. Iglesias     versal_unimp_area(s, "crf", &s->mr_ps,
284b89de436SEdgar E. Iglesias                         MM_FPD_CRF, MM_FPD_CRF_SIZE);
285f0138990SEdgar E. Iglesias     versal_unimp_area(s, "crp", &s->mr_ps,
286f0138990SEdgar E. Iglesias                         MM_PMC_CRP, MM_PMC_CRP_SIZE);
287b89de436SEdgar E. Iglesias     versal_unimp_area(s, "iou-scntr", &s->mr_ps,
288b89de436SEdgar E. Iglesias                         MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE);
289b89de436SEdgar E. Iglesias     versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps,
290b89de436SEdgar E. Iglesias                         MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE);
291b89de436SEdgar E. Iglesias }
292b89de436SEdgar E. Iglesias 
293b89de436SEdgar E. Iglesias static void versal_realize(DeviceState *dev, Error **errp)
294b89de436SEdgar E. Iglesias {
295b89de436SEdgar E. Iglesias     Versal *s = XLNX_VERSAL(dev);
296b89de436SEdgar E. Iglesias     qemu_irq pic[XLNX_VERSAL_NR_IRQS];
297b89de436SEdgar E. Iglesias 
298b89de436SEdgar E. Iglesias     versal_create_apu_cpus(s);
299b89de436SEdgar E. Iglesias     versal_create_apu_gic(s, pic);
300b89de436SEdgar E. Iglesias     versal_create_uarts(s, pic);
301b89de436SEdgar E. Iglesias     versal_create_gems(s, pic);
3028a218651SEdgar E. Iglesias     versal_create_admas(s, pic);
303b89de436SEdgar E. Iglesias     versal_map_ddr(s);
304b89de436SEdgar E. Iglesias     versal_unimp(s);
305b89de436SEdgar E. Iglesias 
306b89de436SEdgar E. Iglesias     /* Create the On Chip Memory (OCM).  */
307b89de436SEdgar E. Iglesias     memory_region_init_ram(&s->lpd.mr_ocm, OBJECT(s), "ocm",
308b89de436SEdgar E. Iglesias                            MM_OCM_SIZE, &error_fatal);
309b89de436SEdgar E. Iglesias 
310b89de436SEdgar E. Iglesias     memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0);
311b89de436SEdgar E. Iglesias     memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0);
312b89de436SEdgar E. Iglesias }
313b89de436SEdgar E. Iglesias 
314b89de436SEdgar E. Iglesias static void versal_init(Object *obj)
315b89de436SEdgar E. Iglesias {
316b89de436SEdgar E. Iglesias     Versal *s = XLNX_VERSAL(obj);
317b89de436SEdgar E. Iglesias 
318b89de436SEdgar E. Iglesias     memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
319b89de436SEdgar E. Iglesias     memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
320b89de436SEdgar E. Iglesias }
321b89de436SEdgar E. Iglesias 
322b89de436SEdgar E. Iglesias static Property versal_properties[] = {
323b89de436SEdgar E. Iglesias     DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION,
324b89de436SEdgar E. Iglesias                      MemoryRegion *),
325b89de436SEdgar E. Iglesias     DEFINE_PROP_UINT32("psci-conduit", Versal, cfg.psci_conduit, 0),
326b89de436SEdgar E. Iglesias     DEFINE_PROP_END_OF_LIST()
327b89de436SEdgar E. Iglesias };
328b89de436SEdgar E. Iglesias 
329b89de436SEdgar E. Iglesias static void versal_class_init(ObjectClass *klass, void *data)
330b89de436SEdgar E. Iglesias {
331b89de436SEdgar E. Iglesias     DeviceClass *dc = DEVICE_CLASS(klass);
332b89de436SEdgar E. Iglesias 
333b89de436SEdgar E. Iglesias     dc->realize = versal_realize;
3344f67d30bSMarc-André Lureau     device_class_set_props(dc, versal_properties);
335b89de436SEdgar E. Iglesias     /* No VMSD since we haven't got any top-level SoC state to save.  */
336b89de436SEdgar E. Iglesias }
337b89de436SEdgar E. Iglesias 
338b89de436SEdgar E. Iglesias static const TypeInfo versal_info = {
339b89de436SEdgar E. Iglesias     .name = TYPE_XLNX_VERSAL,
340b89de436SEdgar E. Iglesias     .parent = TYPE_SYS_BUS_DEVICE,
341b89de436SEdgar E. Iglesias     .instance_size = sizeof(Versal),
342b89de436SEdgar E. Iglesias     .instance_init = versal_init,
343b89de436SEdgar E. Iglesias     .class_init = versal_class_init,
344b89de436SEdgar E. Iglesias };
345b89de436SEdgar E. Iglesias 
346b89de436SEdgar E. Iglesias static void versal_register_types(void)
347b89de436SEdgar E. Iglesias {
348b89de436SEdgar E. Iglesias     type_register_static(&versal_info);
349b89de436SEdgar E. Iglesias }
350b89de436SEdgar E. Iglesias 
351b89de436SEdgar E. Iglesias type_init(versal_register_types);
352