Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Feb 2009 16:47:30 GMT
From:      Ulf Lilleengen <lulf@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 158388 for review
Message-ID:  <200902271647.n1RGlUAS024049@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=158388

Change 158388 by lulf@lulf_carrot on 2009/02/27 16:47:01

	- Use MIPS busdma as a base instead, as it seems to be a lot simpler
	  than the ARM code. Try to define limits according to the AVR32
	  segments, although not sure if it is completely correct yet.
	- Add cache handling skeleton and read cache characteristics from
	  CONFIG1.  Currently, only noops, but will be implemented next.

Affected files ...

.. //depot/projects/avr32/src/sys/avr32/avr32/busdma_machdep.c#2 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/cache.c#1 add
.. //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#9 edit
.. //depot/projects/avr32/src/sys/avr32/include/cache.h#1 add
.. //depot/projects/avr32/src/sys/conf/files.avr32#9 edit

Differences ...

==== //depot/projects/avr32/src/sys/avr32/avr32/busdma_machdep.c#2 (text+ko) ====

@@ -1,7 +1,5 @@
 /*-
- * Copyright (c) 2004 Olivier Houchard
- * Copyright (c) 2002 Peter Grehan
- * Copyright (c) 1997, 1998 Justin T. Gibbs.
+ * Copyright (c) 2006 Fill this file and put your name here
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,17 +23,50 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *   From arm/busdma_machdep.c,v 1.44 2009/02/09 22:58:09 lulf
+ */
+
+/*-
+ * Copyright (c) 1997, 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the NetBSD
+ *	Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 
+/*	$NetBSD: bus_dma.c,v 1.17 2006/03/01 12:38:11 yamt Exp $	*/
+
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * AVR32 bus dma support routines
- */
+__FBSDID("$FreeBSD: src/sys/avr32/avr32/busdma_machdep.c,v 1.4 2009/02/12 01:10:53 imp Exp $");
 
-#define _AVR32_BUS_DMA_PRIVATE
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
@@ -48,7 +79,6 @@
 #include <sys/uio.h>
 #include <sys/ktr.h>
 #include <sys/kernel.h>
-#include <sys/sysctl.h>
 
 #include <vm/vm.h>
 #include <vm/vm_page.h>
@@ -56,14 +86,9 @@
 
 #include <machine/atomic.h>
 #include <machine/bus.h>
+#include <machine/cache.h>
+#include <machine/cpu.h>
 #include <machine/cpufunc.h>
-#include <machine/md_var.h>
-
-#define MAX_BPAGES 64
-#define BUS_DMA_COULD_BOUNCE	BUS_DMA_BUS3
-#define BUS_DMA_MIN_ALLOC_COMP	BUS_DMA_BUS4
-
-struct bounce_zone;
 
 struct bus_dma_tag {
 	bus_dma_tag_t		parent;
@@ -81,56 +106,12 @@
 	int			map_count;
 	bus_dma_lock_t		*lockfunc;
 	void			*lockfuncarg;
-	/*
-	 * DMA range for this tag.  If the page doesn't fall within
-	 * one of these ranges, an error is returned.  The caller
-	 * may then decide what to do with the transfer.  If the
-	 * range pointer is NULL, it is ignored.
-	 */
-	struct avr32_dma_range	*ranges;
-	int			_nranges;
-	struct bounce_zone *bounce_zone;
-};
-
-struct bounce_page {
-	vm_offset_t	vaddr;		/* kva of bounce buffer */
-	vm_offset_t	vaddr_nocache;	/* kva of bounce buffer uncached */
-	bus_addr_t	busaddr;	/* Physical address */
-	vm_offset_t	datavaddr;	/* kva of client data */
-	bus_size_t	datacount;	/* client data count */
-	STAILQ_ENTRY(bounce_page) links;
-};
-
-int busdma_swi_pending;
-
-struct bounce_zone {
-	STAILQ_ENTRY(bounce_zone) links;
-	STAILQ_HEAD(bp_list, bounce_page) bounce_page_list;
-	int		total_bpages;
-	int		free_bpages;
-	int		reserved_bpages;
-	int		active_bpages;
-	int		total_bounced;
-	int		total_deferred;
-	int		map_count;
-	bus_size_t	alignment;
-	bus_size_t	boundary;
-	bus_addr_t	lowaddr;
-	char		zoneid[8];
-	char		lowaddrid[20];
-	struct sysctl_ctx_list sysctl_tree;
-	struct sysctl_oid *sysctl_tree_top;
+	/* XXX: machine-dependent fields */
+	vm_offset_t		_physbase;
+	vm_offset_t		_wbase;
+	vm_offset_t		_wsize;
 };
 
