From mboxrd@z Thu Jan 1 00:00:00 1970 From: Hemant Agrawal Subject: [PATCHv7 44/47] bus/fslmc: add support for DMA mapping for ARM SMMU Date: Thu, 16 Feb 2017 06:09:43 +0530 Message-ID: <1487205586-6785-45-git-send-email-hemant.agrawal@nxp.com> References: <1485172803-17288-1-git-send-email-hemant.agrawal@nxp.com> <1487205586-6785-1-git-send-email-hemant.agrawal@nxp.com> Mime-Version: 1.0 Content-Type: text/plain Cc: , , , , , To: Return-path: Received: from NAM03-DM3-obe.outbound.protection.outlook.com (mail-dm3nam03on0070.outbound.protection.outlook.com [104.47.41.70]) by dpdk.org (Postfix) with ESMTP id 015FBFB03 for ; Wed, 15 Feb 2017 20:07:55 +0100 (CET) In-Reply-To: <1487205586-6785-1-git-send-email-hemant.agrawal@nxp.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Signed-off-by: Hemant Agrawal --- drivers/bus/fslmc/fslmc_vfio.c | 96 +++++++++++++++++++++++++++++ drivers/bus/fslmc/fslmc_vfio.h | 1 + drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 + 3 files changed, 98 insertions(+) diff --git a/drivers/bus/fslmc/fslmc_vfio.c b/drivers/bus/fslmc/fslmc_vfio.c index fc017fc..5f1d1b7 100644 --- a/drivers/bus/fslmc/fslmc_vfio.c +++ b/drivers/bus/fslmc/fslmc_vfio.c @@ -76,8 +76,10 @@ static struct fslmc_vfio_group vfio_groups[VFIO_MAX_GRP]; static struct fslmc_vfio_container vfio_containers[VFIO_MAX_CONTAINERS]; static int container_device_fd; +static uint32_t *msi_intr_vaddr; void *(*rte_mcp_ptr_list); static uint32_t mcp_id; +static int is_dma_done; static int vfio_connect_container(struct fslmc_vfio_group *vfio_group) { @@ -147,6 +149,35 @@ static int vfio_connect_container(struct fslmc_vfio_group *vfio_group) return 0; } +static int vfio_map_irq_region(struct fslmc_vfio_group *group) +{ + int ret; + unsigned long *vaddr = NULL; + struct vfio_iommu_type1_dma_map map = { + .argsz = sizeof(map), + .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE, + .vaddr = 0x6030000, + .iova = 0x6030000, + .size = 0x1000, + }; + + vaddr = (unsigned long *)mmap(NULL, 0x1000, PROT_WRITE | + PROT_READ, MAP_SHARED, container_device_fd, 0x6030000); + if (vaddr == MAP_FAILED) { + FSLMC_VFIO_LOG(ERR, "Unable to map region (errno = %d)", errno); + return -errno; + } + + msi_intr_vaddr = (uint32_t *)((char *)(vaddr) + 64); + map.vaddr = (unsigned long)vaddr; + ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, &map); + if (ret == 0) + return 0; + + FSLMC_VFIO_LOG(ERR, "VFIO_IOMMU_MAP_DMA fails (errno = %d)", errno); + return -errno; +} + int vfio_dmamap_mem_region(uint64_t vaddr, uint64_t iova, uint64_t size) @@ -170,6 +201,71 @@ int vfio_dmamap_mem_region(uint64_t vaddr, return 0; } +int rte_fslmc_vfio_dmamap(void) +{ + int ret; + struct fslmc_vfio_group *group; + struct vfio_iommu_type1_dma_map dma_map = { + .argsz = sizeof(struct vfio_iommu_type1_dma_map), + .flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE, + }; + + int i; + const struct rte_memseg *memseg; + + if (is_dma_done) + return 0; + is_dma_done = 1; + + for (i = 0; i < RTE_MAX_MEMSEG; i++) { + memseg = rte_eal_get_physmem_layout(); + if (memseg == NULL) { + FSLMC_VFIO_LOG(ERR, "Cannot get physical layout."); + return -ENODEV; + } + + if (memseg[i].addr == NULL && memseg[i].len == 0) + break; + + dma_map.size = memseg[i].len; + dma_map.vaddr = memseg[i].addr_64; +#ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA + dma_map.iova = memseg[i].phys_addr; +#else + dma_map.iova = dma_map.vaddr; +#endif + + /* SET DMA MAP for IOMMU */ + group = &vfio_groups[0]; + + if (!group->container) { + FSLMC_VFIO_LOG(ERR, "Container is not connected "); + return -1; + } + + FSLMC_VFIO_LOG(DEBUG, "-->Initial SHM Virtual ADDR %llX", + dma_map.vaddr); + FSLMC_VFIO_LOG(DEBUG, "-----> DMA size 0x%llX\n", dma_map.size); + ret = ioctl(group->container->fd, VFIO_IOMMU_MAP_DMA, + &dma_map); + if (ret) { + FSLMC_VFIO_LOG(ERR, "VFIO_IOMMU_MAP_DMA API" + "(errno = %d)", errno); + return ret; + } + FSLMC_VFIO_LOG(DEBUG, "-----> dma_map.vaddr = 0x%llX", + dma_map.vaddr); + } + + /* TODO - This is a W.A. as VFIO currently does not add the mapping of + * the interrupt region to SMMU. This should be removed once the + * support is added in the Kernel. + */ + vfio_map_irq_region(group); + + return 0; +} + static int64_t vfio_map_mcp_obj(struct fslmc_vfio_group *group, char *mcp_obj) { int64_t v_addr = (int64_t)MAP_FAILED; diff --git a/drivers/bus/fslmc/fslmc_vfio.h b/drivers/bus/fslmc/fslmc_vfio.h index 80c6869..53dd0b7 100644 --- a/drivers/bus/fslmc/fslmc_vfio.h +++ b/drivers/bus/fslmc/fslmc_vfio.h @@ -70,6 +70,7 @@ int vfio_dmamap_mem_region( int fslmc_vfio_setup_group(void); int fslmc_vfio_process_group(void); +int rte_fslmc_vfio_dmamap(void); /* create dpio device */ int dpaa2_create_dpio_device(struct fslmc_vfio_device *vdev, diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map index 4a8f478..505873a 100644 --- a/drivers/bus/fslmc/rte_bus_fslmc_version.map +++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map @@ -52,6 +52,7 @@ DPDK_17.02 { per_lcore__dpaa2_io; rte_fslmc_driver_register; rte_fslmc_driver_unregister; + rte_fslmc_vfio_dmamap; rte_mcp_ptr_list; local: *; -- 1.9.1