Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/sparc64 Handle bus_dma aligment properly.



details:   https://anonhg.NetBSD.org/src/rev/610e93ef8d48
branches:  trunk
changeset: 494492:610e93ef8d48
user:      eeh <eeh%NetBSD.org@localhost>
date:      Fri Jul 07 02:50:19 2000 +0000

description:
Handle bus_dma aligment properly.

diffstat:

 sys/arch/sparc64/dev/iommu.c       |  61 +++++++++++++++++++++++--------------
 sys/arch/sparc64/include/bus.h     |   9 ++++-
 sys/arch/sparc64/sparc64/machdep.c |  16 ++++++++-
 3 files changed, 57 insertions(+), 29 deletions(-)

diffs (248 lines):

diff -r b72dc0470e1e -r 610e93ef8d48 sys/arch/sparc64/dev/iommu.c
--- a/sys/arch/sparc64/dev/iommu.c      Fri Jul 07 01:39:26 2000 +0000
+++ b/sys/arch/sparc64/dev/iommu.c      Fri Jul 07 02:50:19 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iommu.c,v 1.20 2000/07/02 14:00:38 mrg Exp $   */
+/*     $NetBSD: iommu.c,v 1.21 2000/07/07 02:50:21 eeh Exp $   */
 
 /*
  * Copyright (c) 1999, 2000 Matthew R. Green
@@ -240,7 +240,7 @@
                (unsigned int)is->is_dvmabase,
                (unsigned int)IOTSB_VEND);
        is->is_dvmamap = extent_create(name,
-                                      is->is_dvmabase, IOTSB_VEND,
+                                      is->is_dvmabase, (u_long)IOTSB_VEND,
                                       M_DEVBUF, 0, 0, EX_NOWAIT);
 }
 
@@ -255,21 +255,27 @@
 {
 
        /* Need to do 64-bit stores */
-       bus_space_write_8(is->is_bustag, &is->is_iommu->iommu_tsb, 0, is->is_ptsb);
+       bus_space_write_8(is->is_bustag, 
+                         (bus_space_handle_t)(u_long)&is->is_iommu->iommu_tsb, 
+                         0, is->is_ptsb);
        /* Enable IOMMU in diagnostic mode */
-       bus_space_write_8(is->is_bustag, &is->is_iommu->iommu_cr, 0, 
-               is->is_cr|IOMMUCR_DE);
+       bus_space_write_8(is->is_bustag, 
+                         (bus_space_handle_t)(u_long)&is->is_iommu->iommu_cr, 0, 
+                         is->is_cr|IOMMUCR_DE);
 
 
        if (!is->is_sb)
                return;
 
        /* Enable diagnostics mode? */
-       bus_space_write_8(is->is_bustag, &is->is_sb->strbuf_ctl, 0, STRBUF_EN);
+       bus_space_write_8(is->is_bustag, 
+                         (bus_space_handle_t)(u_long)&is->is_sb->strbuf_ctl,
+                         0, STRBUF_EN);
 
        /* No streaming buffers? Disable them */
        if (bus_space_read_8(is->is_bustag,
-           (bus_space_handle_t)(u_long)&is->is_sb->strbuf_ctl, 0) == 0)
+                            (bus_space_handle_t)(u_long)&is->is_sb->strbuf_ctl, 
+                            0) == 0)
                is->is_sb = 0;
 }
 
@@ -295,15 +301,15 @@
        
        /* Is the streamcache flush really needed? */
        if (is->is_sb) {
-               bus_space_write_8(is->is_bustag, &is->is_sb->strbuf_pgflush, 0,
-                   va);
+               bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long)
+                                 &is->is_sb->strbuf_pgflush, 0, va);
                iommu_strbuf_flush(is);
        }
        DPRINTF(IDB_DVMA, ("Clearing TSB slot %d for va %p\n", 
                       (int)IOTSBSLOT(va,is->is_tsbsize), va));
        is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)] = tte;
-       bus_space_write_8(is->is_bustag, &is->is_iommu->iommu_flush, 
-                         0, va);
+       bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long)
+                         &is->is_iommu->iommu_flush, 0, va);
        DPRINTF(IDB_DVMA, ("iommu_enter: va %lx pa %lx TSB[%lx]@%p=%lx\n",
                       va, (long)pa, IOTSBSLOT(va,is->is_tsbsize), 
                       &is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)],