-static struct mtx bounce_lock;
-static int total_bpages;
-static int busdma_zonecount;
-static STAILQ_HEAD(, bounce_zone) bounce_zone_list;
-
-SYSCTL_NODE(_hw, OID_AUTO, busdma, CTLFLAG_RD, 0, "Busdma parameters");
-SYSCTL_INT(_hw_busdma, OID_AUTO, total_bpages, CTLFLAG_RD, &total_bpages, 0,
-	   "Total bounce pages");
-
 #define DMAMAP_LINEAR		0x1
 #define DMAMAP_MBUF		0x2
 #define DMAMAP_UIO		0x4
@@ -138,9 +119,6 @@
 #define DMAMAP_TYPE_MASK	(DMAMAP_LINEAR|DMAMAP_MBUF|DMAMAP_UIO)
 #define DMAMAP_COHERENT		0x8
 struct bus_dmamap {
-	struct bp_list	bpages;
-	int		pagesneeded;
-	int		pagesreserved;
         bus_dma_tag_t	dmat;
 	int		flags;
 	void 		*buffer;
@@ -148,15 +126,8 @@
 	void		*allocbuffer;
 	TAILQ_ENTRY(bus_dmamap)	freelist;
 	int		len;
-	STAILQ_ENTRY(bus_dmamap) links;
-	bus_dmamap_callback_t *callback;
-	void		      *callback_arg;
-
 };
 
-static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist;
-static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist;
-
 static TAILQ_HEAD(,bus_dmamap) dmamap_freelist = 
 	TAILQ_HEAD_INITIALIZER(dmamap_freelist);
 
@@ -167,45 +138,6 @@
 
 MTX_SYSINIT(busdma_mtx, &busdma_mtx, "busdma lock", MTX_DEF);
 
-static void init_bounce_pages(void *dummy);
-static int alloc_bounce_zone(bus_dma_tag_t dmat);
-static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages);
-static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
-				int commit);
-static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
-				   vm_offset_t vaddr, bus_size_t size);
-static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
-
-/* Default tag, as most drivers provide no parent tag. */
-bus_dma_tag_t avr32_root_dma_tag;
-
-/*
- * Return true if a match is made.
- *
- * To find a match walk the chain of bus_dma_tag_t's looking for 'paddr'.
- *
- * If paddr is within the bounds of the dma tag then call the filter callback
- * to check for a match, if there is no filter callback then assume a match.
- */
-static int
-run_filter(bus_dma_tag_t dmat, bus_addr_t paddr)
-{
-	int retval;
-
-	retval = 0;
-
-	do {
-		if (((paddr > dmat->lowaddr && paddr <= dmat->highaddr)
-		 || ((paddr & (dmat->alignment - 1)) != 0))
-		 && (dmat->filter == NULL
-		  || (*dmat->filter)(dmat->filterarg, paddr) != 0))
-			retval = 1;
-
-		dmat = dmat->parent;		
-	} while (retval == 0 && dmat != NULL);
-	return (retval);
-}
-
 static void
 avr32_dmamap_freelist_init(void *dummy)
 {
@@ -226,34 +158,6 @@
     bus_dmamap_t map, void *buf, bus_size_t buflen, struct pmap *pmap,
     int flags, vm_offset_t *lastaddrp, int *segp);
 
