aboutsummaryrefslogtreecommitdiff
path: root/hw/arm/xlnx-zynqmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm/xlnx-zynqmp.c')
-rw-r--r--hw/arm/xlnx-zynqmp.c86
1 files changed, 64 insertions, 22 deletions
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 3597e8db4d..4e5a471e30 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -20,6 +20,7 @@
#include "qemu/module.h"
#include "hw/arm/xlnx-zynqmp.h"
#include "hw/intc/arm_gic_common.h"
+#include "hw/misc/unimp.h"
#include "hw/boards.h"
#include "sysemu/kvm.h"
#include "sysemu/sysemu.h"
@@ -56,6 +57,9 @@
#define DPDMA_ADDR 0xfd4c0000
#define DPDMA_IRQ 116
+#define APU_ADDR 0xfd5c0000
+#define APU_SIZE 0x100
+
#define IPI_ADDR 0xFF300000
#define IPI_IRQ 64
@@ -222,6 +226,32 @@ static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s,
qdev_realize(DEVICE(&s->rpu_cluster), NULL, &error_fatal);
}
+static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
+{
+ static const struct UnimpInfo {
+ const char *name;
+ hwaddr base;
+ hwaddr size;
+ } unimp_areas[ARRAY_SIZE(s->mr_unimp)] = {
+ { .name = "apu", APU_ADDR, APU_SIZE },
+ };
+ unsigned int nr;
+
+ for (nr = 0; nr < ARRAY_SIZE(unimp_areas); nr++) {
+ const struct UnimpInfo *info = &unimp_areas[nr];
+ DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+ assert(info->name && info->base && info->size > 0);
+ qdev_prop_set_string(dev, "name", info->name);
+ qdev_prop_set_uint64(dev, "size", info->size);
+ object_property_add_child(OBJECT(s), info->name, OBJECT(dev));
+
+ sysbus_realize_and_unref(sbd, &error_fatal);
+ sysbus_mmio_map(sbd, 0, info->base);
+ }
+}
+
static void xlnx_zynqmp_init(Object *obj)
{
MachineState *ms = MACHINE(qdev_get_machine());
@@ -570,26 +600,6 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
g_free(bus_name);
}
- if (!sysbus_realize(SYS_BUS_DEVICE(&s->qspi), errp)) {
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 0, QSPI_ADDR);
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 1, LQSPI_ADDR);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi), 0, gic_spi[QSPI_IRQ]);
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_QSPI_BUS; i++) {
- gchar *bus_name;
- gchar *target_bus;
-
- /* Alias controller SPI bus to the SoC itself */
- bus_name = g_strdup_printf("qspi%d", i);
- target_bus = g_strdup_printf("spi%d", i);
- object_property_add_alias(OBJECT(s), bus_name,
- OBJECT(&s->qspi), target_bus);
- g_free(bus_name);
- g_free(target_bus);
- }
-
if (!sysbus_realize(SYS_BUS_DEVICE(&s->dp), errp)) {
return;
}
@@ -616,11 +626,17 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, RTC_ADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, gic_spi[RTC_IRQ]);
+ xlnx_zynqmp_create_unimp_mmio(s);
+
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
if (!object_property_set_uint(OBJECT(&s->gdma[i]), "bus-width", 128,
errp)) {
return;
}
+ if (!object_property_set_link(OBJECT(&s->gdma[i]), "dma",
+ OBJECT(system_memory), errp)) {
+ return;
+ }
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gdma[i]), errp)) {
return;
}
@@ -631,6 +647,10 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
}
for (i = 0; i < XLNX_ZYNQMP_NUM_ADMA_CH; i++) {
+ if (!object_property_set_link(OBJECT(&s->adma[i]), "dma",
+ OBJECT(system_memory), errp)) {
+ return;
+ }
if (!sysbus_realize(SYS_BUS_DEVICE(&s->adma[i]), errp)) {
return;
}
@@ -640,14 +660,36 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
gic_spi[adma_ch_intr[i]]);
}
+ if (!object_property_set_link(OBJECT(&s->qspi_dma), "dma",
+ OBJECT(system_memory), errp)) {
+ return;
+ }
if (!sysbus_realize(SYS_BUS_DEVICE(&s->qspi_dma), errp)) {
return;
}
sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi_dma), 0, QSPI_DMA_ADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi_dma), 0, gic_spi[QSPI_IRQ]);
- object_property_set_link(OBJECT(&s->qspi), "stream-connected-dma",
- OBJECT(&s->qspi_dma), errp);
+
+ if (!object_property_set_link(OBJECT(&s->qspi), "stream-connected-dma",
+ OBJECT(&s->qspi_dma), errp)) {
+ return;
+ }
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->qspi), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 0, QSPI_ADDR);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 1, LQSPI_ADDR);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi), 0, gic_spi[QSPI_IRQ]);
+
+ for (i = 0; i < XLNX_ZYNQMP_NUM_QSPI_BUS; i++) {
+ g_autofree gchar *bus_name = g_strdup_printf("qspi%d", i);
+ g_autofree gchar *target_bus = g_strdup_printf("spi%d", i);
+
+ /* Alias controller SPI bus to the SoC itself */
+ object_property_add_alias(OBJECT(s), bus_name,
+ OBJECT(&s->qspi), target_bus);
+ }
}
static Property xlnx_zynqmp_props[] = {