@@ -347,8 +353,8 @@
                               (long)&is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)],
                               (long)(is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)]), 
                               (u_long)len));
-                       bus_space_write_8(is->is_bustag,
-                           &is->is_sb->strbuf_pgflush, 0, va);
+                       bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long)
+                                         &is->is_sb->strbuf_pgflush, 0, va);
                        if (len <= NBPG)
                                iommu_strbuf_flush(is);
                        DPRINTF(IDB_DVMA, ("iommu_remove: flushed va %p TSB[%lx]@%p=%lx, %lu bytes left\n",            
@@ -365,7 +371,8 @@
                        len -= NBPG;
 
                is->is_tsb[IOTSBSLOT(va,is->is_tsbsize)] = 0;
-               bus_space_write_8(is->is_bustag, &is->is_iommu->iommu_flush, 0, va);
+               bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long)
+                                 &is->is_iommu->iommu_flush, 0, va);
                va += NBPG;
        }
 }
@@ -405,7 +412,8 @@
 
        is->is_flush = 0;
        membar_sync();
-       bus_space_write_8(is->is_bustag, &is->is_sb->strbuf_flushsync, 0, is->is_flushpa);
+       bus_space_write_8(is->is_bustag, (bus_space_handle_t)(u_long)
+                         &is->is_sb->strbuf_flushsync, 0, is->is_flushpa);
        membar_sync();
 
        microtime(&flushtimeout); 
@@ -452,7 +460,8 @@
        int err;
        bus_size_t sgsize;
        paddr_t curaddr;
-       u_long dvmaddr, align;
+       u_long dvmaddr;
+       bus_size_t align, boundary;
        vaddr_t vaddr = (vaddr_t)buf;
        pmap_t pmap;
 
@@ -478,12 +487,15 @@
        sgsize = round_page(buflen + ((int)vaddr & PGOFSET));
 
        /*
-        * XXX Need to implement "don't dma across this boundry".
+        * A boundary presented to bus_dmamem_alloc() takes precedence
+        * over boundary in the map.
         */
-       align = max(map->_dm_boundary, NBPG);
+       if ((boundary = (map->dm_segs[0]._ds_boundary)) == 0)
+               boundary = map->_dm_boundary;
+       align = max(map->dm_segs[0]._ds_align, NBPG);
        s = splhigh();
        err = extent_alloc(is->is_dvmamap, sgsize, align,
-           map->_dm_boundary, EX_NOWAIT|EX_BOUNDZERO, (u_long *)&dvmaddr);
+           boundary, EX_NOWAIT|EX_BOUNDZERO, (u_long *)&dvmaddr);
        splx(s);
 
 #ifdef DEBUG
@@ -598,7 +610,7 @@
        int err;
        bus_size_t sgsize;
        paddr_t pa;
-       u_long boundary, align;
+       bus_size_t boundary, align;
        u_long dvmaddr;
        struct pglist *mlist;
        int pagesz = PAGE_SIZE;
@@ -633,7 +645,7 @@
        if ((boundary = segs[0]._ds_boundary) == 0)
                boundary = map->_dm_boundary;
        
-       align = max(map->_dm_boundary, NBPG);
+       align = max(segs[0]._ds_align, NBPG);
        s = splhigh();
        err = extent_alloc(is->is_dvmamap, sgsize, align, boundary, 
           ((flags & BUS_DMA_NOWAIT) == 0 ? EX_WAITOK : EX_NOWAIT)|EX_BOUNDZERO, 
@@ -712,8 +724,9 @@
                                DPRINTF(IDB_DVMA,
                                    ("iommu_dvmamap_sync: flushing va %p, %lu "
                                     "bytes left\n", (long)va, (u_long)len));
-                               bus_space_write_8(is->is_bustag,
-                                   &is->is_sb->strbuf_pgflush, 0, va);
+                               bus_space_write_8(is->is_bustag, 
+                                                 (bus_space_handle_t)(u_long)
+                                                 &is->is_sb->strbuf_pgflush, 0, va);
                                if (len <= NBPG) {
                                        iommu_strbuf_flush(is);
                                        len = 0;
@@ -750,7 +763,7 @@
        DPRINTF(IDB_DVMA, ("iommu_dvmamem_alloc: sz %qx align %qx bound %qx "
           "segp %p flags %d\n", size, alignment, boundary, segs, flags));
        return (bus_dmamem_alloc(t->_parent, size, alignment, boundary,
-           segs, nsegs, rsegs, flags));
+           segs, nsegs, rsegs, flags|BUS_DMA_DVMA));
 }
 
 void
