Source-Changes-HG archive

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

[src/matt-nb6-plus]: src/sys/arch/arm/arm32 sync with HEAD



details:   https://anonhg.NetBSD.org/src/rev/a976d492ee07
branches:  matt-nb6-plus
changeset: 774556:a976d492ee07
user:      matt <matt%NetBSD.org@localhost>
date:      Thu Feb 14 01:12:53 2013 +0000

description:
sync with HEAD

diffstat:

 sys/arch/arm/arm32/bus_dma.c |  104 +++++++++++++++++++++++-------------------
 1 files changed, 58 insertions(+), 46 deletions(-)

diffs (231 lines):

diff -r 86cff2fc32e4 -r a976d492ee07 sys/arch/arm/arm32/bus_dma.c
--- a/sys/arch/arm/arm32/bus_dma.c      Wed Feb 13 23:54:04 2013 +0000
+++ b/sys/arch/arm/arm32/bus_dma.c      Thu Feb 14 01:12:53 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus_dma.c,v 1.54.10.2 2013/01/16 22:44:18 matt Exp $   */
+/*     $NetBSD: bus_dma.c,v 1.54.10.3 2013/02/14 01:12:53 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.2 2013/01/16 22:44:18 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.54.10.3 2013/02/14 01:12:53 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -169,16 +169,17 @@
                 * If this region is coherent, mark the segment as coherent.
                 */
                _ds_flags |= dr->dr_flags & _BUS_DMAMAP_COHERENT;
-#if 0
-               printf("%p: %#lx: range %#lx/%#lx/%#lx/%#x: %#x\n",
-                   t, paddr, dr->dr_sysbase, dr->dr_busbase,
-                   dr->dr_len, dr->dr_flags, _ds_flags);
-#endif
+
                /*
                 * In a valid DMA range.  Translate the physical
                 * memory address to an address in the DMA window.
                 */
                curaddr = (paddr - dr->dr_sysbase) + dr->dr_busbase;
+#if 0
+               printf("%p: %#lx: range %#lx/%#lx/%#lx/%#x: %#x <-- %#lx\n",
+                   t, paddr, dr->dr_sysbase, dr->dr_busbase,
+                   dr->dr_len, dr->dr_flags, _ds_flags, curaddr);
+#endif
        } else
                curaddr = paddr;
 
@@ -450,7 +451,9 @@
        map->dm_mapsize = 0;
        map->dm_nsegs = 0;
        map->_dm_buftype = _BUS_DMA_BUFTYPE_INVALID;
-       KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz);
+       KASSERTMSG(map->dm_maxsegsz <= map->_dm_maxmaxsegsz,
+           "dm_maxsegsz %lu _dm_maxmaxsegsz %lu",
+           map->dm_maxsegsz, map->_dm_maxmaxsegsz);
 
        if (buflen > map->_dm_size)
                return (EINVAL);
@@ -517,7 +520,9 @@
        map->dm_mapsize = 0;
        map->dm_nsegs = 0;
        map->_dm_buftype = _BUS_DMA_BUFTYPE_INVALID;
-       KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz);
+       KASSERTMSG(map->dm_maxsegsz <= map->_dm_maxmaxsegsz,
+           "dm_maxsegsz %lu _dm_maxmaxsegsz %lu",
+           map->dm_maxsegsz, map->_dm_maxmaxsegsz);
 
 #ifdef DIAGNOSTIC
        if ((m0->m_flags & M_PKTHDR) == 0)
@@ -639,7 +644,9 @@
         */
        map->dm_mapsize = 0;
        map->dm_nsegs = 0;
-       KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz);
+       KASSERTMSG(map->dm_maxsegsz <= map->_dm_maxmaxsegsz,
+           "dm_maxsegsz %lu _dm_maxmaxsegsz %lu",
+           map->dm_maxsegsz, map->_dm_maxmaxsegsz);
 
        resid = uio->uio_resid;
        iov = uio->uio_iov;
@@ -956,7 +963,7 @@
         *      POSTWRITE -- Nothing.
         */
 #ifdef _ARM32_NEED_BUS_DMA_BOUNCE
-       const bool bouncing = (map->_dm_flags & _BUS_DMA_IS_BOUNCING);
+       const bool bouncing = (map->_dm_flags & _BUS_DMAMAP_IS_BOUNCING);
 #else
        const bool bouncing = false;
 #endif
@@ -970,7 +977,8 @@
        if (!bouncing && pre_ops == 0 && post_ops == BUS_DMASYNC_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;
@@ -1010,7 +1018,8 @@
        /* Skip cache frobbing if mapping was COHERENT. */
        if (!bouncing && (map->_dm_flags & _BUS_DMAMAP_COHERENT)) {
                /* Drain the write buffer. */
-               cpu_drain_writebuf();
+               if (pre_ops & BUS_DMASYNC_PREWRITE)
+                       cpu_drain_writebuf();
                return;
        }
 
@@ -1132,7 +1141,8 @@
        if ((dr = t->_ranges) != NULL) {
                error = ENOMEM;
                for (i = 0; i < t->_nranges; i++, dr++) {
-                       if (dr->dr_len == 0)
+                       if (dr->dr_len == 0
+                           || (dr->dr_flags & _BUS_DMAMAP_NOALLOC))
                                continue;
                        error = _bus_dmamem_alloc_range(t, size, alignment,
                            boundary, segs, nsegs, rsegs, flags,
@@ -1213,34 +1223,32 @@
         * 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);
+                           _bus_dma_paddr_inrange(t->_ranges, t->_nranges, pa);
                        if (dr != NULL
-                           && (dr->dr_flags & _BUS_DMAMAP_COHERENT) != 0) {
-                               *kvap = (void *)PMAP_MAP_POOLPAGE(paddr);
+                           && (dr->dr_flags & _BUS_DMAMAP_COHERENT)) {
+                               direct_mapable = true;
+                       }
+               }
+
+               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 +1281,24 @@
                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
+                           && (dr->dr_flags & _BUS_DMAMAP_COHERENT)) {
+                               uncached = false;
+                       }
+
                        pmap_kenter_pa(va, pa,
                            VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED);
 
@@ -1289,21 +1310,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);
@@ -1356,6 +1362,7 @@
 _bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
     off_t off, int prot, int flags)
 {
+       paddr_t map_flags;
        int i;
 
        for (i = 0; i < nsegs; i++) {
@@ -1373,7 +1380,12 @@
                        continue;
                }
 
-               return (arm_btop((u_long)segs[i].ds_addr + off));
+               map_flags = 0;
+               if (flags & BUS_DMA_PREFETCHABLE)
+                       map_flags |= ARM32_MMAP_WRITECOMBINE;
+
+               return (arm_btop((u_long)segs[i].ds_addr + off) | map_flags);
+               
        }
 
        /* Page not found. */



Home | Main Index | Thread Index | Old Index