Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/mips/mips When doing dmamap syncs, try to use KSEG0...



details:   https://anonhg.NetBSD.org/src/rev/d18adafe7597
branches:  trunk
changeset: 346517:d18adafe7597
user:      matt <matt%NetBSD.org@localhost>
date:      Sat Jul 16 21:33:46 2016 +0000

description:
When doing dmamap syncs, try to use KSEG0/XKPHYS address if possible.
XXX once hard page coloring is supported XKPHYS could be used all the time.

diffstat:

 sys/arch/mips/mips/bus_dma.c |  56 ++++++++++++++++++++++++++++++++-----------
 1 files changed, 41 insertions(+), 15 deletions(-)

diffs (154 lines):

diff -r 7f0e0b128526 -r d18adafe7597 sys/arch/mips/mips/bus_dma.c
--- a/sys/arch/mips/mips/bus_dma.c      Sat Jul 16 17:13:25 2016 +0000
+++ b/sys/arch/mips/mips/bus_dma.c      Sat Jul 16 21:33:46 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus_dma.c,v 1.34 2015/02/17 09:58:33 macallan Exp $    */
+/*     $NetBSD: bus_dma.c,v 1.35 2016/07/16 21:33:46 matt Exp $        */
 
 /*-
  * Copyright (c) 1997, 1998, 2001 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.34 2015/02/17 09:58:33 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.35 2016/07/16 21:33:46 matt Exp $");
 
 #define _MIPS_BUS_DMA_PRIVATE
 
@@ -106,18 +106,16 @@
     void *buf, bus_size_t buflen, struct vmspace *vm, int flags,
     int *segp, bool first)
 {
-       bus_size_t sgsize;
        paddr_t baddr, curaddr, lastaddr;
        vaddr_t vaddr = (vaddr_t)buf, lastvaddr;
-       int seg = *segp;
-       bus_dma_segment_t *ds = &map->dm_segs[seg];
+       bus_dma_segment_t *ds = &map->dm_segs[*segp];
        bus_dma_segment_t * const eds = &map->dm_segs[map->_dm_segcnt];
+       const bus_addr_t bmask = ~(map->_dm_boundary - 1);
        const bool d_cache_coherent =
            (mips_options.mips_cpu_flags & CPU_MIPS_D_CACHE_COHERENT) != 0;
 
        lastaddr = ds->ds_addr + ds->ds_len;
        lastvaddr = ds->_ds_vaddr + ds->ds_len;
-       const bus_size_t bmask = ~(map->_dm_boundary - 1);
 
        while (buflen > 0) {
                /*
@@ -146,7 +144,7 @@
                /*
                 * Compute the segment size, and adjust counts.
                 */
-               sgsize = PAGE_SIZE - ((uintptr_t)vaddr & PGOFSET);
+               bus_size_t sgsize = PAGE_SIZE - ((uintptr_t)vaddr & PGOFSET);
                if (sgsize > buflen) {
                        sgsize = buflen;
                }
@@ -174,8 +172,12 @@
                        ds->_ds_vaddr = vaddr;
                        first = false;
                } else if (curaddr == lastaddr
-                   && (d_cache_coherent || lastvaddr == vaddr)
-                   && ds->ds_len + sgsize <= map->dm_maxsegsz
+                   && (d_cache_coherent
+#ifndef __mips_o32
+                       || !MIPS_CACHE_VIRTUAL_ALIAS
+#endif
+                       || vaddr == lastvaddr)
+                   && (ds->ds_len + sgsize) <= map->dm_maxsegsz
                    && (map->_dm_boundary == 0
                        || ((ds->ds_addr ^ curaddr) & bmask) == 0)) {
                        ds->ds_len += sgsize;
@@ -185,6 +187,25 @@
                        ds->ds_addr = curaddr;
                        ds->ds_len = sgsize;
                        ds->_ds_vaddr = vaddr;
+                       /*
+                        * If this segment uses the correct color, try to see
+                        * if we can use a direct-mapped VA for the segment.
+                        */
+                       if (!mips_cache_badalias(curaddr, vaddr)) {
+#ifdef __mips_o32
+                               if (MIPS_KSEG0_P(curaddr + sgsize - 1)) {
+                                       ds->_ds_vaddr =
+                                           MIPS_PHYS_TO_KSEG0(curaddr);
+                               }
+#else
+                               /*
+                                * All physical addresses can be accessed
+                                * via XKPHYS.
+                                */
+                               ds->_ds_vaddr =
+                                   MIPS_PHYS_TO_XKPHYS_CACHED(curaddr);
+#endif
+                       }
                }
 
                lastaddr = curaddr + sgsize;
@@ -496,6 +517,7 @@
 #endif
                STAT_INCR(unloads);
        }
+
        /*
         * Make sure that on error condition we return "no valid mappings."
         */
@@ -803,6 +825,7 @@
            || (ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) == 0)
                goto bounce_it;
 
+#ifdef _mips_o32
        /*
         * If the mapping belongs to the kernel, or it belongs
         * to the currently-running process (XXX actually, vmspace),
@@ -812,6 +835,7 @@
         */
        const bool useindex = (!VMSPACE_IS_KERNEL_P(map->_dm_vmspace)
            && map->_dm_vmspace != curproc->p_vmspace);
+#endif
 
        bus_dma_segment_t *seg = map->dm_segs;
        bus_dma_segment_t * const lastseg = seg + map->dm_nsegs;
@@ -827,7 +851,7 @@
                 * Now at the first segment to sync; nail each segment until we
                 * have exhausted the length.
                 */
-               vaddr_t vaddr = seg->_ds_vaddr + offset;
+               register_t vaddr = (intptr_t)seg->_ds_vaddr + offset;
                minlen = ulmin(len, seg->ds_len - offset);
 
 #ifdef BUS_DMA_DEBUG
@@ -843,13 +867,15 @@
                 * If we are forced to use Index ops, it's always a
                 * Write-back,Invalidate, so just do one test.
                 */
-               if (__predict_false(useindex)) {
+#ifdef mips_o32
+               if (__predict_false(useindex || vaddr == 0)) {
                        mips_dcache_wbinv_range_index(vaddr, minlen);
 #ifdef BUS_DMA_DEBUG
                        printf("\n");
 #endif
                        continue;
                }
+#endif
 
                switch (ops) {
                case BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE:
@@ -858,10 +884,10 @@
 
                case BUS_DMASYNC_PREREAD: {
                        struct mips_cache_info * const mci = &mips_cache_info;
-                       vaddr_t start = vaddr;
-                       vaddr_t end = vaddr + minlen;
-                       vaddr_t preboundary, firstboundary, lastboundary;
-                       vaddr_t mask = mci->mci_dcache_align_mask;
+                       register_t start = vaddr;
+                       register_t end = vaddr + minlen;
+                       register_t preboundary, firstboundary, lastboundary;
+                       register_t mask = mci->mci_dcache_align_mask;
 
                        preboundary = start & ~mask;
                        firstboundary = (start + mask) & ~mask;



Home | Main Index | Thread Index | Old Index