]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/arm/busdma_machdep.c
unbound: Vendor import 1.15.0
[FreeBSD/FreeBSD.git] / sys / arm / arm / busdma_machdep.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2012-2015 Ian Lepore
5  * Copyright (c) 2010 Mark Tinguely
6  * Copyright (c) 2004 Olivier Houchard
7  * Copyright (c) 2002 Peter Grehan
8  * Copyright (c) 1997, 1998 Justin T. Gibbs.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification, immediately at the beginning of the file.
17  * 2. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *  From i386/busdma_machdep.c 191438 2009-04-23 20:24:19Z jhb
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/malloc.h>
41 #include <sys/bus.h>
42 #include <sys/busdma_bufalloc.h>
43 #include <sys/counter.h>
44 #include <sys/interrupt.h>
45 #include <sys/kernel.h>
46 #include <sys/ktr.h>
47 #include <sys/lock.h>
48 #include <sys/memdesc.h>
49 #include <sys/proc.h>
50 #include <sys/mutex.h>
51 #include <sys/sysctl.h>
52 #include <sys/uio.h>
53
54 #include <vm/vm.h>
55 #include <vm/vm_param.h>
56 #include <vm/vm_page.h>
57 #include <vm/vm_phys.h>
58 #include <vm/vm_map.h>
59 #include <vm/vm_extern.h>
60 #include <vm/vm_kern.h>
61
62 #include <machine/atomic.h>
63 #include <machine/bus.h>
64 #include <machine/cpu.h>
65 #include <machine/md_var.h>
66
67 //#define ARM_BUSDMA_MAPLOAD_STATS
68
69 #define BUSDMA_DCACHE_ALIGN     cpuinfo.dcache_line_size
70 #define BUSDMA_DCACHE_MASK      cpuinfo.dcache_line_mask
71
72 #define MAX_BPAGES              64
73 #define MAX_DMA_SEGMENTS        4096
74 #define BUS_DMA_EXCL_BOUNCE     BUS_DMA_BUS2
75 #define BUS_DMA_ALIGN_BOUNCE    BUS_DMA_BUS3
76 #define BUS_DMA_COULD_BOUNCE    (BUS_DMA_EXCL_BOUNCE | BUS_DMA_ALIGN_BOUNCE)
77 #define BUS_DMA_MIN_ALLOC_COMP  BUS_DMA_BUS4
78
79 struct bounce_page;
80 struct bounce_zone;
81
82 struct bus_dma_tag {
83         bus_dma_tag_t           parent;
84         bus_size_t              alignment;
85         bus_addr_t              boundary;
86         bus_addr_t              lowaddr;
87         bus_addr_t              highaddr;
88         bus_dma_filter_t        *filter;
89         void                    *filterarg;
90         bus_size_t              maxsize;
91         u_int                   nsegments;
92         bus_size_t              maxsegsz;
93         int                     flags;
94         int                     ref_count;
95         int                     map_count;
96         bus_dma_lock_t          *lockfunc;
97         void                    *lockfuncarg;
98         struct bounce_zone      *bounce_zone;
99 };
100
101 struct sync_list {
102         vm_offset_t     vaddr;          /* kva of client data */
103         bus_addr_t      paddr;          /* physical address */
104         vm_page_t       pages;          /* starting page of client data */
105         bus_size_t      datacount;      /* client data count */
106 };
107
108 static uint32_t tags_total;
109 static uint32_t maps_total;
110 static uint32_t maps_dmamem;
111 static uint32_t maps_coherent;
112 #ifdef ARM_BUSDMA_MAPLOAD_STATS
113 static counter_u64_t maploads_total;
114 static counter_u64_t maploads_bounced;
115 static counter_u64_t maploads_coherent;
116 static counter_u64_t maploads_dmamem;
117 static counter_u64_t maploads_mbuf;
118 static counter_u64_t maploads_physmem;
119 #endif
120
121 SYSCTL_NODE(_hw, OID_AUTO, busdma, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
122     "Busdma parameters");
123 SYSCTL_UINT(_hw_busdma, OID_AUTO, tags_total, CTLFLAG_RD, &tags_total, 0,
124    "Number of active tags");
125 SYSCTL_UINT(_hw_busdma, OID_AUTO, maps_total, CTLFLAG_RD, &maps_total, 0,
126    "Number of active maps");
127 SYSCTL_UINT(_hw_busdma, OID_AUTO, maps_dmamem, CTLFLAG_RD, &maps_dmamem, 0,
128    "Number of active maps for bus_dmamem_alloc buffers");
129 SYSCTL_UINT(_hw_busdma, OID_AUTO, maps_coherent, CTLFLAG_RD, &maps_coherent, 0,
130    "Number of active maps with BUS_DMA_COHERENT flag set");
131 #ifdef ARM_BUSDMA_MAPLOAD_STATS
132 SYSCTL_COUNTER_U64(_hw_busdma, OID_AUTO, maploads_total, CTLFLAG_RD,
133     &maploads_total, "Number of load operations performed");
134 SYSCTL_COUNTER_U64(_hw_busdma, OID_AUTO, maploads_bounced, CTLFLAG_RD,
135     &maploads_bounced, "Number of load operations that used bounce buffers");
136 SYSCTL_COUNTER_U64(_hw_busdma, OID_AUTO, maploads_coherent, CTLFLAG_RD,
137     &maploads_dmamem, "Number of load operations on BUS_DMA_COHERENT memory");
138 SYSCTL_COUNTER_U64(_hw_busdma, OID_AUTO, maploads_dmamem, CTLFLAG_RD,
139     &maploads_dmamem, "Number of load operations on bus_dmamem_alloc buffers");
140 SYSCTL_COUNTER_U64(_hw_busdma, OID_AUTO, maploads_mbuf, CTLFLAG_RD,
141     &maploads_mbuf, "Number of load operations for mbufs");
142 SYSCTL_COUNTER_U64(_hw_busdma, OID_AUTO, maploads_physmem, CTLFLAG_RD,
143     &maploads_physmem, "Number of load operations on physical buffers");
144 #endif
145
146 struct bus_dmamap {
147         STAILQ_HEAD(, bounce_page) bpages;
148         int                     pagesneeded;
149         int                     pagesreserved;
150         bus_dma_tag_t           dmat;
151         struct memdesc          mem;
152         bus_dmamap_callback_t   *callback;
153         void                    *callback_arg;
154         int                     flags;
155 #define DMAMAP_COHERENT         (1 << 0)
156 #define DMAMAP_DMAMEM_ALLOC     (1 << 1)
157 #define DMAMAP_MBUF             (1 << 2)
158         STAILQ_ENTRY(bus_dmamap) links;
159         bus_dma_segment_t       *segments;
160         int                     sync_count;
161         struct sync_list        slist[];
162 };
163
164 static void _bus_dmamap_count_pages(bus_dma_tag_t dmat, pmap_t pmap,
165     bus_dmamap_t map, void *buf, bus_size_t buflen, int flags);
166 static void _bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
167     vm_paddr_t buf, bus_size_t buflen, int flags);
168 static void dma_preread_safe(vm_offset_t va, vm_paddr_t pa, vm_size_t size);
169 static void dma_dcache_sync(struct sync_list *sl, bus_dmasync_op_t op);
170
171 static busdma_bufalloc_t coherent_allocator;    /* Cache of coherent buffers */
172 static busdma_bufalloc_t standard_allocator;    /* Cache of standard buffers */
173
174 MALLOC_DEFINE(M_BUSDMA, "busdma", "busdma metadata");
175
176 #define dmat_alignment(dmat)    ((dmat)->alignment)
177 #define dmat_flags(dmat)        ((dmat)->flags)
178 #define dmat_lowaddr(dmat)      ((dmat)->lowaddr)
179 #define dmat_lockfunc(dmat)     ((dmat)->lockfunc)
180 #define dmat_lockfuncarg(dmat)  ((dmat)->lockfuncarg)
181
182 #include "../../kern/subr_busdma_bounce.c"
183
184 static void
185 busdma_init(void *dummy)
186 {
187         int uma_flags;
188
189 #ifdef ARM_BUSDMA_MAPLOAD_STATS
190         maploads_total    = counter_u64_alloc(M_WAITOK);
191         maploads_bounced  = counter_u64_alloc(M_WAITOK);
192         maploads_coherent = counter_u64_alloc(M_WAITOK);
193         maploads_dmamem   = counter_u64_alloc(M_WAITOK);
194         maploads_mbuf     = counter_u64_alloc(M_WAITOK);
195         maploads_physmem  = counter_u64_alloc(M_WAITOK);
196 #endif
197
198         uma_flags = 0;
199
200         /* Create a cache of buffers in standard (cacheable) memory. */
201         standard_allocator = busdma_bufalloc_create("buffer",
202             BUSDMA_DCACHE_ALIGN,/* minimum_alignment */
203             NULL,               /* uma_alloc func */
204             NULL,               /* uma_free func */
205             uma_flags);         /* uma_zcreate_flags */
206
207 #ifdef INVARIANTS
208         /*
209          * Force UMA zone to allocate service structures like
210          * slabs using own allocator. uma_debug code performs
211          * atomic ops on uma_slab_t fields and safety of this
212          * operation is not guaranteed for write-back caches
213          */
214         uma_flags = UMA_ZONE_NOTOUCH;
215 #endif
216         /*
217          * Create a cache of buffers in uncacheable memory, to implement the
218          * BUS_DMA_COHERENT (and potentially BUS_DMA_NOCACHE) flag.
219          */
220         coherent_allocator = busdma_bufalloc_create("coherent",
221             BUSDMA_DCACHE_ALIGN,/* minimum_alignment */
222             busdma_bufalloc_alloc_uncacheable,
223             busdma_bufalloc_free_uncacheable,
224             uma_flags); /* uma_zcreate_flags */
225 }
226
227 /*
228  * This init historically used SI_SUB_VM, but now the init code requires
229  * malloc(9) using M_BUSDMA memory and the pcpu zones for counter(9), which get
230  * set up by SI_SUB_KMEM and SI_ORDER_LAST, so we'll go right after that by
231  * using SI_SUB_KMEM+1.
232  */
233 SYSINIT(busdma, SI_SUB_KMEM+1, SI_ORDER_FIRST, busdma_init, NULL);
234
235 /*
236  * This routine checks the exclusion zone constraints from a tag against the
237  * physical RAM available on the machine.  If a tag specifies an exclusion zone
238  * but there's no RAM in that zone, then we avoid allocating resources to bounce
239  * a request, and we can use any memory allocator (as opposed to needing
240  * kmem_alloc_contig() just because it can allocate pages in an address range).
241  *
242  * Most tags have BUS_SPACE_MAXADDR or BUS_SPACE_MAXADDR_32BIT (they are the
243  * same value on 32-bit architectures) as their lowaddr constraint, and we can't
244  * possibly have RAM at an address higher than the highest address we can
245  * express, so we take a fast out.
246  */
247 static int
248 exclusion_bounce_check(vm_offset_t lowaddr, vm_offset_t highaddr)
249 {
250         int i;
251
252         if (lowaddr >= BUS_SPACE_MAXADDR)
253                 return (0);
254
255         for (i = 0; phys_avail[i] && phys_avail[i + 1]; i += 2) {
256                 if ((lowaddr >= phys_avail[i] && lowaddr < phys_avail[i + 1]) ||
257                     (lowaddr < phys_avail[i] && highaddr >= phys_avail[i]))
258                         return (1);
259         }
260         return (0);
261 }
262
263 /*
264  * Return true if the tag has an exclusion zone that could lead to bouncing.
265  */
266 static __inline int
267 exclusion_bounce(bus_dma_tag_t dmat)
268 {
269
270         return (dmat->flags & BUS_DMA_EXCL_BOUNCE);
271 }
272
273 /*
274  * Return true if the given address does not fall on the alignment boundary.
275  */
276 static __inline int
277 alignment_bounce(bus_dma_tag_t dmat, bus_addr_t addr)
278 {
279
280         return (!vm_addr_align_ok(addr, dmat->alignment));
281 }
282
283 /*
284  * Return true if the DMA should bounce because the start or end does not fall
285  * on a cacheline boundary (which would require a partial cacheline flush).
286  * COHERENT memory doesn't trigger cacheline flushes.  Memory allocated by
287  * bus_dmamem_alloc() is always aligned to cacheline boundaries, and there's a
288  * strict rule that such memory cannot be accessed by the CPU while DMA is in
289  * progress (or by multiple DMA engines at once), so that it's always safe to do
290  * full cacheline flushes even if that affects memory outside the range of a
291  * given DMA operation that doesn't involve the full allocated buffer.  If we're
292  * mapping an mbuf, that follows the same rules as a buffer we allocated.
293  */
294 static __inline int
295 cacheline_bounce(bus_dmamap_t map, bus_addr_t addr, bus_size_t size)
296 {
297
298         if (map->flags & (DMAMAP_DMAMEM_ALLOC | DMAMAP_COHERENT | DMAMAP_MBUF))
299                 return (0);
300         return ((addr | size) & BUSDMA_DCACHE_MASK);
301 }
302
303 /*
304  * Return true if we might need to bounce the DMA described by addr and size.
305  *
306  * This is used to quick-check whether we need to do the more expensive work of
307  * checking the DMA page-by-page looking for alignment and exclusion bounces.
308  *
309  * Note that the addr argument might be either virtual or physical.  It doesn't
310  * matter because we only look at the low-order bits, which are the same in both
311  * address spaces and maximum alignment of generic buffer is limited up to page
312  * size.
313  * Bouncing of buffers allocated by bus_dmamem_alloc()is not necessary, these
314  * always comply with the required rules (alignment, boundary, and address
315  * range).
316  */
317 static __inline int
318 might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t addr,
319     bus_size_t size)
320 {
321
322         KASSERT(map->flags & DMAMAP_DMAMEM_ALLOC ||
323             dmat->alignment <= PAGE_SIZE,
324             ("%s: unsupported alignment (0x%08lx) for buffer not "
325             "allocated by bus_dmamem_alloc()",
326             __func__, dmat->alignment));
327
328         return (!(map->flags & DMAMAP_DMAMEM_ALLOC) &&
329             ((dmat->flags & BUS_DMA_EXCL_BOUNCE) ||
330             alignment_bounce(dmat, addr) ||
331             cacheline_bounce(map, addr, size)));
332 }
333
334 /*
335  * Return true if we must bounce the DMA described by paddr and size.
336  *
337  * Bouncing can be triggered by DMA that doesn't begin and end on cacheline
338  * boundaries, or doesn't begin on an alignment boundary, or falls within the
339  * exclusion zone of any tag in the ancestry chain.
340  *
341  * For exclusions, walk the chain of tags comparing paddr to the exclusion zone
342  * within each tag.  If the tag has a filter function, use it to decide whether
343  * the DMA needs to bounce, otherwise any DMA within the zone bounces.
344  */
345 static int
346 must_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t paddr,
347     bus_size_t size)
348 {
349
350         if (cacheline_bounce(map, paddr, size))
351                 return (1);
352
353         /*
354          *  The tag already contains ancestors' alignment restrictions so this
355          *  check doesn't need to be inside the loop.
356          */
357         if (alignment_bounce(dmat, paddr))
358                 return (1);
359
360         /*
361          * Even though each tag has an exclusion zone that is a superset of its
362          * own and all its ancestors' exclusions, the exclusion zone of each tag
363          * up the chain must be checked within the loop, because the busdma
364          * rules say the filter function is called only when the address lies
365          * within the low-highaddr range of the tag that filterfunc belongs to.
366          */
367         while (dmat != NULL && exclusion_bounce(dmat)) {
368                 if ((paddr >= dmat->lowaddr && paddr <= dmat->highaddr) &&
369                     (dmat->filter == NULL ||
370                     dmat->filter(dmat->filterarg, paddr) != 0))
371                         return (1);
372                 dmat = dmat->parent;
373         }
374
375         return (0);
376 }
377
378 /*
379  * Allocate a device specific dma_tag.
380  */
381 int
382 bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
383     bus_addr_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr,
384     bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize,
385     int nsegments, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
386     void *lockfuncarg, bus_dma_tag_t *dmat)
387 {
388         bus_dma_tag_t newtag;
389         int error = 0;
390
391         /* Basic sanity checking. */
392         KASSERT(boundary == 0 || powerof2(boundary),
393             ("dma tag boundary %lu, must be a power of 2", boundary));
394         KASSERT(boundary == 0 || boundary >= maxsegsz,
395             ("dma tag boundary %lu is < maxsegsz %lu\n", boundary, maxsegsz));
396         KASSERT(alignment != 0 && powerof2(alignment),
397             ("dma tag alignment %lu, must be non-zero power of 2", alignment));
398         KASSERT(maxsegsz != 0, ("dma tag maxsegsz must not be zero"));
399
400         /* Return a NULL tag on failure */
401         *dmat = NULL;
402
403         newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_BUSDMA,
404             M_ZERO | M_NOWAIT);
405         if (newtag == NULL) {
406                 CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
407                     __func__, newtag, 0, error);
408                 return (ENOMEM);
409         }
410
411         newtag->parent = parent;
412         newtag->alignment = alignment;
413         newtag->boundary = boundary;
414         newtag->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1);
415         newtag->highaddr = trunc_page((vm_paddr_t)highaddr) +
416             (PAGE_SIZE - 1);
417         newtag->filter = filter;
418         newtag->filterarg = filterarg;
419         newtag->maxsize = maxsize;
420         newtag->nsegments = nsegments;
421         newtag->maxsegsz = maxsegsz;
422         newtag->flags = flags;
423         newtag->ref_count = 1; /* Count ourself */
424         newtag->map_count = 0;
425         if (lockfunc != NULL) {
426                 newtag->lockfunc = lockfunc;
427                 newtag->lockfuncarg = lockfuncarg;
428         } else {
429                 newtag->lockfunc = _busdma_dflt_lock;
430                 newtag->lockfuncarg = NULL;
431         }
432
433         /* Take into account any restrictions imposed by our parent tag */
434         if (parent != NULL) {
435                 newtag->lowaddr = MIN(parent->lowaddr, newtag->lowaddr);
436                 newtag->highaddr = MAX(parent->highaddr, newtag->highaddr);
437                 newtag->alignment = MAX(parent->alignment, newtag->alignment);
438                 newtag->flags |= parent->flags & BUS_DMA_COULD_BOUNCE;
439                 newtag->flags |= parent->flags & BUS_DMA_COHERENT;
440                 if (newtag->boundary == 0)
441                         newtag->boundary = parent->boundary;
442                 else if (parent->boundary != 0)
443                         newtag->boundary = MIN(parent->boundary,
444                                                newtag->boundary);
445                 if (newtag->filter == NULL) {
446                         /*
447                          * Short circuit to looking at our parent directly
448                          * since we have encapsulated all of its information
449                          */
450                         newtag->filter = parent->filter;
451                         newtag->filterarg = parent->filterarg;
452                         newtag->parent = parent->parent;
453                 }
454                 if (newtag->parent != NULL)
455                         atomic_add_int(&parent->ref_count, 1);
456         }
457
458         if (exclusion_bounce_check(newtag->lowaddr, newtag->highaddr))
459                 newtag->flags |= BUS_DMA_EXCL_BOUNCE;
460         if (alignment_bounce(newtag, 1))
461                 newtag->flags |= BUS_DMA_ALIGN_BOUNCE;
462
463         /*
464          * Any request can auto-bounce due to cacheline alignment, in addition
465          * to any alignment or boundary specifications in the tag, so if the
466          * ALLOCNOW flag is set, there's always work to do.
467          */
468         if ((flags & BUS_DMA_ALLOCNOW) != 0) {
469                 struct bounce_zone *bz;
470                 /*
471                  * Round size up to a full page, and add one more page because
472                  * there can always be one more boundary crossing than the
473                  * number of pages in a transfer.
474                  */
475                 maxsize = roundup2(maxsize, PAGE_SIZE) + PAGE_SIZE;
476
477                 if ((error = alloc_bounce_zone(newtag)) != 0) {
478                         free(newtag, M_BUSDMA);
479                         return (error);
480                 }
481                 bz = newtag->bounce_zone;
482
483                 if (ptoa(bz->total_bpages) < maxsize) {
484                         int pages;
485
486                         pages = atop(maxsize) - bz->total_bpages;
487
488                         /* Add pages to our bounce pool */
489                         if (alloc_bounce_pages(newtag, pages) < pages)
490                                 error = ENOMEM;
491                 }
492                 /* Performed initial allocation */
493                 newtag->flags |= BUS_DMA_MIN_ALLOC_COMP;
494         } else
495                 newtag->bounce_zone = NULL;
496
497         if (error != 0) {
498                 free(newtag, M_BUSDMA);
499         } else {
500                 atomic_add_32(&tags_total, 1);
501                 *dmat = newtag;
502         }
503         CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
504             __func__, newtag, (newtag != NULL ? newtag->flags : 0), error);
505         return (error);
506 }
507
508 void
509 bus_dma_template_clone(bus_dma_template_t *t, bus_dma_tag_t dmat)
510 {
511
512         if (t == NULL || dmat == NULL)
513                 return;
514
515         t->parent = dmat->parent;
516         t->alignment = dmat->alignment;
517         t->boundary = dmat->boundary;
518         t->lowaddr = dmat->lowaddr;
519         t->highaddr = dmat->highaddr;
520         t->maxsize = dmat->maxsize;
521         t->nsegments = dmat->nsegments;
522         t->maxsegsize = dmat->maxsegsz;
523         t->flags = dmat->flags;
524         t->lockfunc = dmat->lockfunc;
525         t->lockfuncarg = dmat->lockfuncarg;
526 }
527
528 int
529 bus_dma_tag_set_domain(bus_dma_tag_t dmat, int domain)
530 {
531
532         return (0);
533 }
534
535 int
536 bus_dma_tag_destroy(bus_dma_tag_t dmat)
537 {
538         bus_dma_tag_t dmat_copy;
539         int error;
540
541         error = 0;
542         dmat_copy = dmat;
543
544         if (dmat != NULL) {
545                 if (dmat->map_count != 0) {
546                         error = EBUSY;
547                         goto out;
548                 }
549
550                 while (dmat != NULL) {
551                         bus_dma_tag_t parent;
552
553                         parent = dmat->parent;
554                         atomic_subtract_int(&dmat->ref_count, 1);
555                         if (dmat->ref_count == 0) {
556                                 atomic_subtract_32(&tags_total, 1);
557                                 free(dmat, M_BUSDMA);
558                                 /*
559                                  * Last reference count, so
560                                  * release our reference
561                                  * count on our parent.
562                                  */
563                                 dmat = parent;
564                         } else
565                                 dmat = NULL;
566                 }
567         }
568 out:
569         CTR3(KTR_BUSDMA, "%s tag %p error %d", __func__, dmat_copy, error);
570         return (error);
571 }
572
573 static int
574 allocate_bz_and_pages(bus_dma_tag_t dmat, bus_dmamap_t mapp)
575 {
576         struct bounce_zone *bz;
577         int maxpages;
578         int error;
579
580         if (dmat->bounce_zone == NULL)
581                 if ((error = alloc_bounce_zone(dmat)) != 0)
582                         return (error);
583         bz = dmat->bounce_zone;
584         /* Initialize the new map */
585         STAILQ_INIT(&(mapp->bpages));
586
587         /*
588          * Attempt to add pages to our pool on a per-instance basis up to a sane
589          * limit.  Even if the tag isn't flagged as COULD_BOUNCE due to
590          * alignment and boundary constraints, it could still auto-bounce due to
591          * cacheline alignment, which requires at most two bounce pages.
592          */
593         if (dmat->flags & BUS_DMA_COULD_BOUNCE)
594                 maxpages = MAX_BPAGES;
595         else
596                 maxpages = 2 * bz->map_count;
597         if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0 ||
598             (bz->map_count > 0 && bz->total_bpages < maxpages)) {
599                 int pages;
600
601                 pages = atop(roundup2(dmat->maxsize, PAGE_SIZE)) + 1;
602                 pages = MIN(maxpages - bz->total_bpages, pages);
603                 pages = MAX(pages, 2);
604                 if (alloc_bounce_pages(dmat, pages) < pages)
605                         return (ENOMEM);
606
607                 if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0)
608                         dmat->flags |= BUS_DMA_MIN_ALLOC_COMP;
609         }
610         bz->map_count++;
611         return (0);
612 }
613
614 static bus_dmamap_t
615 allocate_map(bus_dma_tag_t dmat, int mflags)
616 {
617         int mapsize, segsize;
618         bus_dmamap_t map;
619
620         /*
621          * Allocate the map.  The map structure ends with an embedded
622          * variable-sized array of sync_list structures.  Following that
623          * we allocate enough extra space to hold the array of bus_dma_segments.
624          */
625         KASSERT(dmat->nsegments <= MAX_DMA_SEGMENTS,
626            ("cannot allocate %u dma segments (max is %u)",
627             dmat->nsegments, MAX_DMA_SEGMENTS));
628         segsize = sizeof(struct bus_dma_segment) * dmat->nsegments;
629         mapsize = sizeof(*map) + sizeof(struct sync_list) * dmat->nsegments;
630         map = malloc(mapsize + segsize, M_BUSDMA, mflags | M_ZERO);
631         if (map == NULL) {
632                 CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__, dmat, ENOMEM);
633                 return (NULL);
634         }
635         map->segments = (bus_dma_segment_t *)((uintptr_t)map + mapsize);
636         STAILQ_INIT(&map->bpages);
637         return (map);
638 }
639
640 /*
641  * Allocate a handle for mapping from kva/uva/physical
642  * address space into bus device space.
643  */
644 int
645 bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
646 {
647         bus_dmamap_t map;
648         int error = 0;
649
650         *mapp = map = allocate_map(dmat, M_NOWAIT);
651         if (map == NULL) {
652                 CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__, dmat, ENOMEM);
653                 return (ENOMEM);
654         }
655
656         /*
657          * Bouncing might be required if the driver asks for an exclusion
658          * region, a data alignment that is stricter than 1, or DMA that begins
659          * or ends with a partial cacheline.  Whether bouncing will actually
660          * happen can't be known until mapping time, but we need to pre-allocate
661          * resources now because we might not be allowed to at mapping time.
662          */
663         error = allocate_bz_and_pages(dmat, map);
664         if (error != 0) {
665                 free(map, M_BUSDMA);
666                 *mapp = NULL;
667                 return (error);
668         }
669         if (map->flags & DMAMAP_COHERENT)
670                 atomic_add_32(&maps_coherent, 1);
671         atomic_add_32(&maps_total, 1);
672         dmat->map_count++;
673
674         return (0);
675 }
676
677 /*
678  * Destroy a handle for mapping from kva/uva/physical
679  * address space into bus device space.
680  */
681 int
682 bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
683 {
684
685         if (STAILQ_FIRST(&map->bpages) != NULL || map->sync_count != 0) {
686                 CTR3(KTR_BUSDMA, "%s: tag %p error %d",
687                     __func__, dmat, EBUSY);
688                 return (EBUSY);
689         }
690         if (dmat->bounce_zone)
691                 dmat->bounce_zone->map_count--;
692         if (map->flags & DMAMAP_COHERENT)
693                 atomic_subtract_32(&maps_coherent, 1);
694         atomic_subtract_32(&maps_total, 1);
695         free(map, M_BUSDMA);
696         dmat->map_count--;
697         CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat);
698         return (0);
699 }
700
701 /*
702  * Allocate a piece of memory that can be efficiently mapped into bus device
703  * space based on the constraints listed in the dma tag.  Returns a pointer to
704  * the allocated memory, and a pointer to an associated bus_dmamap.
705  */
706 int
707 bus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags,
708     bus_dmamap_t *mapp)
709 {
710         busdma_bufalloc_t ba;
711         struct busdma_bufzone *bufzone;
712         bus_dmamap_t map;
713         vm_memattr_t memattr;
714         int mflags;
715
716         if (flags & BUS_DMA_NOWAIT)
717                 mflags = M_NOWAIT;
718         else
719                 mflags = M_WAITOK;
720         if (flags & BUS_DMA_ZERO)
721                 mflags |= M_ZERO;
722
723         *mapp = map = allocate_map(dmat, mflags);
724         if (map == NULL) {
725                 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
726                     __func__, dmat, dmat->flags, ENOMEM);
727                 return (ENOMEM);
728         }
729         map->flags = DMAMAP_DMAMEM_ALLOC;
730
731         /* For coherent memory, set the map flag that disables sync ops. */
732         if (flags & BUS_DMA_COHERENT)
733                 map->flags |= DMAMAP_COHERENT;
734
735         /*
736          * Choose a busdma buffer allocator based on memory type flags.
737          * If the tag's COHERENT flag is set, that means normal memory
738          * is already coherent, use the normal allocator.
739          */
740         if ((flags & BUS_DMA_COHERENT) &&
741             ((dmat->flags & BUS_DMA_COHERENT) == 0)) {
742                 memattr = VM_MEMATTR_UNCACHEABLE;
743                 ba = coherent_allocator;
744         } else {
745                 memattr = VM_MEMATTR_DEFAULT;
746                 ba = standard_allocator;
747         }
748
749         /*
750          * Try to find a bufzone in the allocator that holds a cache of buffers
751          * of the right size for this request.  If the buffer is too big to be
752          * held in the allocator cache, this returns NULL.
753          */
754         bufzone = busdma_bufalloc_findzone(ba, dmat->maxsize);
755
756         /*
757          * Allocate the buffer from the uma(9) allocator if...
758          *  - It's small enough to be in the allocator (bufzone not NULL).
759          *  - The alignment constraint isn't larger than the allocation size
760          *    (the allocator aligns buffers to their size boundaries).
761          *  - There's no need to handle lowaddr/highaddr exclusion zones.
762          * else allocate non-contiguous pages if...
763          *  - The page count that could get allocated doesn't exceed
764          *    nsegments also when the maximum segment size is less
765          *    than PAGE_SIZE.
766          *  - The alignment constraint isn't larger than a page boundary.
767          *  - There are no boundary-crossing constraints.
768          * else allocate a block of contiguous pages because one or more of the
769          * constraints is something that only the contig allocator can fulfill.
770          */
771         if (bufzone != NULL && dmat->alignment <= bufzone->size &&
772             !exclusion_bounce(dmat)) {
773                 *vaddr = uma_zalloc(bufzone->umazone, mflags);
774         } else if (dmat->nsegments >=
775             howmany(dmat->maxsize, MIN(dmat->maxsegsz, PAGE_SIZE)) &&
776             dmat->alignment <= PAGE_SIZE &&
777             (dmat->boundary % PAGE_SIZE) == 0) {
778                 *vaddr = (void *)kmem_alloc_attr(dmat->maxsize, mflags, 0,
779                     dmat->lowaddr, memattr);
780         } else {
781                 *vaddr = (void *)kmem_alloc_contig(dmat->maxsize, mflags, 0,
782                     dmat->lowaddr, dmat->alignment, dmat->boundary, memattr);
783         }
784         if (*vaddr == NULL) {
785                 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
786                     __func__, dmat, dmat->flags, ENOMEM);
787                 free(map, M_BUSDMA);
788                 *mapp = NULL;
789                 return (ENOMEM);
790         }
791         if (map->flags & DMAMAP_COHERENT)
792                 atomic_add_32(&maps_coherent, 1);
793         atomic_add_32(&maps_dmamem, 1);
794         atomic_add_32(&maps_total, 1);
795         dmat->map_count++;
796
797         CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
798             __func__, dmat, dmat->flags, 0);
799         return (0);
800 }
801
802 /*
803  * Free a piece of memory that was allocated via bus_dmamem_alloc, along with
804  * its associated map.
805  */
806 void
807 bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
808 {
809         struct busdma_bufzone *bufzone;
810         busdma_bufalloc_t ba;
811
812         if ((map->flags & DMAMAP_COHERENT) &&
813             ((dmat->flags & BUS_DMA_COHERENT) == 0))
814                 ba = coherent_allocator;
815         else
816                 ba = standard_allocator;
817
818         bufzone = busdma_bufalloc_findzone(ba, dmat->maxsize);
819
820         if (bufzone != NULL && dmat->alignment <= bufzone->size &&
821             !exclusion_bounce(dmat))
822                 uma_zfree(bufzone->umazone, vaddr);
823         else
824                 kmem_free((vm_offset_t)vaddr, dmat->maxsize);
825
826         dmat->map_count--;
827         if (map->flags & DMAMAP_COHERENT)
828                 atomic_subtract_32(&maps_coherent, 1);
829         atomic_subtract_32(&maps_total, 1);
830         atomic_subtract_32(&maps_dmamem, 1);
831         free(map, M_BUSDMA);
832         CTR3(KTR_BUSDMA, "%s: tag %p flags 0x%x", __func__, dmat, dmat->flags);
833 }
834
835 static void
836 _bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf,
837     bus_size_t buflen, int flags)
838 {
839         bus_addr_t curaddr;
840         bus_size_t sgsize;
841
842         if (map->pagesneeded == 0) {
843                 CTR5(KTR_BUSDMA, "lowaddr= %d, boundary= %d, alignment= %d"
844                     " map= %p, pagesneeded= %d",
845                     dmat->lowaddr, dmat->boundary, dmat->alignment,
846                     map, map->pagesneeded);
847                 /*
848                  * Count the number of bounce pages
849                  * needed in order to complete this transfer
850                  */
851                 curaddr = buf;
852                 while (buflen != 0) {
853                         sgsize = MIN(buflen, dmat->maxsegsz);
854                         if (must_bounce(dmat, map, curaddr, sgsize) != 0) {
855                                 sgsize = MIN(sgsize,
856                                     PAGE_SIZE - (curaddr & PAGE_MASK));
857                                 map->pagesneeded++;
858                         }
859                         curaddr += sgsize;
860                         buflen -= sgsize;
861                 }
862                 CTR1(KTR_BUSDMA, "pagesneeded= %d", map->pagesneeded);
863         }
864 }
865
866 static void
867 _bus_dmamap_count_pages(bus_dma_tag_t dmat, pmap_t pmap, bus_dmamap_t map,
868     void *buf, bus_size_t buflen, int flags)
869 {
870         vm_offset_t vaddr;
871         vm_offset_t vendaddr;
872         bus_addr_t paddr;
873
874         if (map->pagesneeded == 0) {
875                 CTR5(KTR_BUSDMA, "lowaddr= %d, boundary= %d, alignment= %d"
876                     " map= %p, pagesneeded= %d",
877                     dmat->lowaddr, dmat->boundary, dmat->alignment,
878                     map, map->pagesneeded);
879                 /*
880                  * Count the number of bounce pages
881                  * needed in order to complete this transfer
882                  */
883                 vaddr = (vm_offset_t)buf;
884                 vendaddr = (vm_offset_t)buf + buflen;
885
886                 while (vaddr < vendaddr) {
887                         if (__predict_true(pmap == kernel_pmap))
888                                 paddr = pmap_kextract(vaddr);
889                         else
890                                 paddr = pmap_extract(pmap, vaddr);
891                         if (must_bounce(dmat, map, paddr,
892                             min(vendaddr - vaddr, (PAGE_SIZE - ((vm_offset_t)vaddr &
893                             PAGE_MASK)))) != 0) {
894                                 map->pagesneeded++;
895                         }
896                         vaddr += (PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK));
897                 }
898                 CTR1(KTR_BUSDMA, "pagesneeded= %d", map->pagesneeded);
899         }
900 }
901
902 /*
903  * Add a single contiguous physical range to the segment list.
904  */
905 static int
906 _bus_dmamap_addseg(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t curaddr,
907     bus_size_t sgsize, bus_dma_segment_t *segs, int *segp)
908 {
909         int seg;
910
911         /*
912          * Make sure we don't cross any boundaries.
913          */
914         if (!vm_addr_bound_ok(curaddr, sgsize, dmat->boundary))
915                 sgsize = roundup2(curaddr, dmat->boundary) - curaddr;
916
917         /*
918          * Insert chunk into a segment, coalescing with
919          * previous segment if possible.
920          */
921         seg = *segp;
922         if (seg == -1) {
923                 seg = 0;
924                 segs[seg].ds_addr = curaddr;
925                 segs[seg].ds_len = sgsize;
926         } else {
927                 if (curaddr == segs[seg].ds_addr + segs[seg].ds_len &&
928                     (segs[seg].ds_len + sgsize) <= dmat->maxsegsz &&
929                     vm_addr_bound_ok(segs[seg].ds_addr,
930                     segs[seg].ds_len + sgsize, dmat->boundary))
931                         segs[seg].ds_len += sgsize;
932                 else {
933                         if (++seg >= dmat->nsegments)
934                                 return (0);
935                         segs[seg].ds_addr = curaddr;
936                         segs[seg].ds_len = sgsize;
937                 }
938         }
939         *segp = seg;
940         return (sgsize);
941 }
942
943 /*
944  * Utility function to load a physical buffer.  segp contains
945  * the starting segment on entrace, and the ending segment on exit.
946  */
947 int
948 _bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf,
949     bus_size_t buflen, int flags, bus_dma_segment_t *segs, int *segp)
950 {
951         bus_addr_t curaddr;
952         bus_addr_t sl_end = 0;
953         bus_size_t sgsize;
954         struct sync_list *sl;
955         int error;
956
957         if (segs == NULL)
958                 segs = map->segments;
959
960 #ifdef ARM_BUSDMA_MAPLOAD_STATS
961         counter_u64_add(maploads_total, 1);
962         counter_u64_add(maploads_physmem, 1);
963 #endif
964
965         if (might_bounce(dmat, map, (bus_addr_t)buf, buflen)) {
966                 _bus_dmamap_count_phys(dmat, map, buf, buflen, flags);
967                 if (map->pagesneeded != 0) {
968 #ifdef ARM_BUSDMA_MAPLOAD_STATS
969                         counter_u64_add(maploads_bounced, 1);
970 #endif
971                         error = _bus_dmamap_reserve_pages(dmat, map, flags);
972                         if (error)
973                                 return (error);
974                 }
975         }
976
977         sl = map->slist + map->sync_count - 1;
978
979         while (buflen > 0) {
980                 curaddr = buf;
981                 sgsize = MIN(buflen, dmat->maxsegsz);
982                 if (map->pagesneeded != 0 && must_bounce(dmat, map, curaddr,
983                     sgsize)) {
984                         sgsize = MIN(sgsize, PAGE_SIZE - (curaddr & PAGE_MASK));
985                         curaddr = add_bounce_page(dmat, map, 0, curaddr,
986                             sgsize);
987                 } else if ((dmat->flags & BUS_DMA_COHERENT) == 0) {
988                         if (map->sync_count > 0)
989                                 sl_end = sl->paddr + sl->datacount;
990
991                         if (map->sync_count == 0 || curaddr != sl_end) {
992                                 if (++map->sync_count > dmat->nsegments)
993                                         break;
994                                 sl++;
995                                 sl->vaddr = 0;
996                                 sl->paddr = curaddr;
997                                 sl->datacount = sgsize;
998                                 sl->pages = PHYS_TO_VM_PAGE(curaddr);
999                                 KASSERT(sl->pages != NULL,
1000                                     ("%s: page at PA:0x%08lx is not in "
1001                                     "vm_page_array", __func__, curaddr));
1002                         } else
1003                                 sl->datacount += sgsize;
1004                 }
1005                 sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
1006                     segp);
1007                 if (sgsize == 0)
1008                         break;
1009                 buf += sgsize;
1010                 buflen -= sgsize;
1011         }
1012
1013         /*
1014          * Did we fit?
1015          */
1016         if (buflen != 0) {
1017                 bus_dmamap_unload(dmat, map);
1018                 return (EFBIG); /* XXX better return value here? */
1019         }
1020         return (0);
1021 }
1022
1023 int
1024 _bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map,
1025     struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
1026     bus_dma_segment_t *segs, int *segp)
1027 {
1028
1029         return (bus_dmamap_load_ma_triv(dmat, map, ma, tlen, ma_offs, flags,
1030             segs, segp));
1031 }
1032
1033 /*
1034  * Utility function to load a linear buffer.  segp contains
1035  * the starting segment on entrance, and the ending segment on exit.
1036  */
1037 int
1038 _bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
1039     bus_size_t buflen, pmap_t pmap, int flags, bus_dma_segment_t *segs,
1040     int *segp)
1041 {
1042         bus_size_t sgsize;
1043         bus_addr_t curaddr;
1044         bus_addr_t sl_pend = 0;
1045         vm_offset_t kvaddr, vaddr, sl_vend = 0;
1046         struct sync_list *sl;
1047         int error;
1048
1049 #ifdef ARM_BUSDMA_MAPLOAD_STATS
1050         counter_u64_add(maploads_total, 1);
1051         if (map->flags & DMAMAP_COHERENT)
1052                 counter_u64_add(maploads_coherent, 1);
1053         if (map->flags & DMAMAP_DMAMEM_ALLOC)
1054                 counter_u64_add(maploads_dmamem, 1);
1055 #endif
1056
1057         if (segs == NULL)
1058                 segs = map->segments;
1059
1060         if (flags & BUS_DMA_LOAD_MBUF) {
1061 #ifdef ARM_BUSDMA_MAPLOAD_STATS
1062                 counter_u64_add(maploads_mbuf, 1);
1063 #endif
1064                 map->flags |= DMAMAP_MBUF;
1065         }
1066
1067         if (might_bounce(dmat, map, (bus_addr_t)buf, buflen)) {
1068                 _bus_dmamap_count_pages(dmat, pmap, map, buf, buflen, flags);
1069                 if (map->pagesneeded != 0) {
1070 #ifdef ARM_BUSDMA_MAPLOAD_STATS
1071                         counter_u64_add(maploads_bounced, 1);
1072 #endif
1073                         error = _bus_dmamap_reserve_pages(dmat, map, flags);
1074                         if (error)
1075                                 return (error);
1076                 }
1077         }
1078
1079         sl = map->slist + map->sync_count - 1;
1080         vaddr = (vm_offset_t)buf;
1081
1082         while (buflen > 0) {
1083                 /*
1084                  * Get the physical address for this segment.
1085                  */
1086                 if (__predict_true(pmap == kernel_pmap)) {
1087                         curaddr = pmap_kextract(vaddr);
1088                         kvaddr = vaddr;
1089                 } else {
1090                         curaddr = pmap_extract(pmap, vaddr);
1091                         kvaddr = 0;
1092                 }
1093
1094                 /*
1095                  * Compute the segment size, and adjust counts.
1096                  */
1097                 sgsize = PAGE_SIZE - (curaddr & PAGE_MASK);
1098                 if (sgsize > dmat->maxsegsz)
1099                         sgsize = dmat->maxsegsz;
1100                 if (buflen < sgsize)
1101                         sgsize = buflen;
1102
1103                 if (map->pagesneeded != 0 && must_bounce(dmat, map, curaddr,
1104                     sgsize)) {
1105                         curaddr = add_bounce_page(dmat, map, kvaddr, curaddr,
1106                             sgsize);
1107                 } else if ((dmat->flags & BUS_DMA_COHERENT) == 0) {
1108                         if (map->sync_count > 0) {
1109                                 sl_pend = sl->paddr + sl->datacount;
1110                                 sl_vend = sl->vaddr + sl->datacount;
1111                         }
1112
1113                         if (map->sync_count == 0 ||
1114                             (kvaddr != 0 && kvaddr != sl_vend) ||
1115                             (curaddr != sl_pend)) {
1116                                 if (++map->sync_count > dmat->nsegments)
1117                                         goto cleanup;
1118                                 sl++;
1119                                 sl->vaddr = kvaddr;
1120                                 sl->paddr = curaddr;
1121                                 if (kvaddr != 0) {
1122                                         sl->pages = NULL;
1123                                 } else {
1124                                         sl->pages = PHYS_TO_VM_PAGE(curaddr);
1125                                         KASSERT(sl->pages != NULL,
1126                                             ("%s: page at PA:0x%08lx is not "
1127                                             "in vm_page_array", __func__,
1128                                             curaddr));
1129                                 }
1130                                 sl->datacount = sgsize;
1131                         } else
1132                                 sl->datacount += sgsize;
1133                 }
1134                 sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
1135                     segp);
1136                 if (sgsize == 0)
1137                         break;
1138                 vaddr += sgsize;
1139                 buflen -= sgsize;
1140         }
1141
1142 cleanup:
1143         /*
1144          * Did we fit?
1145          */
1146         if (buflen != 0) {
1147                 bus_dmamap_unload(dmat, map);
1148                 return (EFBIG); /* XXX better return value here? */
1149         }
1150         return (0);
1151 }
1152
1153 void
1154 _bus_dmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map, struct memdesc *mem,
1155     bus_dmamap_callback_t *callback, void *callback_arg)
1156 {
1157
1158         map->mem = *mem;
1159         map->dmat = dmat;
1160         map->callback = callback;
1161         map->callback_arg = callback_arg;
1162 }
1163
1164 bus_dma_segment_t *
1165 _bus_dmamap_complete(bus_dma_tag_t dmat, bus_dmamap_t map,
1166     bus_dma_segment_t *segs, int nsegs, int error)
1167 {
1168
1169         if (segs == NULL)
1170                 segs = map->segments;
1171         return (segs);
1172 }
1173
1174 /*
1175  * Release the mapping held by map.
1176  */
1177 void
1178 bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
1179 {
1180         struct bounce_page *bpage;
1181         struct bounce_zone *bz;
1182
1183         if ((bz = dmat->bounce_zone) != NULL) {
1184                 while ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
1185                         STAILQ_REMOVE_HEAD(&map->bpages, links);
1186                         free_bounce_page(dmat, bpage);
1187                 }
1188
1189                 bz = dmat->bounce_zone;
1190                 bz->free_bpages += map->pagesreserved;
1191                 bz->reserved_bpages -= map->pagesreserved;
1192                 map->pagesreserved = 0;
1193                 map->pagesneeded = 0;
1194         }
1195         map->sync_count = 0;
1196         map->flags &= ~DMAMAP_MBUF;
1197 }
1198
1199 static void
1200 dma_preread_safe(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
1201 {
1202         /*
1203          * Write back any partial cachelines immediately before and
1204          * after the DMA region.  We don't need to round the address
1205          * down to the nearest cacheline or specify the exact size,
1206          * as dcache_wb_poc() will do the rounding for us and works
1207          * at cacheline granularity.
1208          */
1209         if (va & BUSDMA_DCACHE_MASK)
1210                 dcache_wb_poc(va, pa, 1);
1211         if ((va + size) & BUSDMA_DCACHE_MASK)
1212                 dcache_wb_poc(va + size, pa + size, 1);
1213
1214         dcache_inv_poc_dma(va, pa, size);
1215 }
1216
1217 static void
1218 dma_dcache_sync(struct sync_list *sl, bus_dmasync_op_t op)
1219 {
1220         uint32_t len, offset;
1221         vm_page_t m;
1222         vm_paddr_t pa;
1223         vm_offset_t va, tempva;
1224         bus_size_t size;
1225
1226         offset = sl->paddr & PAGE_MASK;
1227         m = sl->pages;
1228         size = sl->datacount;
1229         pa = sl->paddr;
1230
1231         for ( ; size != 0; size -= len, pa += len, offset = 0, ++m) {
1232                 tempva = 0;
1233                 if (sl->vaddr == 0) {
1234                         len = min(PAGE_SIZE - offset, size);
1235                         tempva = pmap_quick_enter_page(m);
1236                         va = tempva | offset;
1237                         KASSERT(pa == (VM_PAGE_TO_PHYS(m) | offset),
1238                             ("unexpected vm_page_t phys: 0x%08x != 0x%08x",
1239                             VM_PAGE_TO_PHYS(m) | offset, pa));
1240                 } else {
1241                         len = sl->datacount;
1242                         va = sl->vaddr;
1243                 }
1244
1245                 switch (op) {
1246                 case BUS_DMASYNC_PREWRITE:
1247                 case BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD:
1248                         dcache_wb_poc(va, pa, len);
1249                         break;
1250                 case BUS_DMASYNC_PREREAD:
1251                         /*
1252                          * An mbuf may start in the middle of a cacheline. There
1253                          * will be no cpu writes to the beginning of that line
1254                          * (which contains the mbuf header) while dma is in
1255                          * progress.  Handle that case by doing a writeback of
1256                          * just the first cacheline before invalidating the
1257                          * overall buffer.  Any mbuf in a chain may have this
1258                          * misalignment.  Buffers which are not mbufs bounce if
1259                          * they are not aligned to a cacheline.
1260                          */
1261                         dma_preread_safe(va, pa, len);
1262                         break;
1263                 case BUS_DMASYNC_POSTREAD:
1264                 case BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE:
1265                         dcache_inv_poc(va, pa, len);
1266                         break;
1267                 default:
1268                         panic("unsupported combination of sync operations: "
1269                               "0x%08x\n", op);
1270                 }
1271
1272                 if (tempva != 0)
1273                         pmap_quick_remove_page(tempva);
1274         }
1275 }
1276
1277 void
1278 bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
1279 {
1280         struct bounce_page *bpage;
1281         struct sync_list *sl, *end;
1282         vm_offset_t datavaddr, tempvaddr;
1283
1284         if (op == BUS_DMASYNC_POSTWRITE)
1285                 return;
1286
1287         /*
1288          * If the buffer was from user space, it is possible that this is not
1289          * the same vm map, especially on a POST operation.  It's not clear that
1290          * dma on userland buffers can work at all right now.  To be safe, until
1291          * we're able to test direct userland dma, panic on a map mismatch.
1292          */
1293         if ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
1294                 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
1295                     "performing bounce", __func__, dmat, dmat->flags, op);
1296
1297                 /*
1298                  * For PREWRITE do a writeback.  Clean the caches from the
1299                  * innermost to the outermost levels.
1300                  */
1301                 if (op & BUS_DMASYNC_PREWRITE) {
1302                         while (bpage != NULL) {
1303                                 tempvaddr = 0;
1304                                 datavaddr = bpage->datavaddr;
1305                                 if (datavaddr == 0) {
1306                                         tempvaddr = pmap_quick_enter_page(
1307                                             bpage->datapage);
1308                                         datavaddr = tempvaddr | bpage->dataoffs;
1309                                 }
1310                                 bcopy((void *)datavaddr, (void *)bpage->vaddr,
1311                                     bpage->datacount);
1312                                 if (tempvaddr != 0)
1313                                         pmap_quick_remove_page(tempvaddr);
1314                                 if ((dmat->flags & BUS_DMA_COHERENT) == 0)
1315                                         dcache_wb_poc(bpage->vaddr,
1316                                             bpage->busaddr, bpage->datacount);
1317                                 bpage = STAILQ_NEXT(bpage, links);
1318                         }
1319                         dmat->bounce_zone->total_bounced++;
1320                 }
1321
1322                 /*
1323                  * Do an invalidate for PREREAD unless a writeback was already
1324                  * done above due to PREWRITE also being set.  The reason for a
1325                  * PREREAD invalidate is to prevent dirty lines currently in the
1326                  * cache from being evicted during the DMA.  If a writeback was
1327                  * done due to PREWRITE also being set there will be no dirty
1328                  * lines and the POSTREAD invalidate handles the rest. The
1329                  * invalidate is done from the innermost to outermost level. If
1330                  * L2 were done first, a dirty cacheline could be automatically
1331                  * evicted from L1 before we invalidated it, re-dirtying the L2.
1332                  */
1333                 if ((op & BUS_DMASYNC_PREREAD) && !(op & BUS_DMASYNC_PREWRITE)) {
1334                         bpage = STAILQ_FIRST(&map->bpages);
1335                         while (bpage != NULL) {
1336                                 if ((dmat->flags & BUS_DMA_COHERENT) == 0)
1337                                         dcache_inv_poc_dma(bpage->vaddr,
1338                                             bpage->busaddr, bpage->datacount);
1339                                 bpage = STAILQ_NEXT(bpage, links);
1340                         }
1341                 }
1342
1343                 /*
1344                  * Re-invalidate the caches on a POSTREAD, even though they were
1345                  * already invalidated at PREREAD time.  Aggressive prefetching
1346                  * due to accesses to other data near the dma buffer could have
1347                  * brought buffer data into the caches which is now stale.  The
1348                  * caches are invalidated from the outermost to innermost; the
1349                  * prefetches could be happening right now, and if L1 were
1350                  * invalidated first, stale L2 data could be prefetched into L1.
1351                  */
1352                 if (op & BUS_DMASYNC_POSTREAD) {
1353                         while (bpage != NULL) {
1354                                 if ((dmat->flags & BUS_DMA_COHERENT) == 0)
1355                                         dcache_inv_poc(bpage->vaddr,
1356                                             bpage->busaddr, bpage->datacount);
1357                                 tempvaddr = 0;
1358                                 datavaddr = bpage->datavaddr;
1359                                 if (datavaddr == 0) {
1360                                         tempvaddr = pmap_quick_enter_page(
1361                                             bpage->datapage);
1362                                         datavaddr = tempvaddr | bpage->dataoffs;
1363                                 }
1364                                 bcopy((void *)bpage->vaddr, (void *)datavaddr,
1365                                     bpage->datacount);
1366                                 if (tempvaddr != 0)
1367                                         pmap_quick_remove_page(tempvaddr);
1368                                 bpage = STAILQ_NEXT(bpage, links);
1369                         }
1370                         dmat->bounce_zone->total_bounced++;
1371                 }
1372         }
1373
1374         /*
1375          * For COHERENT memory no cache maintenance is necessary, but ensure all
1376          * writes have reached memory for the PREWRITE case.  No action is
1377          * needed for a PREREAD without PREWRITE also set, because that would
1378          * imply that the cpu had written to the COHERENT buffer and expected
1379          * the dma device to see that change, and by definition a PREWRITE sync
1380          * is required to make that happen.
1381          */
1382         if (map->flags & DMAMAP_COHERENT) {
1383                 if (op & BUS_DMASYNC_PREWRITE) {
1384                         dsb();
1385                         if ((dmat->flags & BUS_DMA_COHERENT) == 0)
1386                                 cpu_l2cache_drain_writebuf();
1387                 }
1388                 return;
1389         }
1390
1391         /*
1392          * Cache maintenance for normal (non-COHERENT non-bounce) buffers.  All
1393          * the comments about the sequences for flushing cache levels in the
1394          * bounce buffer code above apply here as well.  In particular, the fact
1395          * that the sequence is inner-to-outer for PREREAD invalidation and
1396          * outer-to-inner for POSTREAD invalidation is not a mistake.
1397          */
1398         if (map->sync_count != 0) {
1399                 sl = &map->slist[0];
1400                 end = &map->slist[map->sync_count];
1401                 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
1402                     "performing sync", __func__, dmat, dmat->flags, op);
1403
1404                 for ( ; sl != end; ++sl)
1405                         dma_dcache_sync(sl, op);
1406         }
1407 }