Hi, On 21/10/2016 03:22, Rick Song wrote: > This patch allows the instantiation of the vfio-hisi-hnsvf device > from the QEMU command line (-device vfio-hisi-hnsvf,host="<device>"). > A specialized device tree node is created for the guest, containing > compat, dma-coherent, reg and interrupts properties.
For additional devices, Peter requested we re-structured the sysbus-fdt.c file to avoid it gets too large. We need to define relevant helpers and put node creation function elsewhere. Similarly I can propose something next week except if you want to do it. Thanks Eric > > Signed-off-by: Rick Song <songwen...@huawei.com> > --- > hw/arm/sysbus-fdt.c | 71 > +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 71 insertions(+) > > diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c > index d68e3dc..207586f 100644 > --- a/hw/arm/sysbus-fdt.c > +++ b/hw/arm/sysbus-fdt.c > @@ -36,6 +36,7 @@ > #include "hw/vfio/vfio-platform.h" > #include "hw/vfio/vfio-calxeda-xgmac.h" > #include "hw/vfio/vfio-amd-xgbe.h" > +#include "hw/vfio/vfio-hisi-hnsvf.h" > #include "hw/arm/fdt.h" > > /* > @@ -413,6 +414,75 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, > void *opaque) > return 0; > } > > +/** > + * add_hisi_hnsvf_fdt_node > + * > + * Generates a simple node with following properties: > + * compatible string, regs, interrupts, dma-coherent > + */ > +static int add_hisi_hnsvf_fdt_node(SysBusDevice *sbdev, void *opaque) > +{ > + PlatformBusFDTData *data = opaque; > + PlatformBusDevice *pbus = data->pbus; > + void *fdt = data->fdt; > + const char *parent_node = data->pbus_node_name; > + int compat_str_len, i; > + char *nodename; > + uint32_t *irq_attr, *reg_attr; > + uint64_t mmio_base, irq_number; > + VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev); > + VFIODevice *vbasedev = &vdev->vbasedev; > + VFIOINTp *intp; > + > + mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); > + nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node, > + vbasedev->name, mmio_base); > + qemu_fdt_add_subnode(fdt, nodename); > + > + compat_str_len = strlen(vdev->compat) + 1; > + qemu_fdt_setprop(fdt, nodename, "compatible", > + vdev->compat, compat_str_len); > + > + qemu_fdt_setprop(fdt, nodename, "dma-coherent", "", 0); > + > + reg_attr = g_new(uint32_t, vbasedev->num_regions * 2); > + for (i = 0; i < vbasedev->num_regions; i++) { > + mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i); > + reg_attr[2 * i] = cpu_to_be32(mmio_base); > + reg_attr[2 * i + 1] = cpu_to_be32( > + memory_region_size(vdev->regions[i]->mem)); > + } > + qemu_fdt_setprop(fdt, nodename, "reg", reg_attr, > + vbasedev->num_regions * 2 * sizeof(uint32_t)); > + > + irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3); > + for (i = 0; i < vbasedev->num_irqs; i++) { > + irq_number = platform_bus_get_irqn(pbus, sbdev , i) > + + data->irq_start; > + irq_attr[3 * i] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI); > + irq_attr[3 * i + 1] = cpu_to_be32(irq_number); > + > + QLIST_FOREACH(intp, &vdev->intp_list, next) { > + if (intp->pin == i) { > + break; > + } > + } > + > + if (intp->flags & VFIO_IRQ_INFO_AUTOMASKED) { > + irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_HI); > + } else { > + irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI); > + } > + } > + qemu_fdt_setprop(fdt, nodename, "interrupts", > + irq_attr, vbasedev->num_irqs * 3 * sizeof(uint32_t)); > + g_free(irq_attr); > + g_free(reg_attr); > + g_free(nodename); > + return 0; > + > +} > + > #endif /* CONFIG_LINUX */ > > /* list of supported dynamic sysbus devices */ > @@ -420,6 +490,7 @@ static const NodeCreationPair add_fdt_node_functions[] = { > #ifdef CONFIG_LINUX > {TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node}, > {TYPE_VFIO_AMD_XGBE, add_amd_xgbe_fdt_node}, > + {TYPE_VFIO_HISI_HNSVF, add_hisi_hnsvf_fdt_node}, > #endif > {"", NULL}, /* last element */ > }; >