Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/arm32 On Cortex, speculative loads can cache li...
details: https://anonhg.NetBSD.org/src/rev/bf8af49cbfcc
branches: trunk
changeset: 784062:bf8af49cbfcc
user: matt <matt%NetBSD.org@localhost>
date: Wed Jan 16 22:32:45 2013 +0000
description:
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.
diffstat:
sys/arch/arm/arm32/bus_dma.c | 31 ++++++++++++++++++++++++++-----
1 files changed, 26 insertions(+), 5 deletions(-)
diffs (73 lines):
diff -r d705a55f2fbc -r bf8af49cbfcc sys/arch/arm/arm32/bus_dma.c
--- a/sys/arch/arm/arm32/bus_dma.c Wed Jan 16 21:48:56 2013 +0000
+++ b/sys/arch/arm/arm32/bus_dma.c Wed Jan 16 22:32:45 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bus_dma.c,v 1.66 2012/10/23 12:23:20 skrll Exp $ */
+/* $NetBSD: bus_dma.c,v 1.67 2013/01/16 22:32:45 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.66 2012/10/23 12:23:20 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.67 2013/01/16 22:32:45 matt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -758,6 +758,20 @@
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 @@
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 @@
* 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 @@
#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;
}
Home |
Main Index |
Thread Index |
Old Index