-static __inline int
-_bus_dma_can_bounce(vm_offset_t lowaddr, vm_offset_t highaddr)
-{
-	int i;
-	for (i = 0; phys_avail[i] && phys_avail[i + 1]; i += 2) {
-		if ((lowaddr >= phys_avail[i] && lowaddr <= phys_avail[i + 1])
-		    || (lowaddr < phys_avail[i] && 
-		    highaddr > phys_avail[i]))
-			return (1);
-	}
-	return (0);
-}
-
-static __inline struct avr32_dma_range *
-_bus_dma_inrange(struct avr32_dma_range *ranges, int nranges,
-    bus_addr_t curaddr)
-{
-	struct avr32_dma_range *dr;
-	int i;
-
-	for (i = 0, dr = ranges; i < nranges; i++, dr++) {
-		if (curaddr >= dr->dr_sysbase &&
-		    round_page(curaddr) <= (dr->dr_sysbase + dr->dr_len))
-			return (dr);
-	}
-
-	return (NULL);
-}
 /*
  * Convenience function for manipulating driver locks from busdma (during
  * busdma_swi, for example).  Drivers that don't provide their own locks
@@ -310,7 +214,6 @@
 			map->flags = DMAMAP_ALLOCATED;
 	} else
 		map->flags = 0;
-	STAILQ_INIT(&map->bpages);
 	return (map);
 }
 
@@ -326,11 +229,6 @@
 	}
 }
 
-/*
- * Allocate a device specific dma_tag.
- */
-#define SEG_NB 1024
-
 int
 bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
 		   bus_size_t boundary, bus_addr_t lowaddr,
@@ -341,12 +239,16 @@
 {
 	bus_dma_tag_t newtag;
 	int error = 0;
+
+	/* Basic sanity checking */
+	if (boundary != 0 && boundary < maxsegsz)
+		maxsegsz = boundary;
+
 	/* Return a NULL tag on failure */
 	*dmat = NULL;
-	if (!parent)
-		parent = avr32_root_dma_tag;
 
-	newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, M_NOWAIT);
+	newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF,
+	    M_ZERO | M_NOWAIT);
 	if (newtag == NULL) {
 		CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
 		    __func__, newtag, 0, error);
@@ -356,18 +258,24 @@
 	newtag->parent = parent;
 	newtag->alignment = alignment;
 	newtag->boundary = boundary;
-	newtag->lowaddr = trunc_page((vm_offset_t)lowaddr) + (PAGE_SIZE - 1);
-	newtag->highaddr = trunc_page((vm_offset_t)highaddr) + (PAGE_SIZE - 1);
+	newtag->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1);
+	newtag->highaddr = trunc_page((vm_paddr_t)highaddr) +
+	    (PAGE_SIZE - 1);
 	newtag->filter = filter;
 	newtag->filterarg = filterarg;
-        newtag->maxsize = maxsize;
-        newtag->nsegments = nsegments;
+	newtag->maxsize = maxsize;
+	newtag->nsegments = nsegments;
 	newtag->maxsegsz = maxsegsz;
 	newtag->flags = flags;
 	newtag->ref_count = 1; /* Count ourself */
 	newtag->map_count = 0;
-	newtag->ranges = bus_dma_get_range();
-	newtag->_nranges = bus_dma_get_range_nb();
+	newtag->_wbase = 0;
+	newtag->_physbase = 0;
+	/*
+	 * Currently limited to the first physical segment, should perhaps be
+	 * physical size of memory, as noted in the mips code.
+	 */
+	newtag->_wsize = AVR32_SEG_P2 - AVR32_SEG_P1;
 	if (lockfunc != NULL) {
 		newtag->lockfunc = lockfunc;
 		newtag->lockfuncarg = lockfuncarg;
@@ -375,68 +283,36 @@
 		newtag->lockfunc = dflt_lock;
 		newtag->lockfuncarg = NULL;
 	}
