Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm Add a flag to make bus_dmamem_map use the bus/s...



details:   https://anonhg.NetBSD.org/src/rev/9ba3a27dbaaf
branches:  trunk
changeset: 784389:9ba3a27dbaaf
user:      matt <matt%NetBSD.org@localhost>
date:      Sun Jan 27 17:38:55 2013 +0000

description:
Add a flag to make bus_dmamem_map use the bus/sys transation table when
mapping bus addresses.  Make bcm2835 obio use it.

diffstat:

 sys/arch/arm/arm32/bus_dma.c         |  75 +++++++++++++++++++----------------
 sys/arch/arm/broadcom/bcm2835_obio.c |   5 +-
 sys/arch/arm/include/bus_defs.h      |   3 +-
 3 files changed, 45 insertions(+), 38 deletions(-)

diffs (176 lines):

diff -r 556cd40c0ad7 -r 9ba3a27dbaaf sys/arch/arm/arm32/bus_dma.c
--- a/sys/arch/arm/arm32/bus_dma.c      Sun Jan 27 16:03:15 2013 +0000
+++ b/sys/arch/arm/arm32/bus_dma.c      Sun Jan 27 17:38:55 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus_dma.c,v 1.67 2013/01/16 22:32:45 matt Exp $        */
+/*     $NetBSD: bus_dma.c,v 1.68 2013/01/27 17:38:55 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.67 2013/01/16 22:32:45 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.68 2013/01/27 17:38:55 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -970,7 +970,7 @@
        if (!bouncing && pre_ops == 0 && post_ops == BUS_DMASYNC_POSTWRITE) {
                return;
        }
-
+       KASSERT(pre_ops != 0 || (post_ops & BUS_DMASYNC_POSTREAD));
 #ifdef _ARM32_NEED_BUS_DMA_BOUNCE
        if (bouncing && (ops & BUS_DMASYNC_PREWRITE)) {
                struct arm32_bus_dma_cookie * const cookie = map->_dm_cookie;
@@ -1213,34 +1213,37 @@
         * avoid having a separate mapping for it.
         */
        if (nsegs == 1) {
-               paddr_t paddr = segs[0].ds_addr;
                /*
                 * If this is a non-COHERENT mapping, then the existing kernel
                 * mapping is already compatible with it.
                 */
-               if ((flags & BUS_DMA_COHERENT) == 0) {
-#ifdef DEBUG_DMA
-                       printf("dmamem_map: =%p\n", *kvap);
-#endif /* DEBUG_DMA */
-                       *kvap = (void *)PMAP_MAP_POOLPAGE(paddr);
-                       return 0;
-               }
+               bool direct_mapable = (flags & BUS_DMA_COHERENT) == 0;
+               pa = segs[0].ds_addr;
+
                /*
-                * This is a COHERENT mapping, which unless this address is in
+                * This is a COHERENT mapping which, unless this address is in
                 * a COHERENT dma range, will not be compatible.
                 */
                if (t->_ranges != NULL) {
                        const struct arm32_dma_range * const dr =
-                           _bus_dma_paddr_inrange(t->_ranges, t->_nranges,
-                               paddr);
-                       if (dr != NULL
-                           && (dr->dr_flags & _BUS_DMAMAP_COHERENT) != 0) {
-                               *kvap = (void *)PMAP_MAP_POOLPAGE(paddr);
+                           _bus_dma_paddr_inrange(t->_ranges, t->_nranges, pa);
+                       if (dr != NULL) {
+                               if (dr->dr_flags & _BUS_DMAMAP_COHERENT) {
+                                       direct_mapable = true;
+                               }
+                               if (dr->dr_flags & _BUS_DMAMAP_MEM_XLATE) {
+                                       pa = (pa - dr->dr_sysbase)
+                                           + dr->dr_busbase;
+                               }
+                       }
+               }
+
+               if (direct_mapable) {
+                       *kvap = (void *)PMAP_MAP_POOLPAGE(pa);
 #ifdef DEBUG_DMA
-                               printf("dmamem_map: =%p\n", *kvap);
+                       printf("dmamem_map: =%p\n", *kvap);
 #endif /* DEBUG_DMA */
-                               return 0;
-                       }
+                       return 0;
                }
        }
 #endif
