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;
 	}
 

Reply via email to