From commits-return-9685-archive-asf-public=cust-asf.ponee.io@nuttx.apache.org Fri May 15 22:11:46 2020 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with SMTP id 56C05180675 for ; Sat, 16 May 2020 00:11:46 +0200 (CEST) Received: (qmail 78506 invoked by uid 500); 15 May 2020 22:11:45 -0000 Mailing-List: contact commits-help@nuttx.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@nuttx.apache.org Delivered-To: mailing list commits@nuttx.apache.org Received: (qmail 78460 invoked by uid 99); 15 May 2020 22:11:45 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 15 May 2020 22:11:45 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 244938BFAE; Fri, 15 May 2020 22:11:44 +0000 (UTC) Date: Fri, 15 May 2020 22:11:45 +0000 To: "commits@nuttx.apache.org" Subject: [incubator-nuttx] 02/07: arch/arm/src/stm32h7/stm32_sdmmc: check IDMA buffer address MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit From: aguettouche@apache.org In-Reply-To: <158958070336.9672.3151925592409629599@gitbox.apache.org> References: <158958070336.9672.3151925592409629599@gitbox.apache.org> X-Git-Host: gitbox.apache.org X-Git-Repo: incubator-nuttx X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Rev: 07bd520ccb36ac51aaa8347886d576fe68ec8979 X-Git-NotificationType: diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated Message-Id: <20200515221145.244938BFAE@gitbox.apache.org> This is an automated email from the ASF dual-hosted git repository. aguettouche pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git commit 07bd520ccb36ac51aaa8347886d576fe68ec8979 Author: Pierre-Olivier Vauboin AuthorDate: Tue Mar 31 17:51:01 2020 +0200 arch/arm/src/stm32h7/stm32_sdmmc: check IDMA buffer address For SDMMC1, IDMA cannot access SRAM123 or SRAM4. Refer to ST AN5200 for details. This patch makes stm32_dmapreflight check the buffer address and return an error when the buffer is located in a invalid address space. This does not fix the hardware limitation but at least makes it visible. --- arch/arm/src/stm32h7/stm32_sdmmc.c | 64 ++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/arch/arm/src/stm32h7/stm32_sdmmc.c b/arch/arm/src/stm32h7/stm32_sdmmc.c index 99a98d9..93af586 100644 --- a/arch/arm/src/stm32h7/stm32_sdmmc.c +++ b/arch/arm/src/stm32h7/stm32_sdmmc.c @@ -98,6 +98,12 @@ * be monitored off the an HP work thread for a residual of less than * FIFO_SIZE_IN_BYTES / 2. * + * HW Issues when using IDMA + * + * The DMA buffer must be located in a zone accessible via IDMA. + * For SDMMC1, IDMA cannot access SRAM123 or SRAM4. Refer to ST AN5200. + * Buffer validity is checked when CONFIG_ARCH_HAVE_SDIO_PREFLIGHT is set. + * * MDMA is only available on for SDMMC1 and Not supported at this time. * * Required system configuration options: @@ -110,13 +116,13 @@ * APIs to manage concurrent accesses on the SDMMC bus. This is not * needed for the simple case of a single SD card, for example. * CONFIG_STM32H7_SDMMC_IDMA - Enable SDMMC IDMA. - * DMA support for SDMMC. If disabled disabled, the SDMMC will work in + * DMA support for SDMMC. If disabled, the SDMMC will work in * interrupt mode and still use the IDMA to a local buffer for data * lengths less the 32 bytes due to the FIFO limitations. * CONFIG_SDMMC1/2_WIDTH_D1_ONLY - This may be selected to force the driver * operate with only a single data line (the default is to use all * 4 SD data lines). - * CONFIG_CONFIG_STM32H7_SDMMC_XFRDEBUG - Enables some very low-level debug + * CONFIG_STM32H7_SDMMC_XFRDEBUG - Enables some very low-level debug * output This also requires CONFIG_DEBUG_FS and CONFIG_DEBUG_INFO * CONFIG_SDMMC1/2_SDIO_MODE * Build ins additional support needed only for SDIO cards (vs. SD memory @@ -141,6 +147,11 @@ #if !defined(CONFIG_STM32H7_SDMMC_IDMA) # warning "Large Non-DMA transfer may result in RX overrun failures" +#elif defined(CONFIG_STM32H7_SDMMC1) +# define SRAM123_START STM32_SRAM123_BASE +# define SRAM123_END (SRAM123_START + STM32H7_SRAM123_SIZE) +# define SRAM4_START STM32_SRAM4_BASE +# define SRAM4_END (SRAM4_START + STM32H7_SRAM4_SIZE) #endif #ifndef CONFIG_SCHED_WORKQUEUE @@ -153,7 +164,7 @@ #endif #if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_FEATURES) -# undef CONFIG_CONFIG_STM32H7_SDMMC_XFRDEBUG +# undef CONFIG_STM32H7_SDMMC_XFRDEBUG #endif #ifdef CONFIG_SDMMC1_SDIO_PULLUP @@ -1515,6 +1526,21 @@ static void stm32_endtransfer(struct stm32_dev_s *priv, sdmmc_putreg32(priv, STM32_SDMMC_XFRDONE_ICR, STM32_SDMMC_ICR_OFFSET); +#if defined(CONFIG_STM32H7_SDMMC_IDMA) && \ + !defined(CONFIG_ARCH_HAVE_SDIO_DELAYED_INVLDT) + /* invalidate dcache in case of DMA receive. */ + + if (priv->receivecnt) + { + up_invalidate_dcache((uintptr_t)priv->buffer, + (uintptr_t)priv->buffer + priv->remaining); + } +#endif + + /* DMA debug instrumentation */ + + stm32_sample(priv, SAMPLENDX_END_TRANSFER); + /* Mark the transfer finished */ priv->remaining = 0; @@ -3038,7 +3064,29 @@ static int stm32_registercallback(FAR struct sdio_dev_s *dev, static int stm32_dmapreflight(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, size_t buflen) { - /* DMA must be possible to the buffer */ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + + /* IDMA must be possible to the buffer */ + +#if defined(CONFIG_STM32H7_SDMMC1) + if (priv->base == STM32_SDMMC1_BASE) + { + /* For SDMMC1, IDMA cannot access SRAM123 or SRAM4. */ + + if (((uintptr_t)buffer >= SRAM123_START && + (uintptr_t)buffer + buflen <= SRAM123_END) || + ((uintptr_t)buffer >= SRAM4_START && + (uintptr_t)buffer + buflen <= SRAM4_END)) + { + mcerr("invalid IDMA address " + "buffer:0x%08x end:0x%08x\n", + buffer, buffer + buflen - 1); + return -EFAULT; + } + } +#endif # if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH) /* buffer alignment is required for DMA transfers with dcache in buffered @@ -3048,15 +3096,11 @@ static int stm32_dmapreflight(FAR struct sdio_dev_s *dev, * ARMV7M_DCACHE_LINESIZE boundaries. */ - struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; - - DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); - if (buffer != priv->rxfifo && (((uintptr_t)buffer & (ARMV7M_DCACHE_LINESIZE - 1)) != 0 || ((uintptr_t)(buffer + buflen) & (ARMV7M_DCACHE_LINESIZE - 1)) != 0)) { - dmainfo("stm32_dmapreflight: dcache unaligned " + mcerr("dcache unaligned " "buffer:0x%08x end:0x%08x\n", buffer, buffer + buflen - 1); return -EFAULT; @@ -3276,7 +3320,7 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, static int stm32_dmadelydinvldt(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, size_t buflen) { - /* Invaliate cache to physical memory when not in DTCM memory. */ + /* Invalidate cache to physical memory when not in DTCM memory. */ if ((uintptr_t)buffer < DTCM_START || (uintptr_t)buffer + buflen > DTCM_END)