-        /*
-	 * Take into account any restrictions imposed by our parent tag
-	 */
-        if (parent != NULL) {
-                newtag->lowaddr = min(parent->lowaddr, newtag->lowaddr);
-                newtag->highaddr = max(parent->highaddr, newtag->highaddr);
+
+	/* Take into account any restrictions imposed by our parent tag */
+	if (parent != NULL) {
+		newtag->lowaddr = MIN(parent->lowaddr, newtag->lowaddr);
+		newtag->highaddr = MAX(parent->highaddr, newtag->highaddr);
 		if (newtag->boundary == 0)
 			newtag->boundary = parent->boundary;
 		else if (parent->boundary != 0)
-                	newtag->boundary = min(parent->boundary,
+			newtag->boundary = MIN(parent->boundary,
 					       newtag->boundary);
-		if ((newtag->filter != NULL) ||
-		    ((parent->flags & BUS_DMA_COULD_BOUNCE) != 0))
-			newtag->flags |= BUS_DMA_COULD_BOUNCE;
-                if (newtag->filter == NULL) {
-                        /*
-                         * Short circuit looking at our parent directly
-                         * since we have encapsulated all of its information
-                         */
-                        newtag->filter = parent->filter;
-                        newtag->filterarg = parent->filterarg;
-                        newtag->parent = parent->parent;
+		if (newtag->filter == NULL) {
+			/*
+			 * Short circuit looking at our parent directly
+			 * since we have encapsulated all of its information
+			 */
+			newtag->filter = parent->filter;
+			newtag->filterarg = parent->filterarg;
+			newtag->parent = parent->parent;
 		}
 		if (newtag->parent != NULL)
 			atomic_add_int(&parent->ref_count, 1);
 	}
-	if (_bus_dma_can_bounce(newtag->lowaddr, newtag->highaddr)
-	 || newtag->alignment > 1)
-		newtag->flags |= BUS_DMA_COULD_BOUNCE;
 
-	if (((newtag->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
-	    (flags & BUS_DMA_ALLOCNOW) != 0) {
-		struct bounce_zone *bz;
-
-		/* Must bounce */
-
-		if ((error = alloc_bounce_zone(newtag)) != 0) {
-			free(newtag, M_DEVBUF);
-			return (error);
-		}
-		bz = newtag->bounce_zone;
-
-		if (ptoa(bz->total_bpages) < maxsize) {
-			int pages;
-
-			pages = atop(maxsize) - bz->total_bpages;
-
-			/* Add pages to our bounce pool */
-			if (alloc_bounce_pages(newtag, pages) < pages)
-				error = ENOMEM;
-		}
-		/* Performed initial allocation */
-		newtag->flags |= BUS_DMA_MIN_ALLOC_COMP;
-	} else
-		newtag->bounce_zone = NULL;
-	if (error != 0)
+	if (error != 0) {
 		free(newtag, M_DEVBUF);
-	else
+	} else {
 		*dmat = newtag;
+	}
 	CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
 	    __func__, newtag, (newtag != NULL ? newtag->flags : 0), error);
-
 	return (error);
 }
 
@@ -474,7 +350,6 @@
         return (0);
 }
 
-#include <sys/kdb.h>
 /*
  * Allocate a handle for mapping from kva/uva/physical
  * address space into bus device space.
@@ -483,7 +358,9 @@
 bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
 {
 	bus_dmamap_t newmap;
+#ifdef KTR
 	int error = 0;
+#endif
 
 	newmap = _busdma_alloc_dmamap();
 	if (newmap == NULL) {
@@ -492,60 +369,13 @@
 	}
 	*mapp = newmap;
 	newmap->dmat = dmat;
-	newmap->allocbuffer = NULL;
 	dmat->map_count++;
 
-	/*
-	 * Bouncing might be required if the driver asks for an active
-	 * exclusion region, a data alignment that is stricter than 1, and/or
-	 * an active address boundary.
-	 */
-	if (dmat->flags & BUS_DMA_COULD_BOUNCE) {
-
-		/* Must bounce */
-		struct bounce_zone *bz;
-		int maxpages;
-
-		if (dmat->bounce_zone == NULL) {
-			if ((error = alloc_bounce_zone(dmat)) != 0) {
-				_busdma_free_dmamap(newmap);
-				*mapp = NULL;
-				return (error);
-			}
-		}
-		bz = dmat->bounce_zone;
-
-		/* Initialize the new map */
-		STAILQ_INIT(&((*mapp)->bpages));
-
-		/*
-		 * Attempt to add pages to our pool on a per-instance
-		 * basis up to a sane limit.
-		 */
-		maxpages = MAX_BPAGES;
-		if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0
-		 || (bz->map_count > 0 && bz->total_bpages < maxpages)) {
-			int pages;
-
-			pages = MAX(atop(dmat->maxsize), 1);
-			pages = MIN(maxpages - bz->total_bpages, pages);
-			pages = MAX(pages, 1);
-			if (alloc_bounce_pages(dmat, pages) < pages)
-				error = ENOMEM;
-
-			if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) {
-				if (error == 0)
-					dmat->flags |= BUS_DMA_MIN_ALLOC_COMP;
-			} else {
-				error = 0;
-			}
-		}
-		bz->map_count++;
-	}
 	CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
 	    __func__, dmat, dmat->flags, error);
 
 	return (0);
