Module Name: src Committed By: matt Date: Wed Jan 16 22:44:18 UTC 2013
Modified Files: src/sys/arch/arm/arm32 [matt-nb6-plus]: bus_dma.c Log Message: Pullup from HEAD: On Cortex, speculative loads can cache lines to be populated after then they've been invalidated for a DMA read. So after the DMA read we have to reinvalidate them again. We have to both invalidates since the former prevents dirty lines overwriting just DMAed data. To generate a diff of this commit: cvs rdiff -u -r1.54.10.1 -r1.54.10.2 src/sys/arch/arm/arm32/bus_dma.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/arm32/bus_dma.c diff -u src/sys/arch/arm/arm32/bus_dma.c:1.54.10.1 src/sys/arch/arm/arm32/bus_dma.c:1.54.10.2 --- src/sys/arch/arm/arm32/bus_dma.c:1.54.10.1 Wed Nov 28 22:40:17 2012 +++ src/sys/arch/arm/arm32/bus_dma.c Wed Jan 16 22:44:18 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: bus_dma.c,v 1.54.10.1 2012/11/28 22:40:17 matt Exp $ */ +/* $NetBSD: bus_dma.c,v 1.54.10.2 2013/01/16 22:44:18 matt Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #define _ARM32_BUS_DMA_PRIVATE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.54.10.1 2012/11/28 22:40:17 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.54.10.2 2013/01/16 22:44:18 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -758,6 +758,20 @@ _bus_dmamap_sync_segment(vaddr_t va, pad cpu_dcache_wb_range(va, len); cpu_sdcache_wb_range(va, pa, len); break; + +#ifdef CPU_CORTEX + /* + * Cortex CPUs can do speculative loads so we need to clean the cache + * after a DMA read to deal with any speculatively loaded cache lines. + * Since these can't be dirty, we can just invalidate them and don't + * have to worry about having to write back their contents. + */ + case BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE: + case BUS_DMASYNC_POSTREAD: + cpu_dcache_inv_range(va, len); + cpu_sdcache_inv_range(va, pa, len); + break; +#endif } } @@ -786,7 +800,7 @@ _bus_dmamap_sync_linear(bus_dma_tag_t t, if ((ds->_ds_flags & _BUS_DMAMAP_COHERENT) == 0) _bus_dmamap_sync_segment(va + offset, pa, seglen, ops, - false); + false); offset += seglen; len -= seglen; @@ -935,7 +949,9 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm * we are doing a PREREAD|PREWRITE, we can collapse * the whole thing into a single Wb-Inv. * - * POSTREAD -- Nothing. + * POSTREAD -- Re-invalidate the D-cache in case speculative + * memory accesses caused cachelines to become valid with now + * invalid data. * * POSTWRITE -- Nothing. */ @@ -946,7 +962,12 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm #endif const int pre_ops = ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - if (!bouncing && pre_ops == 0) { +#ifdef CPU_CORTEX + const int post_ops = ops & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); +#else + const int post_ops = 0; +#endif + if (!bouncing && pre_ops == 0 && post_ops == BUS_DMASYNC_POSTWRITE) { return; }