@@ -28,6 +28,7 @@
#include "sysemu/sysemu.h"
#include "hw/vfio/vfio-platform.h"
#include "hw/vfio/vfio-calxeda-xgmac.h"
+#include "hw/misc/sdm-platform.h"
#include "hw/arm/fdt.h"
/*
@@ -123,9 +124,70 @@ fail_reg:
return ret;
}
+/**
+ * add_sdm_fdt_node
+ *
+ * Generates a node with following properties:
+ * compatible string, regs, interrupts
+ *
+ */
+static int add_sdm_fdt_node(SysBusDevice *sbdev, void *opaque)
+{
+ PlatformBusFDTData *data = opaque;
+ PlatformBusDevice *pbus = data->pbus;
+ const char sdm_compat[] = "sdm-ipi";
+ void *fdt = data->fdt;
+ const char *parent_node = data->pbus_node_name;
+ char *nodename;
+ int ret = -1;
+ uint32_t *irq_attr, *reg_attr;
+ uint64_t mmio_base, irq_number;
+
+ mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+ nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node,
+ TYPE_SDM_PLATFORM, mmio_base);
+ qemu_fdt_add_subnode(fdt, nodename);
+
+ qemu_fdt_setprop(fdt, nodename, "compatible", sdm_compat,
+ sizeof(sdm_compat));
+
+ /**
+ * There is only one MMIO region defined for the SDM device
+ */
+ reg_attr = g_new(uint32_t, 2);
+ mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+ reg_attr[0] = cpu_to_be32(mmio_base);
+ reg_attr[1] = cpu_to_be32(SDM_PLATFORM_SIZE);
+ ret = qemu_fdt_setprop(fdt, nodename, "reg", reg_attr,
+ 2 * sizeof(uint32_t));
+ if (ret) {
+ error_report("could not set reg property of node %s", nodename);
+ goto fail;
+ }
+
+ irq_attr = g_new(uint32_t, 3);
+ irq_number = platform_bus_get_irqn(pbus, sbdev , 0)
+ + data->irq_start;
+ irq_attr[0] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI);
+ irq_attr[1] = cpu_to_be32(irq_number);
+ irq_attr[2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+ ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
+ irq_attr, 3 * sizeof(uint32_t));
+ if (ret) {
+ error_report("could not set interrupts property of node %s",
+ nodename);
+ }
+ g_free(irq_attr);
+fail:
+ g_free(reg_attr);
+ g_free(nodename);
+ return ret;
+}
+
/* list of supported dynamic sysbus devices */
static const NodeCreationPair add_fdt_node_functions[] = {
{TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node},
+ {TYPE_SDM_PLATFORM, add_sdm_fdt_node},
{"", NULL}, /* last element */
};