+
 }
 
 /*
@@ -555,21 +385,12 @@
 int
 bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
 {
-
 	_busdma_free_dmamap(map);
-	if (STAILQ_FIRST(&map->bpages) != NULL) {
-		CTR3(KTR_BUSDMA, "%s: tag %p error %d",
-		    __func__, dmat, EBUSY);
-		return (EBUSY);
-	}
-	if (dmat->bounce_zone)
-		dmat->bounce_zone->map_count--;
         dmat->map_count--;
 	CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat);
         return (0);
 }
 
-#ifdef notyet
 /*
  * Allocate a piece of memory that can be efficiently mapped into
  * bus device space based on the constraints lited in the dma tag.
@@ -600,9 +421,7 @@
 	*mapp = newmap;
 	newmap->dmat = dmat;
 	
-        if (dmat->maxsize <= PAGE_SIZE &&
-	   (dmat->alignment < dmat->maxsize) &&
-	   !_bus_dma_can_bounce(dmat->lowaddr, dmat->highaddr)) {
+        if (dmat->maxsize <= PAGE_SIZE) {
                 *vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags);
         } else {
                 /*
@@ -610,8 +429,23 @@
                  *     and handles multi-seg allocations.  Nobody is doing
                  *     multi-seg allocations yet though.
                  */
+	         vm_paddr_t maxphys;
+		 /* XXX: Fix to use correct largest physical address. */
+	         if((uint32_t)dmat->lowaddr >= (AVR32_SEG_P2 - AVR32_SEG_P1)) {
+		   /* Note in the else case I just put in what was already
+		    * being passed in dmat->lowaddr. I am not sure
+		    * how this would have worked. Since lowaddr is in the
+		    * max address postion. I would have thought that the
+		    * caller would have wanted dmat->highaddr. That is
+		    * presuming they are asking for physical addresses
+		    * which is what contigmalloc takes. - RRS
+		    */
+		   maxphys = (AVR32_SEG_P2 - AVR32_SEG_P1) - 1;
+		 } else {
+		   maxphys = dmat->lowaddr;
+		 }
                 *vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags,
-                    0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul,
+                    0ul, maxphys, dmat->alignment? dmat->alignment : 1ul,
                     dmat->boundary);
         }
         if (*vaddr == NULL) {
@@ -623,18 +457,13 @@
                 return (ENOMEM);
 	}
 	if (flags & BUS_DMA_COHERENT) {
-		void *tmpaddr = arm_remap_nocache(
-		    (void *)((vm_offset_t)*vaddr &~ PAGE_MASK),
-		    dmat->maxsize + ((vm_offset_t)*vaddr & PAGE_MASK));
+		void *tmpaddr = (void *)*vaddr;
 
 		if (tmpaddr) {
-			tmpaddr = (void *)((vm_offset_t)(tmpaddr) +
-			    ((vm_offset_t)*vaddr & PAGE_MASK));
+			tmpaddr = (void *)AVR32_PHYS_TO_P1(vtophys(tmpaddr));
 			newmap->origbuffer = *vaddr;
 			newmap->allocbuffer = tmpaddr;
-			cpu_idcache_wbinv_range((vm_offset_t)*vaddr, 
-			    dmat->maxsize);
-			cpu_l2cache_wbinv_range((vm_offset_t)*vaddr,
+			avr32_dcache_wbinv_range((vm_offset_t)*vaddr,
 			    dmat->maxsize);
 			*vaddr = tmpaddr;
 		} else
@@ -642,10 +471,9 @@
 	} else 
 		newmap->origbuffer = newmap->allocbuffer = NULL;
         return (0);
+
 }
-#endif
 
