Module Name:    src
Committed By:   skrll
Date:           Fri Jun 14 09:09:12 UTC 2019

Modified Files:
        src/sys/arch/arm/arm32: bus_dma.c

Log Message:
Simplify the _ARM32_NEED_BUS_DMA_BOUNCE #ifdefs and rely on compiler
optimisation of the bouncing = false case.

Drain the write buf (aka DSB) in more cases

Catch all CPUs that support speculation. (thunderx isn't CPU_CORTEX)


To generate a diff of this commit:
cvs rdiff -u -r1.114 -r1.115 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.114 src/sys/arch/arm/arm32/bus_dma.c:1.115
--- src/sys/arch/arm/arm32/bus_dma.c:1.114	Sat Jun  8 11:57:27 2019
+++ src/sys/arch/arm/arm32/bus_dma.c	Fri Jun 14 09:09:12 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: bus_dma.c,v 1.114 2019/06/08 11:57:27 skrll Exp $	*/
+/*	$NetBSD: bus_dma.c,v 1.115 2019/06/14 09:09:12 skrll Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
 #include "opt_cputypes.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.114 2019/06/08 11:57:27 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.115 2019/06/14 09:09:12 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -254,12 +254,13 @@ _bus_dmamap_load_paddr(bus_dma_tag_t t, 
 	return 0;
 }
 
+static int _bus_dma_uiomove(void *buf, struct uio *uio, size_t n,
+	    int direction);
+
 #ifdef _ARM32_NEED_BUS_DMA_BOUNCE
 static int _bus_dma_alloc_bouncebuf(bus_dma_tag_t t, bus_dmamap_t map,
 	    bus_size_t size, int flags);
 static void _bus_dma_free_bouncebuf(bus_dma_tag_t t, bus_dmamap_t map);
-static int _bus_dma_uiomove(void *buf, struct uio *uio, size_t n,
-	    int direction);
 
 static int
 _bus_dma_load_bouncebuf(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
@@ -796,7 +797,7 @@ _bus_dmamap_sync_segment(vaddr_t va, pad
     bool readonly_p)
 {
 
-#if defined(ARM_MMU_EXTENDED) || defined(CPU_CORTEX)
+#if defined(ARM_MMU_EXTENDED)
 	/*
 	 * No optimisations are available for readonly mbufs on armv6+, so
 	 * assume it's not readonly from here on.
@@ -863,7 +864,8 @@ _bus_dmamap_sync_segment(vaddr_t va, pad
 		cpu_sdcache_wb_range(va, pa, len);
 		break;
 
-#ifdef CPU_CORTEX
+#if defined(CPU_CORTEX) || defined(CPU_ARMV8)
+
 	/*
 	 * 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.
@@ -1074,22 +1076,23 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm
 #endif
 
 	const int pre_ops = ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
-#ifdef CPU_CORTEX
+#if defined(CPU_CORTEX) || defined(CPU_ARMV8)
 	const int post_ops = ops & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 #else
 	const int post_ops = 0;
 #endif
-	if (!bouncing) {
-		if (pre_ops == 0 && post_ops == BUS_DMASYNC_POSTWRITE) {
-			STAT_INCR(sync_postwrite);
-			return;
-		} else if (pre_ops == 0 && post_ops == 0) {
-			return;
-		}
+	if (pre_ops == 0 && post_ops == 0)
+		return;
+
+	if (post_ops == BUS_DMASYNC_POSTWRITE) {
+		KASSERT(pre_ops == 0);
+		STAT_INCR(sync_postwrite);
+		return;
 	}
+
 	KASSERTMSG(bouncing || pre_ops != 0 || (post_ops & BUS_DMASYNC_POSTREAD),
 	    "pre_ops %#x post_ops %#x", pre_ops, post_ops);
-#ifdef _ARM32_NEED_BUS_DMA_BOUNCE
+
 	if (bouncing && (ops & BUS_DMASYNC_PREWRITE)) {
 		struct arm32_bus_dma_cookie * const cookie = map->_dm_cookie;
 		STAT_INCR(write_bounces);
@@ -1123,23 +1126,28 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm
 #endif /* DIAGNOSTIC */
 		}
 	}
-#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */
 
-	/* Skip cache frobbing if mapping was COHERENT. */
-	if (!bouncing && (map->_dm_flags & _BUS_DMAMAP_COHERENT)) {
-		/* Drain the write buffer. */
-		if (pre_ops & BUS_DMASYNC_PREWRITE)
+	/* Skip cache frobbing if mapping was COHERENT */
+	if ((map->_dm_flags & _BUS_DMAMAP_COHERENT)) {
+		/*
+		 * Drain the write buffer of DMA operators.
+		 * 1) when cpu->device (prewrite)
+		 * 2) when device->cpu (postread)
+		 */
+		if ((pre_ops & BUS_DMASYNC_PREWRITE) || (post_ops & BUS_DMASYNC_POSTREAD))
 			cpu_drain_writebuf();
-		return;
-	}
 
-#ifdef _ARM32_NEED_BUS_DMA_BOUNCE
-	if (bouncing && ((map->_dm_flags & _BUS_DMAMAP_COHERENT) || pre_ops == 0)) {
-		goto bounce_it;
+		/*
+		 * Only thing left to do for COHERENT mapping is copy from bounce
+		 * in the POSTREAD case.
+		 */
+		if (bouncing && (post_ops & BUS_DMASYNC_POSTREAD))
+			goto bounce_it;
+
+		return;
 	}
-#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */
 
-#ifndef ARM_MMU_EXTENDED
+#if !defined( ARM_MMU_EXTENDED)
 	/*
 	 * If the mapping belongs to a non-kernel vmspace, and the
 	 * vmspace has not been active since the last time a full
@@ -1151,11 +1159,9 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm
 #endif
 
 	int buftype = map->_dm_buftype;
-#ifdef _ARM32_NEED_BUS_DMA_BOUNCE
 	if (bouncing) {
 		buftype = _BUS_DMA_BUFTYPE_LINEAR;
 	}
-#endif
 
 	switch (buftype) {
 	case _BUS_DMA_BUFTYPE_LINEAR:
@@ -1186,14 +1192,14 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm
 	/* Drain the write buffer. */
 	cpu_drain_writebuf();
 
-#ifdef _ARM32_NEED_BUS_DMA_BOUNCE
-  bounce_it:
 	if (!bouncing || (ops & BUS_DMASYNC_POSTREAD) == 0)
 		return;
 
+  bounce_it:
+	STAT_INCR(read_bounces);
+
 	struct arm32_bus_dma_cookie * const cookie = map->_dm_cookie;
 	char * const dataptr = (char *)cookie->id_bouncebuf + offset;
-	STAT_INCR(read_bounces);
 	/*
 	 * Copy the bounce buffer to the caller's buffer.
 	 */
@@ -1224,7 +1230,6 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm
 		break;
 #endif
 	}
-#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */
 }
 
 /*
@@ -1749,6 +1754,7 @@ _bus_dma_free_bouncebuf(bus_dma_tag_t t,
 	cookie->id_nbouncesegs = 0;
 	cookie->id_flags &= ~_BUS_DMA_HAS_BOUNCE;
 }
+#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */
 
 /*
  * This function does the same as uiomove, but takes an explicit
@@ -1792,7 +1798,6 @@ _bus_dma_uiomove(void *buf, struct uio *
 	}
 	return 0;
 }
-#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */
 
 int
 _bus_dmatag_subregion(bus_dma_tag_t tag, bus_addr_t min_addr,

Reply via email to