On 8/15/2016 12:03 PM, Peter Maydell wrote: > Just cc'ing Eric on his new email address... > > thanks > -- PMM > > On 14 August 2016 at 16:42, Shanker Donthineni <shank...@codeaurora.org> > wrote: >> This patch introduces the Qualcomm Technologies, Inc HIDMA device and >> allows passthrough the host HIDMA device to a guest machine using the >> vfio-platform framework. >> >> A platform device tree node is created for the guest machine which >> contains the compat string 'qcom,hidma-1.0', mmio regions, active high >> SPIs, and an optional property dma-coherent. >> >> Signed-off-by: Vikram Sethi <vikr...@codeaurora.org> >> Signed-off-by: Shanker Donthineni <shank...@codeaurora.org> >> --- >> Changes sicnce v1: >> combined patches [v1 1/2] and [v1 2/2]. >> added '#include "qemu/osdep.h'. >> changed compact string to 'qcom,hidma-1.0' to match the host driver. >> set dma-coherent property based on the IOMMU coherency status. >> >> hw/arm/sysbus-fdt.c | 67 >> +++++++++++++++++++++++++++++++++++++++ >> hw/vfio/Makefile.objs | 1 + >> hw/vfio/qcom-hidma.c | 58 +++++++++++++++++++++++++++++++++ >> include/hw/vfio/vfio-qcom-hidma.h | 50 +++++++++++++++++++++++++++++ >> 4 files changed, 176 insertions(+) >> create mode 100644 hw/vfio/qcom-hidma.c >> create mode 100644 include/hw/vfio/vfio-qcom-hidma.h >> >> diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c >> index 5debb33..bdf8cbb 100644 >> --- a/hw/arm/sysbus-fdt.c >> +++ b/hw/arm/sysbus-fdt.c >> @@ -27,6 +27,7 @@ >> #include "qemu-common.h" >> #ifdef CONFIG_LINUX >> #include <linux/vfio.h> >> +#include <sys/ioctl.h> >> #endif >> #include "hw/arm/sysbus-fdt.h" >> #include "qemu/error-report.h" >> @@ -36,6 +37,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-qcom-hidma.h" >> #include "hw/arm/fdt.h" >> >> /* >> @@ -262,6 +264,70 @@ static int >> add_calxeda_midway_xgmac_fdt_node(SysBusDevice *sbdev, void *opaque) >> return 0; >> } >> >> +/** >> + * add_qcom_hidma_fdt_node >> + * >> + * Generates a simple node with following properties: >> + * compatible string, regs, active-high interrupts, and optional >> dma-coherent >> + */ >> +static int add_qcom_hidma_fdt_node(SysBusDevice *sbdev, void *opaque) >> +{ >> + VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev); >> + struct VFIOGroup *group = vdev->vbasedev.group; >> + VFIODevice *vbasedev = &vdev->vbasedev; >> + PlatformBusFDTData *data = opaque; >> + const char *parent_node = data->pbus_node_name; >> + PlatformBusDevice *pbus = data->pbus; >> + uint32_t *irq_attr, *reg_attr; >> + uint64_t mmio_base, irq_number; >> + void *fdt = data->fdt; >> + int compat_str_len, i, ret; >> + char *nodename; >> + >> + mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); >> + nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node, >> + vbasedev->name, mmio_base); >> + assert(nodename); >> + qemu_fdt_add_subnode(fdt, nodename); >> + >> + compat_str_len = strlen(vdev->compat) + 1; >> + qemu_fdt_setprop(fdt, nodename, "compatible", >> + vdev->compat, compat_str_len); >> + >> + /* Check if the DMA cache coherency was enabled in IOMMU */ >> + ret = ioctl(group->container->fd, VFIO_CHECK_EXTENSION, >> VFIO_DMA_CC_IOMMU); >> + if (ret > 0) { >> + qemu_fdt_setprop(fdt, nodename, "dma-coherent", "", 0); >> + } >> + >> + reg_attr = g_new(uint32_t, vbasedev->num_regions * 2); >> + assert(reg_attr); >> + 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); >> + assert(irq_attr); >> + 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); >> + irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_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; >> +} >> + >> /* AMD xgbe properties whose values are copied/pasted from host */ >> static HostProperty amd_xgbe_copied_properties[] = { >> {"compatible", false}, >> @@ -420,6 +486,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_QCOM_HIDMA, add_qcom_hidma_fdt_node}, >> #endif >> {"", NULL}, /* last element */ >> }; >> diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs >> index c25e32b..ac38c8f 100644 >> --- a/hw/vfio/Makefile.objs >> +++ b/hw/vfio/Makefile.objs >> @@ -5,4 +5,5 @@ obj-$(CONFIG_SOFTMMU) += platform.o >> obj-$(CONFIG_SOFTMMU) += calxeda-xgmac.o >> obj-$(CONFIG_SOFTMMU) += amd-xgbe.o >> obj-$(CONFIG_SOFTMMU) += spapr.o >> +obj-$(CONFIG_SOFTMMU) += qcom-hidma.o >> endif >> diff --git a/hw/vfio/qcom-hidma.c b/hw/vfio/qcom-hidma.c >> new file mode 100644 >> index 0000000..ddb3c34 >> --- /dev/null >> +++ b/hw/vfio/qcom-hidma.c >> @@ -0,0 +1,58 @@ >> +/* >> + * Qualcomm Technologies, Inc VFIO HiDMA platform device >> + * >> + * Copyright (c) 2016, The Linux Foundation. All rights reserved. >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 and >> + * only version 2 as published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + * >> + */ >> +#include "qemu/osdep.h" >> +#include "hw/vfio/vfio-qcom-hidma.h" >> + >> +static void qcom_hidma_realize(DeviceState *dev, Error **errp) >> +{ >> + VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(dev); >> + VFIOQcomHidmaDeviceClass *k = VFIO_QCOM_HIDMA_DEVICE_GET_CLASS(dev); >> + >> + vdev->compat = g_strdup("qcom,hidma-1.0"); >> + >> + k->parent_realize(dev, errp); >> +} >> + >> +static const VMStateDescription vfio_platform_vmstate = { >> + .name = TYPE_VFIO_QCOM_HIDMA, >> + .unmigratable = 1, >> +}; >> + >> +static void vfio_qcom_hidma_class_init(ObjectClass *klass, void *data) >> +{ >> + DeviceClass *dc = DEVICE_CLASS(klass); >> + VFIOQcomHidmaDeviceClass *vcxc = VFIO_QCOM_HIDMA_DEVICE_CLASS(klass); >> + >> + vcxc->parent_realize = dc->realize; >> + dc->realize = qcom_hidma_realize; >> + dc->desc = "VFIO QCOM HIDMA"; >> + dc->vmsd = &vfio_platform_vmstate; >> +} >> + >> +static const TypeInfo vfio_qcom_hidma_dev_info = { >> + .name = TYPE_VFIO_QCOM_HIDMA, >> + .parent = TYPE_VFIO_PLATFORM, >> + .instance_size = sizeof(VFIOQcomHidmaDevice), >> + .class_init = vfio_qcom_hidma_class_init, >> + .class_size = sizeof(VFIOQcomHidmaDeviceClass), >> +}; >> + >> +static void register_qcom_hidma_dev_type(void) >> +{ >> + type_register_static(&vfio_qcom_hidma_dev_info); >> +} >> + >> +type_init(register_qcom_hidma_dev_type) >> diff --git a/include/hw/vfio/vfio-qcom-hidma.h >> b/include/hw/vfio/vfio-qcom-hidma.h >> new file mode 100644 >> index 0000000..23cd66c >> --- /dev/null >> +++ b/include/hw/vfio/vfio-qcom-hidma.h >> @@ -0,0 +1,50 @@ >> +/* >> + * Qualcomm Technologies, Inc VFIO HiDMA platform device >> + * >> + * Copyright (c) 2016, The Linux Foundation. All rights reserved. >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 and >> + * only version 2 as published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + * >> + */ >> + >> +#ifndef HW_VFIO_VFIO_QCOM_HIDMA_H >> +#define HW_VFIO_VFIO_QCOM_HIDMA_H >> + >> +#include "hw/vfio/vfio-platform.h" >> + >> +#define TYPE_VFIO_QCOM_HIDMA "vfio-qcom-hidma" >> + >> +/** >> + * This device exposes: >> + * - MMIO regions corresponding to its register space >> + * - Active high IRQs >> + * - Optional property 'dma-coherent' >> + */ >> +typedef struct VFIOQcomHidmaDevice { >> + VFIOPlatformDevice vdev; >> +} VFIOQcomHidmaDevice; >> + >> +typedef struct VFIOQcomHidmaDeviceClass { >> + /*< private >*/ >> + VFIOPlatformDeviceClass parent_class; >> + /*< public >*/ >> + DeviceRealize parent_realize; >> +} VFIOQcomHidmaDeviceClass; >> + >> +#define VFIO_QCOM_HIDMA_DEVICE(obj) \ >> + OBJECT_CHECK(VFIOQcomHidmaDevice, (obj), TYPE_VFIO_QCOM_HIDMA) >> +#define VFIO_QCOM_HIDMA_DEVICE_CLASS(klass) \ >> + OBJECT_CLASS_CHECK(VFIOQcomHidmaDeviceClass, (klass), \ >> + TYPE_VFIO_QCOM_HIDMA) >> +#define VFIO_QCOM_HIDMA_DEVICE_GET_CLASS(obj) \ >> + OBJECT_GET_CLASS(VFIOQcomHidmaDeviceClass, (obj), \ >> + TYPE_VFIO_QCOM_HIDMA) >> + >> +#endif >> -- >> Qualcomm Datacenter Technologies, Inc. on behalf of the Qualcomm >> Technologies, Inc. >> Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux >> Foundation Collaborative Project. >> > >
Tested-by: Sinan Kaya <ok...@codeaurora.org> -- Sinan Kaya Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.