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 Simplify the _ARM32_NEED_BUS_DMA_BOUNCE #...



details:   https://anonhg.NetBSD.org/src/rev/21881b7d6eaf
branches:  trunk
changeset: 451999:21881b7d6eaf
user:      skrll <skrll%NetBSD.org@localhost>
date:      Fri Jun 14 09:09:12 2019 +0000

description:
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)

diffstat:

 sys/arch/arm/arm32/bus_dma.c |  73 +++++++++++++++++++++++--------------------
 1 files changed, 39 insertions(+), 34 deletions(-)

diffs (181 lines):

diff -r a71a696329d3 -r 21881b7d6eaf sys/arch/arm/arm32/bus_dma.c
--- a/sys/arch/arm/arm32/bus_dma.c      Fri Jun 14 09:06:45 2019 +0000
+++ b/sys/arch/arm/arm32/bus_dma.c      Fri Jun 14 09:09:12 2019 +0000
@@ -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 @@
        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 @@
     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 @@
                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 @@
 #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 @@
 #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();
+
+               /*
+                * 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;
        }
 
-#ifdef _ARM32_NEED_BUS_DMA_BOUNCE
-       if (bouncing && ((map->_dm_flags & _BUS_DMAMAP_COHERENT) || pre_ops == 0)) {
-               goto bounce_it;
-       }
-#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 @@
 #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 @@
        /* 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 @@
                break;
 #endif
        }
-#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */
 }
 
 /*
@@ -1749,6 +1754,7 @@
        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 @@
        }
        return 0;
 }
-#endif /* _ARM32_NEED_BUS_DMA_BOUNCE */
 
 int
 _bus_dmatag_subregion(bus_dma_tag_t tag, bus_addr_t min_addr,



Home | Main Index | Thread Index | Old Index