From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45141) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z3Ppd-0001d5-Vl for qemu-devel@nongnu.org; Fri, 12 Jun 2015 10:21:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z3PpY-0001lP-VZ for qemu-devel@nongnu.org; Fri, 12 Jun 2015 10:21:17 -0400 Received: from mail-wi0-f170.google.com ([209.85.212.170]:36635) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z3PpY-0001lF-PH for qemu-devel@nongnu.org; Fri, 12 Jun 2015 10:21:12 -0400 Received: by wigg3 with SMTP id g3so19029451wig.1 for ; Fri, 12 Jun 2015 07:21:12 -0700 (PDT) From: Baptiste Reynal Date: Fri, 12 Jun 2015 16:20:10 +0200 Message-Id: <1434118810-28219-7-git-send-email-b.reynal@virtualopensystems.com> In-Reply-To: <1434118810-28219-1-git-send-email-b.reynal@virtualopensystems.com> References: <1434118810-28219-1-git-send-email-b.reynal@virtualopensystems.com> Subject: [Qemu-devel] [RFC 6/6] hw/arm/sysbus-fdt: add smmu masters in device tree List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: iommu@lists.linux-foundation.org, qemu-devel@nongnu.org Cc: Baptiste Reynal , Alex Williamson , tech@virtualopensystems.com, will.deacon@arm.com, Peter Maydell This patch adds a function to bind a device as an SMMU master in the device tree. Currently, only one device is supported. A device can be set as SMMU master by using the "x-iommu" argument on the command line: -device pl330,x-iommu=true Signed-off-by: Baptiste Reynal --- hw/arm/sysbus-fdt.c | 35 +++++++++++++++++++++++++++++++++++ hw/vfio/platform.c | 1 + include/hw/vfio/vfio-platform.h | 1 + 3 files changed, 37 insertions(+) diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c index 67f4425..356f644 100644 --- a/hw/arm/sysbus-fdt.c +++ b/hw/arm/sysbus-fdt.c @@ -101,6 +101,38 @@ static const NodeCreationPair add_fdt_node_functions[] = { {"", NULL}, /* last element */ }; +static int add_smmu_master(SysBusDevice *sbdev, void *opaque) +{ + if (object_dynamic_cast(OBJECT(sbdev), TYPE_VFIO_PLATFORM) && + VFIO_PLATFORM_DEVICE(sbdev)->iommu_master) { + int master[2]; + char *smmu_nodename, *master_nodename; + uint64_t mmio_base; + PlatformBusFDTData *data = opaque; + PlatformBusDevice *pbus = data->pbus; + void *fdt = data->fdt; + VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev); + VFIODevice *vbasedev = &vdev->vbasedev; + const char *parent_node = data->pbus_node_name; + + smmu_nodename = g_strdup_printf("/smmu@%" PRIx64, vsmmu->base); + mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); + + master_nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node, + vbasedev->name, + mmio_base); + + master[0] = cpu_to_be32(qemu_fdt_get_phandle(fdt, master_nodename)); + master[1] = cpu_to_be32(vbasedev->group->groupid); + + qemu_fdt_setprop(fdt, smmu_nodename, "mmu-masters", + master, 2*sizeof(int)); + + } + + return 0; +} + /** * add_fdt_node - add the device tree node of a dynamic sysbus device * @@ -193,6 +225,9 @@ static void add_all_platform_bus_fdt_nodes(ARMPlatformBusFDTParams *fdt_params) /* Loop through all dynamic sysbus devices and create their node */ foreach_dynamic_sysbus_device(add_fdt_node, &data); + if (vsmmu) { + foreach_dynamic_sysbus_device(add_smmu_master, &data); + } g_free(node); } diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c index 6192458..d4ea297 100644 --- a/hw/vfio/platform.c +++ b/hw/vfio/platform.c @@ -585,6 +585,7 @@ static Property vfio_platform_dev_properties[] = { DEFINE_PROP_BOOL("x-mmap", VFIOPlatformDevice, vbasedev.allow_mmap, true), DEFINE_PROP_UINT32("mmap-timeout-ms", VFIOPlatformDevice, mmap_timeout, 1100), + DEFINE_PROP_BOOL("x-iommu", VFIOPlatformDevice, iommu_master, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/vfio/vfio-platform.h b/include/hw/vfio/vfio-platform.h index 26b2ad6..8f5d980 100644 --- a/include/hw/vfio/vfio-platform.h +++ b/include/hw/vfio/vfio-platform.h @@ -57,6 +57,7 @@ typedef struct VFIOPlatformDevice { uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */ QEMUTimer *mmap_timer; /* allows fast-path resume after IRQ hit */ QemuMutex intp_mutex; /* protect the intp_list IRQ state */ + bool iommu_master; /* is the device a master to the vSMMU ? */ } VFIOPlatformDevice; typedef struct VFIOPlatformDeviceClass { -- 2.4.3