Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/sparc Simplify the bus_dma(9) implementation:



details:   https://anonhg.NetBSD.org/src/rev/b40430478d7c
branches:  trunk
changeset: 486496:b40430478d7c
user:      pk <pk%NetBSD.org@localhost>
date:      Tue May 23 11:39:57 2000 +0000

description:
Simplify the bus_dma(9) implementation:

- the `alignment' and `boundary' arguments in bus_dmamem_alloc() only
  serve as hints on how to break up a DMA transaction into chunks
  when necessary; it is not necessary on sparc DVMA hardware.

- exclusively use the VM page size (i.e. PAGE_SIZE et.al.) when computing
  resource allocations.

- remember the size of DVMA resource allocations in the private `_ds_sgsize'
  field in a dma segment descriptor.

diffstat:

 sys/arch/sparc/include/bus.h   |   5 +--
 sys/arch/sparc/sparc/iommu.c   |  53 ++++++++++++++---------------------
 sys/arch/sparc/sparc/machdep.c |  62 +++++++++++++++--------------------------
 3 files changed, 47 insertions(+), 73 deletions(-)

diffs (truncated from 350 to 300 lines):

diff -r 5d2e47d30006 -r b40430478d7c sys/arch/sparc/include/bus.h
--- a/sys/arch/sparc/include/bus.h      Tue May 23 11:37:58 2000 +0000
+++ b/sys/arch/sparc/include/bus.h      Tue May 23 11:39:57 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bus.h,v 1.18 2000/05/09 22:39:35 pk Exp $      */
+/*     $NetBSD: bus.h,v 1.19 2000/05/23 11:39:57 pk Exp $      */
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -933,10 +933,9 @@
 struct sparc_bus_dma_segment {
        bus_addr_t      ds_addr;        /* DVMA address */
        bus_size_t      ds_len;         /* length of transfer */
+       bus_size_t      _ds_sgsize;     /* size of allocated DVMA segment */
        void            *_ds_mlist;     /* page list when dmamem_alloc'ed */
        vaddr_t         _ds_va;         /* VA when dmamem_map'ed */
-       bus_size_t      _ds_alignment;  /* dmamem_alloc() alignment */
-       bus_size_t      _ds_boundary;   /* dmamem_alloc() boundary */
 };
 typedef struct sparc_bus_dma_segment   bus_dma_segment_t;
 
diff -r 5d2e47d30006 -r b40430478d7c sys/arch/sparc/sparc/iommu.c
--- a/sys/arch/sparc/sparc/iommu.c      Tue May 23 11:37:58 2000 +0000
+++ b/sys/arch/sparc/sparc/iommu.c      Tue May 23 11:39:57 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iommu.c,v 1.40 2000/05/10 11:17:50 pk Exp $ */
+/*     $NetBSD: iommu.c,v 1.41 2000/05/23 11:39:58 pk Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -105,7 +105,7 @@
                        int nsegs, size_t size, caddr_t *kvap, int flags));
 int    iommu_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
                        int nsegs, int off, int prot, int flags));
-int    iommu_dvma_alloc(bus_dmamap_t, vaddr_t, bus_size_t, bus_size_t, int,
+int    iommu_dvma_alloc(bus_dmamap_t, vaddr_t, bus_size_t, int,
                        bus_addr_t *, bus_size_t *);
 
 
@@ -436,14 +436,13 @@
 
 
 /*
- * Common routine to allocate space in the IOMMU map.
+ * Internal routine to allocate space in the IOMMU map.
  */
 int
-iommu_dvma_alloc(map, va, len, boundary, flags, dvap, sgsizep)
+iommu_dvma_alloc(map, va, len, flags, dvap, sgsizep)
        bus_dmamap_t map;
        vaddr_t va;
        bus_size_t len;
-       bus_size_t boundary;
        int flags;
        bus_addr_t *dvap;
        bus_size_t *sgsizep;
@@ -452,21 +451,20 @@
        u_long align, voff;
        u_long ex_start, ex_end;
        int s, error;
+       int pagesz = PAGE_SIZE;
 
        /*
         * Remember page offset, then truncate the buffer address to
         * a page boundary.
         */
-       voff = va & PGOFSET;
-       va &= ~PGOFSET;
+       voff = va & (pagesz - 1);
+       va &= -pagesz;
 
        if (len > map->_dm_size)
                return (EINVAL);
 
-       sgsize = (len + voff + PGOFSET) & ~PGOFSET;
-       align = dvma_cachealign ? dvma_cachealign : NBPG;
-       if (boundary == 0)
-               boundary = map->_dm_boundary;
+       sgsize = (len + voff + pagesz - 1) & -pagesz;
+       align = dvma_cachealign ? dvma_cachealign : pagesz;
 
        s = splhigh();
 
@@ -480,7 +478,8 @@
        }
        error = extent_alloc_subregion1(iommu_dvmamap,
                                        ex_start, ex_end,
-                                       sgsize, align, va & (align-1), boundary,
+                                       sgsize, align, va & (align-1),
+                                       map->_dm_boundary,
                                        (flags & BUS_DMA_NOWAIT) == 0
                                                ? EX_WAITOK : EX_NOWAIT,
                                        (u_long *)dvap);
@@ -505,6 +504,7 @@
        bus_size_t sgsize;
        bus_addr_t dva;
        vaddr_t va = (vaddr_t)buf;
+       int pagesz = PAGE_SIZE;
        pmap_t pmap;
        int error;
 
@@ -514,7 +514,7 @@
        map->dm_nsegs = 0;
 
        /* Allocate IOMMU resources */
-       if ((error = iommu_dvma_alloc(map, va, buflen, 0, flags,
+       if ((error = iommu_dvma_alloc(map, va, buflen, flags,
                                        &dva, &sgsize)) != 0)
                return (error);
 
@@ -525,8 +525,9 @@
         */
        map->dm_mapsize = buflen;
        map->dm_nsegs = 1;
-       map->dm_segs[0].ds_addr = dva + (va & PGOFSET);
+       map->dm_segs[0].ds_addr = dva + (va & (pagesz - 1));
        map->dm_segs[0].ds_len = buflen;
+       map->dm_segs[0]._ds_sgsize = sgsize;
 
        if (p != NULL)
                pmap = p->p_vmspace->vm_map.pmap;
@@ -542,9 +543,9 @@
 
                iommu_enter(dva, pa);
 
-               dva += PAGE_SIZE;
-               va += PAGE_SIZE;
-               sgsize -= PAGE_SIZE;
+               dva += pagesz;
+               va += pagesz;
+               sgsize -= pagesz;
        }
 
        return (0);
@@ -561,7 +562,7 @@
        int flags;
 {
 
-       panic("_bus_dmamap_load: not implemented");
+       panic("_bus_dmamap_load_mbuf: not implemented");
 }
 
 /*
@@ -601,17 +602,8 @@
 
        map->dm_nsegs = 0;
 
-#ifdef DIAGNOSTIC
-       /* XXX - unhelpful since we can't reset these in map_unload() */
-       if (segs[0].ds_addr != 0 || segs[0].ds_len != 0)
-               panic("iommu_dmamap_load_raw: segment already loaded: "
-                       "addr 0x%lx, size 0x%lx",
-                       segs[0].ds_addr, segs[0].ds_len);
-#endif
-
        /* Allocate IOMMU resources */
        if ((error = iommu_dvma_alloc(map, segs[0]._ds_va, size,
-                                     segs[0]._ds_boundary,
                                      flags, &dva, &sgsize)) != 0)
                return (error);
 
@@ -625,6 +617,7 @@
 
        map->dm_segs[0].ds_addr = dva;
        map->dm_segs[0].ds_len = size;
+       map->dm_segs[0]._ds_sgsize = sgsize;
 
        /* Map physical pages into IOMMU */
        mlist = segs[0]._ds_mlist;
@@ -658,10 +651,8 @@
        int i, s, error;
 
        for (i = 0; i < nsegs; i++) {
-               dva = segs[i].ds_addr;
-               len = segs[i].ds_len;
-               len = ((dva & PGOFSET) + len + PGOFSET) & ~PGOFSET;
-               dva &= ~PGOFSET;
+               dva = segs[i].ds_addr & -PAGE_SIZE;
+               len = segs[i]._ds_sgsize;
 
                iommu_remove(dva, len);
                s = splhigh();
diff -r 5d2e47d30006 -r b40430478d7c sys/arch/sparc/sparc/machdep.c
--- a/sys/arch/sparc/sparc/machdep.c    Tue May 23 11:37:58 2000 +0000
+++ b/sys/arch/sparc/sparc/machdep.c    Tue May 23 11:39:57 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.164 2000/05/18 10:10:55 pk Exp $ */
+/*     $NetBSD: machdep.c,v 1.165 2000/05/23 11:39:58 pk Exp $ */
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -1222,8 +1222,6 @@
        segs[0].ds_addr = 0;
        segs[0].ds_len = 0;
        segs[0]._ds_va = 0;
-       segs[0]._ds_alignment = (alignment == 0) ? NBPG : round_page(alignment);
-       segs[0]._ds_boundary = boundary;
        *rsegs = 1;
        return (0);
 }
@@ -1261,7 +1259,7 @@
 {
 
 #ifdef DIAGNOSTIC
-       if ((u_long)kva & PGOFSET)
+       if ((u_long)kva & PAGE_MASK)
                panic("_bus_dmamem_unmap");
 #endif
 
@@ -1374,6 +1372,7 @@
 {
        bus_size_t sgsize;
        vaddr_t va = (vaddr_t)buf;
+       int pagesz = PAGE_SIZE;
        bus_addr_t dva;
        pmap_t pmap;
 
@@ -1401,9 +1400,9 @@
                return (0);
        }
 
-       sgsize = round_page(buflen + (va & PGOFSET));
+       sgsize = round_page(buflen + (va & (pagesz - 1)));
 
-       if (extent_alloc(dvmamap24, sgsize, NBPG, map->_dm_boundary,
+       if (extent_alloc(dvmamap24, sgsize, pagesz, map->_dm_boundary,
                         (flags & BUS_DMA_NOWAIT) == 0 ? EX_WAITOK : EX_NOWAIT,
                         (u_long *)&dva) != 0) {
                return (ENOMEM);
@@ -1413,8 +1412,9 @@
         * We always use just one segment.
         */
        map->dm_mapsize = buflen;
-       map->dm_segs[0].ds_addr = dva + (va & PGOFSET);
+       map->dm_segs[0].ds_addr = dva + (va & (pagesz - 1));
        map->dm_segs[0].ds_len = buflen;
+       map->dm_segs[0]._ds_sgsize = sgsize;
 
        if (p != NULL)
                pmap = p->p_vmspace->vm_map.pmap;
@@ -1431,7 +1431,7 @@
                /*
                 * Compute the segment size, and adjust counts.
                 */
-               sgsize = NBPG - (va & PGOFSET);
+               sgsize = pagesz - (va & (pagesz - 1));
                if (buflen < sgsize)
                        sgsize = buflen;
 
@@ -1442,10 +1442,10 @@
 #endif
 #endif
                pmap_enter(pmap_kernel(), dva,
-                          (pa & ~(NBPG-1)) | PMAP_NC,
+                          (pa & -pagesz) | PMAP_NC,
                           VM_PROT_READ|VM_PROT_WRITE, PMAP_WIRED);
 
-               dva += PAGE_SIZE;
+               dva += pagesz;
                va += sgsize;
                buflen -= sgsize;
        }
@@ -1471,35 +1471,17 @@
        paddr_t pa;
        bus_addr_t dva;
        bus_size_t sgsize;
-       u_long boundary;
        struct pglist *mlist;
        int pagesz = PAGE_SIZE;
        int error;
 
        map->dm_nsegs = 0;
-
-#ifdef DIAGNOSTIC
-       /* XXX - unhelpful since we can't reset these in map_unload() */
-       if (segs[0].ds_addr != 0 || segs[0].ds_len != 0)
-               panic("sun4_dmamap_load_raw: segment already loaded: "
-                       "addr 0x%lx, size 0x%lx",
-                       segs[0].ds_addr, segs[0].ds_len);
-#endif
-
-       sgsize = round_page(size);
-
-       /*
-        * A boundary presented to bus_dmamem_alloc() takes precedence
-        * over boundary in the map.
-        */
-       if ((boundary = segs[0]._ds_boundary) == 0)
-               boundary = map->_dm_boundary;
+       sgsize = (size + pagesz - 1) & -pagesz;
 
        /* Allocate DVMA addresses */
        if ((map->_dm_flags & BUS_DMA_24BIT) != 0) {
-               error = extent_alloc(dvmamap24, sgsize,
-                                       segs[0]._ds_alignment,
-                                       boundary,
+               error = extent_alloc(dvmamap24, sgsize, pagesz,
+                                       map->_dm_boundary,
                                        (flags & BUS_DMA_NOWAIT) == 0
                                                ? EX_WAITOK : EX_NOWAIT,



Home | Main Index | Thread Index | Old Index