diff -r b72dc0470e1e -r 610e93ef8d48 sys/arch/sparc64/include/bus.h
--- a/sys/arch/sparc64/include/bus.h    Fri Jul 07 01:39:26 2000 +0000
+++ b/sys/arch/sparc64/include/bus.h    Fri Jul 07 02:50:19 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus.h,v 1.19 2000/06/29 14:10:16 pk Exp $      */
+/*     $NetBSD: bus.h,v 1.20 2000/07/07 02:50:19 eeh Exp $     */
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -870,11 +870,15 @@
 #define        BUS_DMA_ALLOCNOW        0x02    /* perform resource allocation now */
 #define        BUS_DMA_COHERENT        0x04    /* hint: map memory DMA coherent */
 #define        BUS_DMA_NOWRITE         0x08    /* I suppose the following two should default on */
-#define        BUS_DMA_NOCACHE         0x10    
+#define        BUS_DMA_BUS1            0x10    
 #define        BUS_DMA_BUS2            0x20
 #define        BUS_DMA_BUS3            0x40
 #define        BUS_DMA_BUS4            0x80
 
+
+#define        BUS_DMA_NOCACHE         BUS_DMA_BUS1
+#define        BUS_DMA_DVMA            BUS_DMA_BUS2    /* Don't bother with alignment */
+
 /* Forwards needed by prototypes below. */
 struct mbuf;
 struct uio;
@@ -900,6 +904,7 @@
        bus_addr_t      ds_addr;        /* DVMA address */
        bus_size_t      ds_len;         /* length of transfer */
        bus_size_t      _ds_boundary;   /* don't cross this */
+       bus_size_t      _ds_align;      /* align to this */
        void            *_ds_mlist;     /* XXX - dmamap_alloc'ed pages */
 };
 typedef struct sparc_bus_dma_segment   bus_dma_segment_t;
diff -r b72dc0470e1e -r 610e93ef8d48 sys/arch/sparc64/sparc64/machdep.c
--- a/sys/arch/sparc64/sparc64/machdep.c        Fri Jul 07 01:39:26 2000 +0000
+++ b/sys/arch/sparc64/sparc64/machdep.c        Fri Jul 07 02:50:19 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.74 2000/06/30 22:58:02 eeh Exp $ */
+/*     $NetBSD: machdep.c,v 1.75 2000/07/07 02:50:20 eeh Exp $ */
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -1044,7 +1044,8 @@
        map->_dm_segcnt = nsegments;
        map->_dm_maxsegsz = maxsegsz;
        map->_dm_boundary = boundary;
-       map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT|BUS_DMA_COHERENT|BUS_DMA_NOWRITE|BUS_DMA_NOCACHE);
+       map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT|BUS_DMA_COHERENT|
+                                  BUS_DMA_NOWRITE|BUS_DMA_NOCACHE);
        map->dm_mapsize = 0;            /* no valid mappings */
        map->dm_nsegs = 0;
 
@@ -1262,6 +1263,16 @@
                return (ENOMEM);
 
        /*
+        * If the bus uses DVMA then ignore boundary and alignment.
+        */
+       segs[0]._ds_boundary = boundary;
+       segs[0]._ds_align = alignment;
+       if (flags & BUS_DMA_DVMA) {
+               boundary = 0;
+               alignment = 0;
+       }
+
+       /*
         * Allocate pages from the VM system.
         */
        TAILQ_INIT(mlist);
@@ -1276,7 +1287,6 @@
         */
        segs[0].ds_addr = NULL; /* UPA does not map things */
        segs[0].ds_len = size;
-       segs[0]._ds_boundary = boundary;
        *rsegs = 1;
 
        /*



Home | Main Index | Thread Index | Old Index