-#ifdef notyet
 /*
  * Free a piece of memory and it's allocated dmamap, that was allocated
  * via bus_dmamem_alloc.  Make the same choice for free/contigfree.
@@ -657,11 +485,8 @@
 		KASSERT(map->allocbuffer == vaddr,
 		    ("Trying to freeing the wrong DMA buffer"));
 		vaddr = map->origbuffer;
-		arm_unmap_nocache(map->allocbuffer, dmat->maxsize);
 	}
-        if (dmat->maxsize <= PAGE_SIZE &&
-	   dmat->alignment < dmat->maxsize &&
-	    !_bus_dma_can_bounce(dmat->lowaddr, dmat->highaddr))
+        if (dmat->maxsize <= PAGE_SIZE)
 		free(vaddr, M_DEVBUF);
         else {
 		contigfree(vaddr, dmat->maxsize, M_DEVBUF);
@@ -669,60 +494,7 @@
 	dmat->map_count--;
 	_busdma_free_dmamap(map);
 	CTR3(KTR_BUSDMA, "%s: tag %p flags 0x%x", __func__, dmat, dmat->flags);
-}
-#endif
-
-static int
-_bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
-			bus_size_t buflen, int flags)
-{
-	vm_offset_t vaddr;
-	vm_offset_t vendaddr;
-	bus_addr_t paddr;
-
-	if ((map->pagesneeded == 0)) {
-		CTR3(KTR_BUSDMA, "lowaddr= %d, boundary= %d, alignment= %d",
-		    dmat->lowaddr, dmat->boundary, dmat->alignment);
-		CTR2(KTR_BUSDMA, "map= %p, pagesneeded= %d",
-		    map, map->pagesneeded);
-		/*
-		 * Count the number of bounce pages
-		 * needed in order to complete this transfer
-		 */
-		vaddr = trunc_page((vm_offset_t)buf);
-		vendaddr = (vm_offset_t)buf + buflen;
-
-		while (vaddr < vendaddr) {
-			paddr = pmap_kextract(vaddr);
-			if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
-			    run_filter(dmat, paddr) != 0)
-				map->pagesneeded++;
-			vaddr += PAGE_SIZE;
-		}
-		CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
-	}
-
-	/* Reserve Necessary Bounce Pages */
-	if (map->pagesneeded != 0) {
-		mtx_lock(&bounce_lock);
-		if (flags & BUS_DMA_NOWAIT) {
-			if (reserve_bounce_pages(dmat, map, 0) != 0) {
-				mtx_unlock(&bounce_lock);
-				return (ENOMEM);
-			}
-		} else {
-			if (reserve_bounce_pages(dmat, map, 1) != 0) {
-				/* Queue us for resources */
-				STAILQ_INSERT_TAIL(&bounce_map_waitinglist,
-				    map, links);
-				mtx_unlock(&bounce_lock);
-				return (EINPROGRESS);
-			}
-		}
-		mtx_unlock(&bounce_lock);
-	}
 
-	return (0);
 }
 
 /*
@@ -737,113 +509,45 @@
     int flags, vm_offset_t *lastaddrp, int *segp)
 {
 	bus_size_t sgsize;
-	bus_addr_t curaddr, lastaddr, baddr, bmask;
+	bus_size_t bmask;
+	vm_offset_t curaddr, lastaddr;
 	vm_offset_t vaddr = (vm_offset_t)buf;
 	int seg;
 	int error = 0;
-	pd_entry_t *pde;
-	pt_entry_t pte;
-	pt_entry_t *ptep;
 
 	lastaddr = *lastaddrp;
 	bmask = ~(dmat->boundary - 1);
 
-	if ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) {
-		error = _bus_dmamap_count_pages(dmat, map, buf, buflen, flags);
-		if (error)
-			return (error);
-	}
-	CTR3(KTR_BUSDMA, "lowaddr= %d boundary= %d, "
-	    "alignment= %d", dmat->lowaddr, dmat->boundary, dmat->alignment);
-
 	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.
+		 */
+		KASSERT(kernel_pmap == pmap, ("pmap is not kernel pmap"));
+		curaddr = pmap_kextract(vaddr);
+
+		/*
+		 * If we're beyond the current DMA window, indicate
+		 * that and try to fall back onto something else.
+		 */
+		if (curaddr < dmat->_physbase ||
+		    curaddr >= (dmat->_physbase + dmat->_wsize))
+			return (EINVAL);
+
+		/*
+		 * In a valid DMA range.  Translate the physical
+		 * memory address to an address in the DMA window.
 		 */
