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 an ARM32_DMAMAP_COHERENT flag to indicate...



details:   https://anonhg.NetBSD.org/src/rev/fef524011a87
branches:  trunk
changeset: 535316:fef524011a87
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Wed Aug 14 20:50:37 2002 +0000

description:
* Add an ARM32_DMAMAP_COHERENT flag to indicate that a loaded DMA
  map contains "coherent" (non-cached in ARM-land) mappings.
* Set ARM32_DMAMAP_COHERENT in the map at the start of a load operation,
  and clear it in _bus_dmamap_load_buffer() if we encounter any cacheable
  mappings.
* In _bus_dmamap_sync(), if the map is marked COHERENT, skip any cache
  flushing.

diffstat:

 sys/arch/arm/arm32/bus_dma.c |  59 +++++++++++++++++++++++++++++++++++++++----
 sys/arch/arm/include/bus.h   |   7 ++++-
 2 files changed, 59 insertions(+), 7 deletions(-)

diffs (137 lines):

diff -r 40aff1fd103f -r fef524011a87 sys/arch/arm/arm32/bus_dma.c
--- a/sys/arch/arm/arm32/bus_dma.c      Wed Aug 14 19:47:18 2002 +0000
+++ b/sys/arch/arm/arm32/bus_dma.c      Wed Aug 14 20:50:37 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus_dma.c,v 1.16 2002/08/14 19:21:50 thorpej Exp $     */
+/*     $NetBSD: bus_dma.c,v 1.17 2002/08/14 20:50:37 thorpej Exp $     */
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -169,6 +169,9 @@
        if (buflen > map->_dm_size)
                return (EINVAL);
 
+       /* _bus_dmamap_load_buffer() clears this if we're not... */
+       map->_dm_flags |= ARM32_DMAMAP_COHERENT;
+
        seg = 0;
        error = _bus_dmamap_load_buffer(t, map, buf, buflen, p, flags,
            &lastaddr, &seg, 1);
@@ -215,6 +218,9 @@
        if (m0->m_pkthdr.len > map->_dm_size)
                return (EINVAL);
 
+       /* _bus_dmamap_load_buffer() clears this if we're not... */
+       map->_dm_flags |= ARM32_DMAMAP_COHERENT;
+
        first = 1;
        seg = 0;
        error = 0;
@@ -267,6 +273,9 @@
 #endif
        }
 
+       /* _bus_dmamap_load_buffer() clears this if we're not... */
+       map->_dm_flags |= ARM32_DMAMAP_COHERENT;
+
        first = 1;
        seg = 0;
        error = 0;
@@ -512,9 +521,12 @@
        if (ops == 0)
                return;
 
-       /*
-        * XXX Skip cache frobbing if mapping was COHERENT.
-        */
+       /* Skip cache frobbing if mapping was COHERENT. */
+       if (map->_dm_flags & ARM32_DMAMAP_COHERENT) {
+               /* Drain the write buffer. */
+               cpu_drain_writebuf();
+               return;
+       }
 
        /*
         * If the mapping is not the kernel's and also not the
@@ -688,7 +700,7 @@
                                cpu_dcache_wbinv_range(va, NBPG);
                                cpu_drain_writebuf();
                                ptep = vtopte(va);
-                               *ptep &= ~pte_l2_s_cache_mask;
+                               *ptep &= ~L2_S_CACHE_MASK;
                                tlb_flush();
                        }
 #ifdef DEBUG_DMA
@@ -776,6 +788,8 @@
        bus_size_t sgsize;
        bus_addr_t curaddr, lastaddr, baddr, bmask;
        vaddr_t vaddr = (vaddr_t)buf;
+       pd_entry_t *pde;
+       pt_entry_t pte;
        int seg;
        pmap_t pmap;
 
@@ -795,8 +809,41 @@
        for (seg = *segp; buflen > 0; ) {
                /*
                 * Get the physical address for this segment.
+                *
+                * XXX Don't support checking for coherent mappings
+                * XXX in user address space.
                 */
-               (void) pmap_extract(pmap, (vaddr_t)vaddr, &curaddr);
+               if (__predict_true(pmap == pmap_kernel())) {
+                       pde = pmap_pde(pmap, vaddr);
+                       if (__predict_false(pmap_pde_section(pde))) {
+                               curaddr = (*pde & L1_S_FRAME) |
+                                   (vaddr & L1_S_OFFSET);
+                               if (*pde & L1_S_CACHE_MASK) {
+                                       map->_dm_flags &=
+                                           ~ARM32_DMAMAP_COHERENT;
+                               }
+                       } else {
+                               pte = *vtopte(vaddr);
+                               KDASSERT((pte & L2_TYPE_MASK) != L2_TYPE_INV);
+                               if (__predict_false((pte & L2_TYPE_MASK)
+                                                   == L2_TYPE_L)) {
+                                       curaddr = (pte & L2_L_FRAME) |
+                                           (vaddr & L2_L_OFFSET);
+                                       if (pte & L2_L_CACHE_MASK) {
+                                               map->_dm_flags &=
+                                                   ~ARM32_DMAMAP_COHERENT;
+                                       }
+                               } else {
+                                       curaddr = (pte & L2_S_FRAME) |
+                                           (vaddr & L2_S_OFFSET);
+                                       if (pte & L2_S_CACHE_MASK) {
+                                               map->_dm_flags &=
+                                                   ~ARM32_DMAMAP_COHERENT;
+                                       }
+                               }
+                       }
+               } else
+                       (void) pmap_extract(pmap, vaddr, &curaddr);
 
                /*
                 * Make sure we're in an allowed DMA range.
diff -r 40aff1fd103f -r fef524011a87 sys/arch/arm/include/bus.h
--- a/sys/arch/arm/include/bus.h        Wed Aug 14 19:47:18 2002 +0000
+++ b/sys/arch/arm/include/bus.h        Wed Aug 14 20:50:37 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus.h,v 1.6 2002/07/31 17:34:24 thorpej Exp $  */
+/*     $NetBSD: bus.h,v 1.7 2002/08/14 20:50:37 thorpej Exp $  */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
@@ -634,6 +634,11 @@
 #define        BUS_DMA_READ            0x100   /* mapping is device -> memory only */
 #define        BUS_DMA_WRITE           0x200   /* mapping is memory -> device only */
 
+/*
+ * Private flags stored in the DMA map.
+ */
+#define        ARM32_DMAMAP_COHERENT   0x10000 /* no cache flush necessary on sync */
+
 /* Forwards needed by prototypes below. */
 struct mbuf;
 struct uio;



Home | Main Index | Thread Index | Old Index