From: Baptiste Reynal <b.rey...@virtualopensystems.com> Added node creation for dynamically instantiated sysbus SDM device. Support added for all ARM machines modeling dynamic sysbus devices instantiation.
Signed-off-by: Christian Pinto <c.pi...@virtualopensystems.com> Signed-off-by: Baptiste Reynal <b.rey...@virtualopensystems.com> --- hw/arm/sysbus-fdt.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c index 9d28797..9ad7912 100644 --- a/hw/arm/sysbus-fdt.c +++ b/hw/arm/sysbus-fdt.c @@ -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 */ }; -- 1.9.1