-		if (__predict_true(pmap == pmap_kernel())) {
-#ifdef notyet
-			if (pmap_get_pde_pte(pmap, vaddr, &pde, &ptep) == FALSE)
-				return (EFAULT);
+		curaddr = (curaddr - dmat->_physbase) + dmat->_wbase;
 
-			if (__predict_false(pmap_pde_section(pde))) {
-				if (*pde & L1_S_SUPERSEC)
-					curaddr = (*pde & L1_SUP_FRAME) |
-					    (vaddr & L1_SUP_OFFSET);
-				else
-					curaddr = (*pde & L1_S_FRAME) |
-					    (vaddr & L1_S_OFFSET);
-				if (*pde & L1_S_CACHE_MASK) {
-					map->flags &=
-					    ~DMAMAP_COHERENT;
-				}
-			} else {
-				pte = *ptep;
-				KASSERT((pte & L2_TYPE_MASK) != L2_TYPE_INV,
-				    ("INV type"));
-				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->flags &=
-						    ~DMAMAP_COHERENT;
-						
-					}
-				} else {
-					curaddr = (pte & L2_S_FRAME) |
-					    (vaddr & L2_S_OFFSET);
-					if (pte & L2_S_CACHE_MASK) {
-						map->flags &=
-						    ~DMAMAP_COHERENT;
-					}
-				}
-			}
-#endif
-		} else {
-			curaddr = pmap_extract(pmap, vaddr);
-			map->flags &= ~DMAMAP_COHERENT;
-		}
 
 		/*
 		 * Compute the segment size, and adjust counts.
 		 */
 		sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
-		if (sgsize > dmat->maxsegsz)
-			sgsize = dmat->maxsegsz;
 		if (buflen < sgsize)
 			sgsize = buflen;
 
 		/*
-		 * Make sure we don't cross any boundaries.
-		 */
-		if (dmat->boundary > 0) {
-			baddr = (curaddr + dmat->boundary) & bmask;
-			if (sgsize > (baddr - curaddr))
-				sgsize = (baddr - curaddr);
-		}
-		if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
-		    map->pagesneeded != 0 && run_filter(dmat, curaddr))
-			curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
-
-		if (dmat->ranges) {
-			struct avr32_dma_range *dr;
-
-			dr = _bus_dma_inrange(dmat->ranges, dmat->_nranges,
-			    curaddr);
-			if (dr == NULL)
-				return (EINVAL);
-			/*
-		     	 * In a valid DMA range.  Translate the physical
-			 * memory address to an address in the DMA window.
-			 */
-			curaddr = (curaddr - dr->dr_sysbase) + dr->dr_busbase;
-						
-		}
-
-		/*
 		 * Insert chunk into a segment, coalescing with
 		 * the previous segment if possible.
 		 */
@@ -875,8 +579,9 @@
 	 * Did we fit?
 	 */
 	if (buflen != 0)
-		error = EFBIG; /* XXX better return value here? */
-	return (error);
+		error = EFBIG;
+
+	return error;
 }
 
 /*
@@ -897,8 +602,6 @@
 
 	KASSERT(dmat != NULL, ("dmatag is NULL"));
 	KASSERT(map != NULL, ("dmamap is NULL"));
-	map->callback = callback;
-	map->callback_arg = callback_arg;
 	map->flags &= ~DMAMAP_TYPE_MASK;
 	map->flags |= DMAMAP_LINEAR|DMAMAP_COHERENT;
 	map->buffer = buf;
@@ -906,8 +609,7 @@
 	error = bus_dmamap_load_buffer(dmat,
 	    dm_segments, map, buf, buflen, kernel_pmap,
 	    flags, &lastaddr, &nsegs);
-	if (error == EINPROGRESS)
-		return (error);
+
 	if (error)
 		(*callback)(callback_arg, NULL, 0, error);
 	else
@@ -916,7 +618,8 @@
 	CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
 	    __func__, dmat, dmat->flags, nsegs + 1, error);
 
-	return (error);
+	return (0);
+
 }
 
 /*
@@ -940,6 +643,7 @@
 	map->flags |= DMAMAP_MBUF | DMAMAP_COHERENT;
 	map->buffer = m0;
 	map->len = 0;
+
 	if (m0->m_pkthdr.len <= dmat->maxsize) {
 		vm_offset_t lastaddr = 0;
 		struct mbuf *m;
@@ -948,7 +652,7 @@
 			if (m->m_len > 0) {
 				error = bus_dmamap_load_buffer(dmat,
 				    dm_segments, map, m->m_data, m->m_len, 
-				    pmap_kernel(), flags, &lastaddr, &nsegs);
+				    kernel_pmap, flags, &lastaddr, &nsegs);
 				map->len += m->m_len;
 			}
 		}
@@ -977,14 +681,16 @@
 			int flags)
 {
 	int error = 0;
+
 	M_ASSERTPKTHDR(m0);
 
 	flags |= BUS_DMA_NOWAIT;
 	*nsegs = -1;
 	map->flags &= ~DMAMAP_TYPE_MASK;
 	map->flags |= DMAMAP_MBUF | DMAMAP_COHERENT;
-	map->buffer = m0;			
+	map->buffer = m0;
 	map->len = 0;
+
 	if (m0->m_pkthdr.len <= dmat->maxsize) {
 		vm_offset_t lastaddr = 0;
 		struct mbuf *m;
@@ -992,9 +698,8 @@
 		for (m = m0; m != NULL && error == 0; m = m->m_next) {
 			if (m->m_len > 0) {
 				error = bus_dmamap_load_buffer(dmat, segs, map,
-						m->m_data, m->m_len,
-						pmap_kernel(), flags, &lastaddr,
-						nsegs);
+				    m->m_data, m->m_len, 
+				    kernel_pmap, flags, &lastaddr, nsegs);
 				map->len += m->m_len;
 			}
 		}
@@ -1002,11 +707,12 @@
 		error = EINVAL;
 	}
 
-	/* XXX FIXME: Having to increment nsegs is really annoying */
 	++*nsegs;
 	CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
 	    __func__, dmat, dmat->flags, error, *nsegs);
