From ae433eaa84368151a2b51b105bbb0bc17227e88d Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 17 Mar 2015 09:28:27 -0600 Subject: [PATCH] SAMV7: Use D-Cache clean/flush/invalidate by range in EMAC and XDMAC drivers --- arch/arm/src/armv7-m/cache.h | 6 ---- arch/arm/src/samv7/sam_emac.c | 66 +++++++++------------------------- arch/arm/src/samv7/sam_xdmac.c | 40 ++------------------- 3 files changed, 19 insertions(+), 93 deletions(-) diff --git a/arch/arm/src/armv7-m/cache.h b/arch/arm/src/armv7-m/cache.h index b1d21192889..333c3ed5f07 100644 --- a/arch/arm/src/armv7-m/cache.h +++ b/arch/arm/src/armv7-m/cache.h @@ -289,13 +289,11 @@ void arch_disable_dcache(void); * ****************************************************************************/ -#if 0 /* Not implemented */ #ifdef CONFIG_ARMV7M_DCACHE void arch_invalidate_dcache(uintptr_t start, uintptr_t end); #else # define arch_invalidate_dcache(s,e) #endif -#endif /**************************************************************************** * Name: arch_invalidate_dcache_all @@ -338,13 +336,11 @@ void arch_invalidate_dcache_all(void); * ****************************************************************************/ -#if 0 /* Not implemented */ #ifdef CONFIG_ARMV7M_DCACHE void arch_clean_dcache(uintptr_t start, uintptr_t end); #else # define arch_clean_dcache(s,e) #endif -#endif /**************************************************************************** * Name: arch_clean_dcache_all @@ -393,13 +389,11 @@ void arch_clean_dcache_all(void); * ****************************************************************************/ -#if 0 /* Not implemented */ #ifdef CONFIG_ARMV7M_DCACHE void arch_flush_dcache(uintptr_t start, uintptr_t end); #else # define arch_flush_dcache(s,e) #endif -#endif /**************************************************************************** * Name: arch_flush_dcache_all diff --git a/arch/arm/src/samv7/sam_emac.c b/arch/arm/src/samv7/sam_emac.c index 8428df087a9..12e3801152c 100644 --- a/arch/arm/src/samv7/sam_emac.c +++ b/arch/arm/src/samv7/sam_emac.c @@ -316,11 +316,6 @@ #define EMAC_RX_UNITSIZE 128 /* Fixed size for RX buffer */ #define EMAC_TX_UNITSIZE CONFIG_NET_ETH_MTU /* MAX size for Ethernet packet */ -/* These cache operations are not yet available */ - -#undef HAVE_CLEAN_DCACHE_RANGE -#undef HAVE_INVALIDATE_DCACHE_RANGE - /* Timing *******************************************************************/ /* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per * second @@ -1118,11 +1113,8 @@ static int sam_transmit(struct sam_emac_s *priv) /* Driver managed the ring buffer */ memcpy((void *)txdesc->addr, dev->d_buf, dev->d_len); - -#ifdef HAVE_CLEAN_DCACHE_RANGE arch_clean_dcache((uintptr_t)txdesc->addr, (uintptr_t)txdesc->addr + dev->d_len); -#endif } /* Update TX descriptor status. */ @@ -1136,13 +1128,8 @@ static int sam_transmit(struct sam_emac_s *priv) /* Update the descriptor status and flush the updated value to RAM */ txdesc->status = status; - -#ifdef HAVE_CLEAN_DCACHE_RANGE arch_clean_dcache((uint32_t)txdesc, (uint32_t)txdesc + sizeof(struct emac_txdesc_s)); -#else - arch_clean_dcache_all(); -#endif /* Increment the head index */ @@ -1346,13 +1333,13 @@ static int sam_recvframe(struct sam_emac_s *priv) rxdesc = &priv->rxdesc[rxndx]; isframe = false; - /* Invalidate the RX descriptor to force re-fetching from RAM */ + /* Invalidate the RX descriptor to force re-fetching from RAM. + * REVISIT: If the rxdesc is not aligned with the cacheline boundary + * then won't this also invalidate some surrounding memory? + */ -#warning FIXME!!! -#ifdef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */ arch_invalidate_dcache((uintptr_t)rxdesc, (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); -#endif nllvdbg("rxndx: %d\n", rxndx); @@ -1373,14 +1360,11 @@ static int sam_recvframe(struct sam_emac_s *priv) rxdesc = &priv->rxdesc[priv->rxndx]; rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); -#warning FIXME!!! -#ifdef HAVE_CLEAN_DCACHE_RANGE /* Flush the modified RX descriptor to RAM */ arch_clean_dcache((uintptr_t)rxdesc, (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); -#endif /* Increment the RX index */ @@ -1421,14 +1405,11 @@ static int sam_recvframe(struct sam_emac_s *priv) rxdesc = &priv->rxdesc[priv->rxndx]; rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); -#warning FIXME!!! -#ifdef HAVE_CLEAN_DCACHE_RANGE /* Flush the modified RX descriptor to RAM */ arch_clean_dcache((uintptr_t)rxdesc, (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); -#endif /* Increment the RX index */ @@ -1451,14 +1432,14 @@ static int sam_recvframe(struct sam_emac_s *priv) /* Get the data source. Invalidate the source memory region to * force reload from RAM. + * + * REVISIT: If the rxdesc is not aligned with the cacheline + * boundary then won't this also invalidate some surrounding + * memory? */ src = (const uint8_t *)(rxdesc->addr & EMACRXD_ADDR_MASK); - -#warning FIXME!!! -#ifdef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */ arch_invalidate_dcache((uintptr_t)src, (uintptr_t)src + copylen); -#endif /* And do the copy */ @@ -1486,14 +1467,11 @@ static int sam_recvframe(struct sam_emac_s *priv) rxdesc = &priv->rxdesc[priv->rxndx]; rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); -#warning FIXME!!! -#ifdef HAVE_CLEAN_DCACHE_RANGE /* Flush the modified RX descriptor to RAM */ arch_clean_dcache((uintptr_t)rxdesc, (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); -#endif /* Increment the RX index */ @@ -1529,14 +1507,11 @@ static int sam_recvframe(struct sam_emac_s *priv) rxdesc->addr &= ~(EMACRXD_ADDR_OWNER); -#warning FIXME!!! -#ifdef HAVE_CLEAN_DCACHE_RANGE /* Flush the modified RX descriptor to RAM */ arch_clean_dcache((uintptr_t)rxdesc, (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); -#endif priv->rxndx = rxndx; } @@ -1544,13 +1519,14 @@ static int sam_recvframe(struct sam_emac_s *priv) rxdesc = &priv->rxdesc[rxndx]; -#warning FIXME!!! -#ifdef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */ - /* Invalidate the RX descriptor to force re-fetching from RAM */ + /* Invalidate the RX descriptor to force re-fetching from RAM + * + * REVISIT: If the rxdesc is not aligned with the cacheline boundary + * then won't this also invalidate some surrounding memory? + */ arch_invalidate_dcache((uintptr_t)rxdesc, (uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s)); -#endif } /* No packet was found */ @@ -1747,11 +1723,12 @@ static void sam_txdone(struct sam_emac_s *priv) txdesc = &priv->txdesc[priv->txtail]; -#warning FIXME!!! -#ifdef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */ + /* REVISIT: If the rxdesc is not aligned with the cacheline boundary + * then won't this also invalidate some surrounding memory? + */ + arch_invalidate_dcache((uintptr_t)txdesc, (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); -#endif /* Is this TX descriptor still in use? */ @@ -1801,11 +1778,8 @@ static void sam_txdone(struct sam_emac_s *priv) /* Make sure that the USED bit is set */ txdesc->status = (uint32_t)EMACTXD_STA_USED; -#warning FIXME!!! -#ifdef HAVE_CLEAN_DCACHE_RANGE arch_clean_dcache((uintptr_t)txdesc, (uintptr_t)txdesc + sizeof(struct emac_txdesc_s)); -#endif #endif /* Increment the tail index */ @@ -4075,14 +4049,11 @@ static void sam_txreset(struct sam_emac_s *priv) txdesc[priv->attr->ntxbuffers - 1].status = EMACTXD_STA_USED | EMACTXD_STA_WRAP; -#warning FIXME!!! -#ifdef HAVE_CLEAN_DCACHE_RANGE /* Flush the entire TX descriptor table to RAM */ arch_clean_dcache((uintptr_t)txdesc, (uintptr_t)txdesc + priv->attr->ntxbuffers * sizeof(struct emac_txdesc_s)); -#endif /* Set the Transmit Buffer Queue Pointer Register */ @@ -4139,14 +4110,11 @@ static void sam_rxreset(struct sam_emac_s *priv) rxdesc[priv->attr->nrxbuffers - 1].addr |= EMACRXD_ADDR_WRAP; -#warning FIXME!!! -#ifdef HAVE_CLEAN_DCACHE_RANGE /* Flush the entire RX descriptor table to RAM */ arch_clean_dcache((uintptr_t)rxdesc, (uintptr_t)rxdesc + priv->attr->nrxbuffers * sizeof(struct emac_rxdesc_s)); -#endif /* Set the Receive Buffer Queue Pointer Register */ diff --git a/arch/arm/src/samv7/sam_xdmac.c b/arch/arm/src/samv7/sam_xdmac.c index e4defa6d1dc..a0b99f68bdf 100644 --- a/arch/arm/src/samv7/sam_xdmac.c +++ b/arch/arm/src/samv7/sam_xdmac.c @@ -92,11 +92,6 @@ # define CONFIG_SAMV7_NLLDESC SAMV7_NDMACHAN #endif -/* These cache operations are not yet available */ - -#undef HAVE_CLEAN_DCACHE_RANGE -#undef HAVE_INVALIDATE_DCACHE_RANGE - /**************************************************************************** * Private Types ****************************************************************************/ @@ -1091,26 +1086,16 @@ sam_allocdesc(struct sam_xdmach_s *xdmach, struct chnext_view1_s *prev, xdmach->lltail = descr; -#ifdef HAVE_CLEAN_DCACHE_RANGE /* REVISIT */ /* Assume that we will be doing multiple buffer transfers and that * that hardware will be accessing the descriptor via DMA. */ arch_clean_dcache((uintptr_t)descr, (uintptr_t)descr + sizeof(struct chnext_view1_s)); -#endif break; } } -#ifndef HAVE_CLEAN_DCACHE_RANGE /* REVISIT */ - /* Assume that we will be doing multiple buffer transfers and that - * that hardware will be accessing the descriptors via DMA. - */ - - arch_clean_dcache_all(); -#endif - /* Because we hold a count from the counting semaphore, the above * search loop should always be successful. */ @@ -1503,17 +1488,6 @@ static void sam_dmaterminate(struct sam_xdmach_s *xdmach, int result) sam_freelinklist(xdmach); -#ifdef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */ - /* If this was an RX DMA (peripheral-to-memory), then invalidate the cache - * to force reloads from memory. - */ - - if (xdmach->rx) - { - arch_invalidate_dcache(xdmach->rxaddr, xdmach->rxaddr + xdmach->rxsize); - } -#endif - /* Perform the DMA complete callback */ if (xdmach->callback) @@ -1873,11 +1847,7 @@ int sam_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, /* Clean caches associated with the DMA memory */ -#ifdef HAVE_CLEAN_DCACHE_RANGE /* REVISIT */ arch_clean_dcache(maddr, maddr + nbytes); -#else - arch_clean_dcache_all(); -#endif return ret; } @@ -1958,11 +1928,7 @@ int sam_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, /* Clean caches associated with the DMA memory */ -#ifdef HAVE_CLEAN_DCACHE_RANGE /* REVISIT */ arch_clean_dcache(maddr, maddr + nbytes); -#else - arch_clean_dcache_all(); -#endif return ret; } @@ -1993,17 +1959,15 @@ int sam_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) xdmach->callback = callback; xdmach->arg = arg; -#ifndef HAVE_INVALIDATE_DCACHE_RANGE /* Revisit */ /* If this is an RX DMA (peripheral-to-memory), then flush and * invalidate the data cache to force reloading from memory when the * DMA completes. */ - if (xdmach->rx) + if (xdmach->rx) { - arch_flush_dcache_all(); + arch_flush_dcache(xdmach->rxaddr, xdmach->rxaddr + xdmach->rxsize); } -#endif /* Is this a single block transfer? Or a multiple block transfer? */