@@ -1273,11 +1276,28 @@
                for (pa = segs[curseg].ds_addr;
                    pa < (segs[curseg].ds_addr + segs[curseg].ds_len);
                    pa += PAGE_SIZE, va += PAGE_SIZE, size -= PAGE_SIZE) {
+                       bool uncached = (flags & BUS_DMA_COHERENT);
 #ifdef DEBUG_DMA
                        printf("wiring p%lx to v%lx", pa, va);
 #endif /* DEBUG_DMA */
                        if (size == 0)
                                panic("_bus_dmamem_map: size botch");
+
+                       const struct arm32_dma_range * const dr =
+                           _bus_dma_paddr_inrange(t->_ranges, t->_nranges, pa);
+                       /*
+                        * If this dma region is coherent then there is
+                        * no need for an uncached mapping.
+                        */
+                       if (dr != NULL) {
+                               if (dr->dr_flags & _BUS_DMAMAP_COHERENT) {
+                                       uncached = false;
+                               }
+                               if (dr->dr_flags & _BUS_DMAMAP_MEM_XLATE) {
+                                       pa = (pa - dr->dr_sysbase)
+                                            + dr->dr_busbase;
+                               }
+                       }
                        pmap_kenter_pa(va, pa,
                            VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED);
 
@@ -1289,21 +1309,6 @@
                         * contain the virtal addresses we are making
                         * uncacheable.
                         */
-
-                       bool uncached = (flags & BUS_DMA_COHERENT);
-                       if (uncached) {
-                               const struct arm32_dma_range * const dr =
-                                   _bus_dma_paddr_inrange(t->_ranges,
-                                       t->_nranges, pa);
-                               /*
-                                * If this dma region is coherent then there is
-                                * no need for an uncached mapping.
-                                */
-                               if (dr != NULL
-                                   && (dr->dr_flags & _BUS_DMAMAP_COHERENT)) {
-                                       uncached = false;
-                               }
-                       }
                        if (uncached) {
                                cpu_dcache_wbinv_range(va, PAGE_SIZE);
                                cpu_sdcache_wbinv_range(va, pa, PAGE_SIZE);
diff -r 556cd40c0ad7 -r 9ba3a27dbaaf sys/arch/arm/broadcom/bcm2835_obio.c
--- a/sys/arch/arm/broadcom/bcm2835_obio.c      Sun Jan 27 16:03:15 2013 +0000
+++ b/sys/arch/arm/broadcom/bcm2835_obio.c      Sun Jan 27 17:38:55 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bcm2835_obio.c,v 1.13 2013/01/26 08:01:49 skrll Exp $  */
+/*     $NetBSD: bcm2835_obio.c,v 1.14 2013/01/27 17:38:55 matt Exp $   */
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm2835_obio.c,v 1.13 2013/01/26 08:01:49 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm2835_obio.c,v 1.14 2013/01/27 17:38:55 matt Exp $");
 
 #include "locators.h"
 #include "obio.h"
@@ -183,6 +183,7 @@
        sc->sc_dmarange.dr_sysbase = 0;
        sc->sc_dmarange.dr_busbase = BCM2835_BUSADDR_CACHE_COHERENT;
        sc->sc_dmarange.dr_len = physmem * PAGE_SIZE;
+       sc->sc_dmarange.dr_flags = _BUS_DMAMAP_MEM_XLATE;
        bcm2835_bus_dma_tag._ranges = &sc->sc_dmarange;
        bcm2835_bus_dma_tag._nranges = 1;
 
diff -r 556cd40c0ad7 -r 9ba3a27dbaaf sys/arch/arm/include/bus_defs.h
--- a/sys/arch/arm/include/bus_defs.h   Sun Jan 27 16:03:15 2013 +0000
+++ b/sys/arch/arm/include/bus_defs.h   Sun Jan 27 17:38:55 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus_defs.h,v 1.5 2012/11/12 18:00:37 skrll Exp $       */
+/*     $NetBSD: bus_defs.h,v 1.6 2013/01/27 17:38:55 matt Exp $        */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
@@ -301,6 +301,7 @@
  */
 #define        _BUS_DMAMAP_COHERENT    0x10000 /* no cache flush necessary on sync */
 #define        _BUS_DMAMAP_IS_BOUNCING 0x20000 /* is bouncing current xfer */
+#define        _BUS_DMAMAP_MEM_XLATE   0x40000 /* translate sys->bus for dmamam_map */
 
 /* Forwards needed by prototypes below. */
 struct mbuf;



Home | Main Index | Thread Index | Old Index