+
 	return (error);
+
 }
 
 /*
@@ -1017,64 +723,9 @@
     bus_dmamap_callback2_t *callback, void *callback_arg,
     int flags)
 {
-	vm_offset_t lastaddr = 0;
-#ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT
-	bus_dma_segment_t dm_segments[dmat->nsegments];
-#else
-	bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS];
-#endif
-	int nsegs, i, error;
-	bus_size_t resid;
-	struct iovec *iov;
-	struct pmap *pmap;
 
-	resid = uio->uio_resid;
-	iov = uio->uio_iov;
-	map->flags &= ~DMAMAP_TYPE_MASK;
-	map->flags |= DMAMAP_UIO|DMAMAP_COHERENT;
-	map->buffer = uio;
-	map->len = 0;
-
-	if (uio->uio_segflg == UIO_USERSPACE) {
-		KASSERT(uio->uio_td != NULL,
-		    ("bus_dmamap_load_uio: USERSPACE but no proc"));
-		pmap = vmspace_pmap(uio->uio_td->td_proc->p_vmspace);
-	} else
-		pmap = kernel_pmap;
-
-	error = 0;
-	nsegs = -1;
-	for (i = 0; i < uio->uio_iovcnt && resid != 0 && !error; i++) {
-		/*
-		 * Now at the first iovec to load.  Load each iovec
-		 * until we have exhausted the residual count.
-		 */
-		bus_size_t minlen =
-		    resid < iov[i].iov_len ? resid : iov[i].iov_len;
-		caddr_t addr = (caddr_t) iov[i].iov_base;
-
-		if (minlen > 0) {
-			error = bus_dmamap_load_buffer(dmat, dm_segments, map,
-			    addr, minlen, pmap, flags, &lastaddr, &nsegs);
-
-			map->len += minlen;
-			resid -= minlen;
-		}
-	}
-
-	if (error) {
-		/* 
-		 * force "no valid mappings" on error in callback.
-		 */
-		(*callback)(callback_arg, dm_segments, 0, 0, error);
-	} else {
-		(*callback)(callback_arg, dm_segments, nsegs+1,
-		    uio->uio_resid, error);
-	}
-
-	CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
-	    __func__, dmat, dmat->flags, error, nsegs + 1);
-	return (error);
+	panic("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__);
+	return (0);
 }
 
 /*
@@ -1083,113 +734,33 @@
 void
 _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
 {
-	struct bounce_page *bpage;
 
-	map->flags &= ~DMAMAP_TYPE_MASK;
-	while ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
-		STAILQ_REMOVE_HEAD(&map->bpages, links);
-		free_bounce_page(dmat, bpage);
-	}
 	return;
 }
 
-static void
+static __inline void

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902271647.n1RGlUAS024049>