]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/sparc64/sparc64/iommu.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / sparc64 / sparc64 / iommu.c
1 /*-
2  * Copyright (c) 1999, 2000 Matthew R. Green
3  * Copyright (c) 2001-2003 Thomas Moestl
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 /*-
30  * Copyright (c) 1998 The NetBSD Foundation, Inc.
31  * All rights reserved.
32  *
33  * This code is derived from software contributed to The NetBSD Foundation
34  * by Paul Kranenburg.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  * 3. All advertising materials mentioning features or use of this software
45  *    must display the following acknowledgement:
46  *        This product includes software developed by the NetBSD
47  *        Foundation, Inc. and its contributors.
48  * 4. Neither the name of The NetBSD Foundation nor the names of its
49  *    contributors may be used to endorse or promote products derived
50  *    from this software without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
53  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
54  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
55  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
56  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
57  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
58  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
59  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
60  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
61  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62  * POSSIBILITY OF SUCH DAMAGE.
63  */
64 /*-
65  * Copyright (c) 1992, 1993
66  *      The Regents of the University of California.  All rights reserved.
67  *
68  * This software was developed by the Computer Systems Engineering group
69  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
70  * contributed to Berkeley.
71  *
72  * Redistribution and use in source and binary forms, with or without
73  * modification, are permitted provided that the following conditions
74  * are met:
75  * 1. Redistributions of source code must retain the above copyright
76  *    notice, this list of conditions and the following disclaimer.
77  * 2. Redistributions in binary form must reproduce the above copyright
78  *    notice, this list of conditions and the following disclaimer in the
79  *    documentation and/or other materials provided with the distribution.
80  * 4. Neither the name of the University nor the names of its contributors
81  *    may be used to endorse or promote products derived from this software
82  *    without specific prior written permission.
83  *
84  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
85  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
86  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
87  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
88  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
89  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
90  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
91  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
92  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
93  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
94  * SUCH DAMAGE.
95  *
96  *      from: NetBSD: sbus.c,v 1.13 1999/05/23 07:24:02 mrg Exp
97  *      from: @(#)sbus.c        8.1 (Berkeley) 6/11/93
98  *      from: NetBSD: iommu.c,v 1.42 2001/08/06 22:02:58 eeh Exp
99  */
100
101 #include <sys/cdefs.h>
102 __FBSDID("$FreeBSD$");
103
104 /*
105  * UltraSPARC IOMMU support; used by both the PCI and SBus code.
106  *
107  * TODO:
108  * - Support sub-page boundaries.
109  * - Fix alignment handling for small allocations (the possible page offset
110  *   of malloc()ed memory is not handled at all).  Revise interaction of
111  *   alignment with the load_mbuf and load_uio functions.
112  * - Handle lowaddr and highaddr in some way, and try to work out a way
113  *   for filter callbacks to work.  Currently, only lowaddr is honored
114  *   in that no addresses above it are considered at all.
115  * - Implement BUS_DMA_ALLOCNOW in bus_dma_tag_create as far as possible.
116  * - Check the possible return values and callback error arguments;
117  *   the callback currently gets called in error conditions where it should
118  *   not be.
119  * - When running out of DVMA space, return EINPROGRESS in the non-
120  *   BUS_DMA_NOWAIT case and delay the callback until sufficient space
121  *   becomes available.
122  * - Use the streaming cache unless BUS_DMA_COHERENT is specified.
123  */
124
125 #include "opt_iommu.h"
126
127 #include <sys/param.h>
128 #include <sys/kernel.h>
129 #include <sys/lock.h>
130 #include <sys/malloc.h>
131 #include <sys/mbuf.h>
132 #include <sys/mutex.h>
133 #include <sys/pcpu.h>
134 #include <sys/proc.h>
135 #include <sys/systm.h>
136 #include <sys/uio.h>
137
138 #include <vm/vm.h>
139 #include <vm/pmap.h>
140 #include <vm/vm_map.h>
141
142 #include <machine/asi.h>
143 #include <machine/bus.h>
144 #include <machine/bus_private.h>
145 #include <machine/iommureg.h>
146 #include <machine/pmap.h>
147 #include <machine/resource.h>
148 #include <machine/ver.h>
149
150 #include <sys/rman.h>
151
152 #include <machine/iommuvar.h>
153
154 /*
155  * Tuning constants
156  */
157 #define IOMMU_MAX_PRE           (32 * 1024)
158 #define IOMMU_MAX_PRE_SEG       3
159
160 /* Threshold for using the streaming buffer */
161 #define IOMMU_STREAM_THRESH     128
162
163 MALLOC_DEFINE(M_IOMMU, "dvmamem", "IOMMU DVMA Buffers");
164
165 static  int iommu_strbuf_flush_sync(struct iommu_state *);
166 #ifdef IOMMU_DIAG
167 static  void iommu_diag(struct iommu_state *, vm_offset_t va);
168 #endif
169
170 /*
171  * Helpers
172  */
173 #define IOMMU_READ8(is, reg, off)                                       \
174         bus_space_read_8((is)->is_bustag, (is)->is_bushandle,           \
175             (is)->reg + (off))
176 #define IOMMU_WRITE8(is, reg, off, v)                                   \
177         bus_space_write_8((is)->is_bustag, (is)->is_bushandle,          \
178             (is)->reg + (off), (v))
179
180 #define IOMMU_HAS_SB(is)                                                \
181         ((is)->is_sb[0] != 0 || (is)->is_sb[1] != 0)
182
183 /*
184  * Always overallocate one page; this is needed to handle alignment of the
185  * buffer, so it makes sense using a lazy allocation scheme.
186  */
187 #define IOMMU_SIZE_ROUNDUP(sz)                                          \
188         (round_io_page(sz) + IO_PAGE_SIZE)
189
190 #define IOMMU_SET_TTE(is, va, tte)                                      \
191         ((is)->is_tsb[IOTSBSLOT(va)] = (tte))
192 #define IOMMU_GET_TTE(is, va)                                           \
193         (is)->is_tsb[IOTSBSLOT(va)]
194
195 /* Resource helpers */
196 #define IOMMU_RES_START(res)                                            \
197         ((bus_addr_t)rman_get_start(res) << IO_PAGE_SHIFT)
198 #define IOMMU_RES_END(res)                                              \
199         ((bus_addr_t)(rman_get_end(res) + 1) << IO_PAGE_SHIFT)
200 #define IOMMU_RES_SIZE(res)                                             \
201         ((bus_size_t)rman_get_size(res) << IO_PAGE_SHIFT)
202
203 /* Helpers for struct bus_dmamap_res */
204 #define BDR_START(r)    IOMMU_RES_START((r)->dr_res)
205 #define BDR_END(r)      IOMMU_RES_END((r)->dr_res)
206 #define BDR_SIZE(r)     IOMMU_RES_SIZE((r)->dr_res)
207
208 /* Locking macros */
209 #define IS_LOCK(is)     mtx_lock(&is->is_mtx)
210 #define IS_LOCK_ASSERT(is)      mtx_assert(&is->is_mtx, MA_OWNED)
211 #define IS_UNLOCK(is)   mtx_unlock(&is->is_mtx)
212
213 /* Flush a page from the TLB.  No locking required, since this is atomic. */
214 static __inline void
215 iommu_tlb_flush(struct iommu_state *is, bus_addr_t va)
216 {
217
218         if ((is->is_flags & IOMMU_FIRE) != 0)
219                 /*
220                  * Direct page flushing is not supported and also not
221                  * necessary due to cache snooping.
222                  */
223                 return;
224         IOMMU_WRITE8(is, is_iommu, IMR_FLUSH, va);
225 }
226
227 /*
228  * Flush a page from the streaming buffer.  No locking required, since this
229  * is atomic.
230  */
231 static __inline void
232 iommu_strbuf_flushpg(struct iommu_state *is, bus_addr_t va)
233 {
234         int i;
235
236         for (i = 0; i < 2; i++)
237                 if (is->is_sb[i] != 0)
238                         IOMMU_WRITE8(is, is_sb[i], ISR_PGFLUSH, va);
239 }
240
241 /*
242  * Flush an address from the streaming buffer(s); this is an asynchronous
243  * operation.  To make sure that it has completed, iommu_strbuf_sync() needs
244  * to be called.  No locking required.
245  */
246 static __inline void
247 iommu_strbuf_flush(struct iommu_state *is, bus_addr_t va)
248 {
249
250         iommu_strbuf_flushpg(is, va);
251 }
252
253 /* Synchronize all outstanding flush operations. */
254 static __inline void
255 iommu_strbuf_sync(struct iommu_state *is)
256 {
257
258         IS_LOCK_ASSERT(is);
259         iommu_strbuf_flush_sync(is);
260 }
261
262 /* LRU queue handling for lazy resource allocation. */
263 static __inline void
264 iommu_map_insq(struct iommu_state *is, bus_dmamap_t map)
265 {
266
267         IS_LOCK_ASSERT(is);
268         if (!SLIST_EMPTY(&map->dm_reslist)) {
269                 if (map->dm_onq)
270                         TAILQ_REMOVE(&is->is_maplruq, map, dm_maplruq);
271                 TAILQ_INSERT_TAIL(&is->is_maplruq, map, dm_maplruq);
272                 map->dm_onq = 1;
273         }
274 }
275
276 static __inline void
277 iommu_map_remq(struct iommu_state *is, bus_dmamap_t map)
278 {
279
280         IS_LOCK_ASSERT(is);
281         if (map->dm_onq)
282                 TAILQ_REMOVE(&is->is_maplruq, map, dm_maplruq);
283         map->dm_onq = 0;
284 }
285
286 /*
287  * initialise the UltraSPARC IOMMU (PCI or SBus):
288  *      - allocate and setup the iotsb.
289  *      - enable the IOMMU
290  *      - initialise the streaming buffers (if they exist)
291  *      - create a private DVMA map.
292  */
293 void
294 iommu_init(const char *name, struct iommu_state *is, u_int tsbsize,
295     uint32_t iovabase, u_int resvpg)
296 {
297         vm_size_t size;
298         vm_offset_t offs;
299         uint64_t end, obpmap, obpptsb, tte;
300         u_int maxtsbsize, obptsbentries, obptsbsize, slot, tsbentries;
301         int i;
302
303         /*
304          * Setup the IOMMU.
305          *
306          * The sun4u IOMMU is part of the PCI or SBus controller so we
307          * will deal with it here..
308          *
309          * The IOMMU address space always ends at 0xffffe000, but the starting
310          * address depends on the size of the map.  The map size is 1024 * 2 ^
311          * is->is_tsbsize entries, where each entry is 8 bytes.  The start of
312          * the map can be calculated by (0xffffe000 << (8 + is->is_tsbsize)).
313          */
314         if ((is->is_flags & IOMMU_FIRE) != 0) {
315                 maxtsbsize = IOMMU_TSB512K;
316                 /*
317                  * We enable bypass in order to be able to use a physical
318                  * address for the event queue base.
319                  */
320                 is->is_cr = IOMMUCR_SE | IOMMUCR_CM_C_TLB_TBW | IOMMUCR_BE;
321         } else {
322                 maxtsbsize = IOMMU_TSB128K;
323                 is->is_cr = (tsbsize << IOMMUCR_TSBSZ_SHIFT) | IOMMUCR_DE;
324         }
325         if (tsbsize > maxtsbsize)
326                 panic("%s: unsupported TSB size ", __func__);
327         tsbentries = IOMMU_TSBENTRIES(tsbsize);
328         is->is_cr |= IOMMUCR_EN;
329         is->is_tsbsize = tsbsize;
330         is->is_dvmabase = iovabase;
331         if (iovabase == -1)
332                 is->is_dvmabase = IOTSB_VSTART(is->is_tsbsize);
333
334         size = IOTSB_BASESZ << is->is_tsbsize;
335         printf("%s: DVMA map: %#lx to %#lx %d entries%s\n", name,
336             is->is_dvmabase, is->is_dvmabase +
337             (size << (IO_PAGE_SHIFT - IOTTE_SHIFT)) - 1, tsbentries,
338             IOMMU_HAS_SB(is) ? ", streaming buffer" : "");
339
340         /*
341          * Set up resource mamangement.
342          */
343         mtx_init(&is->is_mtx, "iommu", NULL, MTX_DEF);
344         end = is->is_dvmabase + (size << (IO_PAGE_SHIFT - IOTTE_SHIFT));
345         is->is_dvma_rman.rm_type = RMAN_ARRAY;
346         is->is_dvma_rman.rm_descr = "DVMA Memory";
347         if (rman_init(&is->is_dvma_rman) != 0 ||
348             rman_manage_region(&is->is_dvma_rman,
349             (is->is_dvmabase >> IO_PAGE_SHIFT) + resvpg,
350             (end >> IO_PAGE_SHIFT) - 1) != 0)
351                 panic("%s: could not initialize DVMA rman", __func__);
352         TAILQ_INIT(&is->is_maplruq);
353
354         /*
355          * Allocate memory for I/O page tables.  They need to be
356          * physically contiguous.
357          */
358         is->is_tsb = contigmalloc(size, M_DEVBUF, M_NOWAIT, 0, ~0UL,
359             PAGE_SIZE, 0);
360         if (is->is_tsb == NULL)
361                 panic("%s: contigmalloc failed", __func__);
362         is->is_ptsb = pmap_kextract((vm_offset_t)is->is_tsb);
363         bzero(is->is_tsb, size);
364
365         /*
366          * Add the PROM mappings to the kernel IOTSB if desired.
367          * Note that the firmware of certain Darwin boards doesn't set
368          * the TSB size correctly.
369          */
370         if ((is->is_flags & IOMMU_FIRE) != 0)
371                 obptsbsize = (IOMMU_READ8(is, is_iommu, IMR_TSB) &
372                     IOMMUTB_TSBSZ_MASK) >> IOMMUTB_TSBSZ_SHIFT;
373         else
374                 obptsbsize = (IOMMU_READ8(is, is_iommu, IMR_CTL) &
375                     IOMMUCR_TSBSZ_MASK) >> IOMMUCR_TSBSZ_SHIFT;
376         obptsbentries = IOMMU_TSBENTRIES(obptsbsize);
377         if (bootverbose)
378                 printf("%s: PROM IOTSB size: %d (%d entries)\n", name,
379                     obptsbsize, obptsbentries);
380         if ((is->is_flags & IOMMU_PRESERVE_PROM) != 0 &&
381             !(PCPU_GET(impl) == CPU_IMPL_ULTRASPARCIIi && obptsbsize == 7)) {
382                 if (obptsbentries > tsbentries)
383                         panic("%s: PROM IOTSB entries exceed kernel",
384                             __func__);
385                 obpptsb = IOMMU_READ8(is, is_iommu, IMR_TSB) &
386                     IOMMUTB_TB_MASK;
387                 for (i = 0; i < obptsbentries; i++) {
388                         tte = ldxa(obpptsb + i * 8, ASI_PHYS_USE_EC);
389                         if ((tte & IOTTE_V) == 0)
390                                 continue;
391                         slot = tsbentries - obptsbentries + i;
392                         if (bootverbose)
393                                 printf("%s: adding PROM IOTSB slot %d "
394                                     "(kernel slot %d) TTE: %#lx\n", name,
395                                     i, slot, tte);
396                         obpmap = (is->is_dvmabase + slot * IO_PAGE_SIZE) >>
397                             IO_PAGE_SHIFT;
398                         if (rman_reserve_resource(&is->is_dvma_rman, obpmap,
399                             obpmap, IO_PAGE_SIZE >> IO_PAGE_SHIFT, RF_ACTIVE,
400                             NULL) == NULL)
401                                 panic("%s: could not reserve PROM IOTSB slot "
402                                     "%d (kernel slot %d)", __func__, i, slot);
403                         is->is_tsb[slot] = tte;
404                 }
405         }
406
407         /*
408          * Initialize streaming buffer, if it is there.
409          */
410         if (IOMMU_HAS_SB(is)) {
411                 /*
412                  * Find two 64-byte blocks in is_flush that are aligned on
413                  * a 64-byte boundary for flushing.
414                  */
415                 offs = roundup2((vm_offset_t)is->is_flush,
416                     STRBUF_FLUSHSYNC_NBYTES);
417                 for (i = 0; i < 2; i++, offs += STRBUF_FLUSHSYNC_NBYTES) {
418                         is->is_flushva[i] = (uint64_t *)offs;
419                         is->is_flushpa[i] = pmap_kextract(offs);
420                 }
421         }
422
423         /*
424          * Now actually start up the IOMMU.
425          */
426         iommu_reset(is);
427 }
428
429 /*
430  * Streaming buffers don't exist on the UltraSPARC IIi; we should have
431  * detected that already and disabled them.  If not, we will notice that
432  * they aren't there when the STRBUF_EN bit does not remain.
433  */
434 void
435 iommu_reset(struct iommu_state *is)
436 {
437         uint64_t tsb;
438         int i;
439
440         tsb = is->is_ptsb;
441         if ((is->is_flags & IOMMU_FIRE) != 0) {
442                 tsb |= is->is_tsbsize;
443                 IOMMU_WRITE8(is, is_iommu, IMR_CACHE_INVAL, ~0ULL);
444         }
445         IOMMU_WRITE8(is, is_iommu, IMR_TSB, tsb);
446         IOMMU_WRITE8(is, is_iommu, IMR_CTL, is->is_cr);
447
448         for (i = 0; i < 2; i++) {
449                 if (is->is_sb[i] != 0) {
450                         IOMMU_WRITE8(is, is_sb[i], ISR_CTL, STRBUF_EN |
451                             ((is->is_flags & IOMMU_RERUN_DISABLE) != 0 ?
452                             STRBUF_RR_DIS : 0));
453
454                         /* No streaming buffers?  Disable them. */
455                         if ((IOMMU_READ8(is, is_sb[i], ISR_CTL) &
456                             STRBUF_EN) == 0)
457                                 is->is_sb[i] = 0;
458                 }
459         }
460
461         (void)IOMMU_READ8(is, is_iommu, IMR_CTL);
462 }
463
464 /*
465  * Enter a mapping into the TSB.  No locking required, since each TSB slot is
466  * uniquely assigned to a single map.
467  */
468 static void
469 iommu_enter(struct iommu_state *is, vm_offset_t va, vm_paddr_t pa,
470     int stream, int flags)
471 {
472         uint64_t tte;
473
474         KASSERT(va >= is->is_dvmabase,
475             ("%s: va %#lx not in DVMA space", __func__, va));
476         KASSERT(pa <= is->is_pmaxaddr,
477             ("%s: XXX: physical address too large (%#lx)", __func__, pa));
478
479         tte = MAKEIOTTE(pa, !(flags & BUS_DMA_NOWRITE),
480             !(flags & BUS_DMA_NOCACHE), stream);
481
482         IOMMU_SET_TTE(is, va, tte);
483         iommu_tlb_flush(is, va);
484 #ifdef IOMMU_DIAG
485         IS_LOCK(is);
486         iommu_diag(is, va);
487         IS_UNLOCK(is);
488 #endif
489 }
490
491 /*
492  * Remove mappings created by iommu_enter().  Flush the streaming buffer,
493  * but do not synchronize it.  Returns whether a streaming buffer flush
494  * was performed.
495  */
496 static int
497 iommu_remove(struct iommu_state *is, vm_offset_t va, vm_size_t len)
498 {
499         int slot, streamed = 0;
500
501 #ifdef IOMMU_DIAG
502         iommu_diag(is, va);
503 #endif
504
505         KASSERT(va >= is->is_dvmabase,
506             ("%s: va 0x%lx not in DVMA space", __func__, (u_long)va));
507         KASSERT(va + len >= va,
508             ("%s: va 0x%lx + len 0x%lx wraps", __func__, (long)va, (long)len));
509
510         va = trunc_io_page(va);
511         while (len > 0) {
512                 if ((IOMMU_GET_TTE(is, va) & IOTTE_STREAM) != 0) {
513                         streamed = 1;
514                         iommu_strbuf_flush(is, va);
515                 }
516                 len -= ulmin(len, IO_PAGE_SIZE);
517                 IOMMU_SET_TTE(is, va, 0);
518                 iommu_tlb_flush(is, va);
519                 if ((is->is_flags & IOMMU_FLUSH_CACHE) != 0) {
520                         slot = IOTSBSLOT(va);
521                         if (len <= IO_PAGE_SIZE || slot % 8 == 7)
522                                 IOMMU_WRITE8(is, is_iommu, IMR_CACHE_FLUSH,
523                                     is->is_ptsb + slot * 8);
524                 }
525                 va += IO_PAGE_SIZE;
526         }
527         return (streamed);
528 }
529
530 /* Decode an IOMMU fault for host bridge error handlers. */
531 void
532 iommu_decode_fault(struct iommu_state *is, vm_offset_t phys)
533 {
534         bus_addr_t va;
535         long idx;
536
537         idx = phys - is->is_ptsb;
538         if (phys < is->is_ptsb ||
539             idx > (PAGE_SIZE << is->is_tsbsize))
540                 return;
541         va = is->is_dvmabase +
542             (((bus_addr_t)idx >> IOTTE_SHIFT) << IO_PAGE_SHIFT);
543         printf("IOMMU fault virtual address %#lx\n", (u_long)va);
544 }
545
546 /*
547  * A barrier operation which makes sure that all previous streaming buffer
548  * flushes complete before it returns.
549  */
550 static int
551 iommu_strbuf_flush_sync(struct iommu_state *is)
552 {
553         struct timeval cur, end;
554         int i;
555
556         IS_LOCK_ASSERT(is);
557         if (!IOMMU_HAS_SB(is))
558                 return (0);
559
560         /*
561          * Streaming buffer flushes:
562          *
563          *   1 Tell strbuf to flush by storing va to strbuf_pgflush.  If
564          *     we're not on a cache line boundary (64-bits):
565          *   2 Store 0 in flag
566          *   3 Store pointer to flag in flushsync
567          *   4 wait till flushsync becomes 0x1
568          *
569          * If it takes more than .5 sec, something went wrong.
570          */
571         *is->is_flushva[0] = 1;
572         *is->is_flushva[1] = 1;
573         membar(StoreStore);
574         for (i = 0; i < 2; i++) {
575                 if (is->is_sb[i] != 0) {
576                         *is->is_flushva[i] = 0;
577                         IOMMU_WRITE8(is, is_sb[i], ISR_FLUSHSYNC,
578                             is->is_flushpa[i]);
579                 }
580         }
581
582         microuptime(&cur);
583         end.tv_sec = 0;
584         /*
585          * 0.5s is the recommended timeout from the U2S manual.  The actual
586          * time required should be smaller by at least a factor of 1000.
587          * We have no choice but to busy-wait.
588          */
589         end.tv_usec = 500000;
590         timevaladd(&end, &cur);
591
592         while ((!*is->is_flushva[0] || !*is->is_flushva[1]) &&
593             timevalcmp(&cur, &end, <=))
594                 microuptime(&cur);
595
596         if (!*is->is_flushva[0] || !*is->is_flushva[1]) {
597                 panic("%s: flush timeout %ld, %ld at %#lx", __func__,
598                     *is->is_flushva[0], *is->is_flushva[1], is->is_flushpa[0]);
599         }
600
601         return (1);
602 }
603
604 /* Determine whether we may enable streaming on a mapping. */
605 static __inline int
606 iommu_use_streaming(struct iommu_state *is, bus_dmamap_t map, bus_size_t size)
607 {
608
609         /*
610          * This cannot be enabled yet, as many driver are still missing
611          * bus_dmamap_sync() calls.  As soon as there is a BUS_DMA_STREAMING
612          * flag, this should be reenabled conditionally on it.
613          */
614 #ifdef notyet
615         return (size >= IOMMU_STREAM_THRESH && IOMMU_HAS_SB(is) &&
616             (map->dm_flags & DMF_COHERENT) == 0);
617 #else
618         return (0);
619 #endif
620 }
621
622 /*
623  * Allocate DVMA virtual memory for a map.  The map may not be on a queue,
624  * so that it can be freely modified.
625  */
626 static int
627 iommu_dvma_valloc(bus_dma_tag_t t, struct iommu_state *is, bus_dmamap_t map,
628     bus_size_t size)
629 {
630         struct resource *res;
631         struct bus_dmamap_res *bdr;
632         bus_size_t align, sgsize;
633
634         KASSERT(!map->dm_onq, ("%s: map on queue!", __func__));
635         if ((bdr = malloc(sizeof(*bdr), M_IOMMU, M_NOWAIT)) == NULL)
636                 return (EAGAIN);
637         /*
638          * If a boundary is specified, a map cannot be larger than it; however
639          * we do not clip currently, as that does not play well with the lazy
640          * allocation code.
641          * Alignment to a page boundary is always enforced.
642          */
643         align = (t->dt_alignment + IO_PAGE_MASK) >> IO_PAGE_SHIFT;
644         sgsize = round_io_page(size) >> IO_PAGE_SHIFT;
645         if (t->dt_boundary > 0 && t->dt_boundary < IO_PAGE_SIZE)
646                 panic("%s: illegal boundary specified", __func__);
647         res = rman_reserve_resource_bound(&is->is_dvma_rman, 0L,
648             t->dt_lowaddr >> IO_PAGE_SHIFT, sgsize,
649             t->dt_boundary >> IO_PAGE_SHIFT,
650             RF_ACTIVE | rman_make_alignment_flags(align), NULL);
651         if (res == NULL) {
652                 free(bdr, M_IOMMU);
653                 return (ENOMEM);
654         }
655
656         bdr->dr_res = res;
657         bdr->dr_used = 0;
658         SLIST_INSERT_HEAD(&map->dm_reslist, bdr, dr_link);
659         return (0);
660 }
661
662 /* Unload the map and mark all resources as unused, but do not free them. */
663 static void
664 iommu_dvmamap_vunload(struct iommu_state *is, bus_dmamap_t map)
665 {
666         struct bus_dmamap_res *r;
667         int streamed = 0;
668
669         IS_LOCK_ASSERT(is);     /* for iommu_strbuf_sync() below */
670         SLIST_FOREACH(r, &map->dm_reslist, dr_link) {
671                 streamed |= iommu_remove(is, BDR_START(r), r->dr_used);
672                 r->dr_used = 0;
673         }
674         if (streamed)
675                 iommu_strbuf_sync(is);
676 }
677
678 /* Free a DVMA virtual memory resource. */
679 static __inline void
680 iommu_dvma_vfree_res(bus_dmamap_t map, struct bus_dmamap_res *r)
681 {
682
683         KASSERT(r->dr_used == 0, ("%s: resource busy!", __func__));
684         if (r->dr_res != NULL && rman_release_resource(r->dr_res) != 0)
685                 printf("warning: DVMA space lost\n");
686         SLIST_REMOVE(&map->dm_reslist, r, bus_dmamap_res, dr_link);
687         free(r, M_IOMMU);
688 }
689
690 /* Free all DVMA virtual memory for a map. */
691 static void
692 iommu_dvma_vfree(struct iommu_state *is, bus_dmamap_t map)
693 {
694
695         IS_LOCK(is);
696         iommu_map_remq(is, map);
697         iommu_dvmamap_vunload(is, map);
698         IS_UNLOCK(is);
699         while (!SLIST_EMPTY(&map->dm_reslist))
700                 iommu_dvma_vfree_res(map, SLIST_FIRST(&map->dm_reslist));
701 }
702
703 /* Prune a map, freeing all unused DVMA resources. */
704 static bus_size_t
705 iommu_dvma_vprune(struct iommu_state *is, bus_dmamap_t map)
706 {
707         struct bus_dmamap_res *r, *n;
708         bus_size_t freed = 0;
709
710         IS_LOCK_ASSERT(is);
711         for (r = SLIST_FIRST(&map->dm_reslist); r != NULL; r = n) {
712                 n = SLIST_NEXT(r, dr_link);
713                 if (r->dr_used == 0) {
714                         freed += BDR_SIZE(r);
715                         iommu_dvma_vfree_res(map, r);
716                 }
717         }
718         if (SLIST_EMPTY(&map->dm_reslist))
719                 iommu_map_remq(is, map);
720         return (freed);
721 }
722
723 /*
724  * Try to find a suitably-sized (and if requested, -aligned) slab of DVMA
725  * memory with IO page offset voffs.
726  */
727 static bus_addr_t
728 iommu_dvma_vfindseg(bus_dmamap_t map, vm_offset_t voffs, bus_size_t size,
729     bus_addr_t amask)
730 {
731         struct bus_dmamap_res *r;
732         bus_addr_t dvmaddr, dvmend;
733
734         KASSERT(!map->dm_onq, ("%s: map on queue!", __func__));
735         SLIST_FOREACH(r, &map->dm_reslist, dr_link) {
736                 dvmaddr = round_io_page(BDR_START(r) + r->dr_used);
737                 /* Alignment can only work with voffs == 0. */
738                 dvmaddr = (dvmaddr + amask) & ~amask;
739                 dvmaddr += voffs;
740                 dvmend = dvmaddr + size;
741                 if (dvmend <= BDR_END(r)) {
742                         r->dr_used = dvmend - BDR_START(r);
743                         return (dvmaddr);
744                 }
745         }
746         return (0);
747 }
748
749 /*
750  * Try to find or allocate a slab of DVMA space; see above.
751  */
752 static int
753 iommu_dvma_vallocseg(bus_dma_tag_t dt, struct iommu_state *is, bus_dmamap_t map,
754     vm_offset_t voffs, bus_size_t size, bus_addr_t amask, bus_addr_t *addr)
755 {
756         bus_dmamap_t tm, last;
757         bus_addr_t dvmaddr, freed;
758         int error, complete = 0;
759
760         dvmaddr = iommu_dvma_vfindseg(map, voffs, size, amask);
761
762         /* Need to allocate. */
763         if (dvmaddr == 0) {
764                 while ((error = iommu_dvma_valloc(dt, is, map,
765                         voffs + size)) == ENOMEM && !complete) {
766                         /*
767                          * Free the allocated DVMA of a few maps until
768                          * the required size is reached. This is an
769                          * approximation to not have to call the allocation
770                          * function too often; most likely one free run
771                          * will not suffice if not one map was large enough
772                          * itself due to fragmentation.
773                          */
774                         IS_LOCK(is);
775                         freed = 0;
776                         last = TAILQ_LAST(&is->is_maplruq, iommu_maplruq_head);
777                         do {
778                                 tm = TAILQ_FIRST(&is->is_maplruq);
779                                 complete = tm == last;
780                                 if (tm == NULL)
781                                         break;
782                                 freed += iommu_dvma_vprune(is, tm);
783                                 /* Move to the end. */
784                                 iommu_map_insq(is, tm);
785                         } while (freed < size && !complete);
786                         IS_UNLOCK(is);
787                 }
788                 if (error != 0)
789                         return (error);
790                 dvmaddr = iommu_dvma_vfindseg(map, voffs, size, amask);
791                 KASSERT(dvmaddr != 0, ("%s: allocation failed unexpectedly!",
792                     __func__));
793         }
794         *addr = dvmaddr;
795         return (0);
796 }
797
798 static int
799 iommu_dvmamem_alloc(bus_dma_tag_t dt, void **vaddr, int flags,
800     bus_dmamap_t *mapp)
801 {
802         struct iommu_state *is = dt->dt_cookie;
803         int error, mflags;
804
805         /*
806          * XXX: This will break for 32 bit transfers on machines with more
807          * than is->is_pmaxaddr memory.
808          */
809         if ((error = sparc64_dma_alloc_map(dt, mapp)) != 0)
810                 return (error);
811
812         if ((flags & BUS_DMA_NOWAIT) != 0)
813                 mflags = M_NOWAIT;
814         else
815                 mflags = M_WAITOK;
816         if ((flags & BUS_DMA_ZERO) != 0)
817                 mflags |= M_ZERO;
818
819         if ((*vaddr = malloc(dt->dt_maxsize, M_IOMMU, mflags)) == NULL) {
820                 error = ENOMEM;
821                 sparc64_dma_free_map(dt, *mapp);
822                 return (error);
823         }
824         if ((flags & BUS_DMA_COHERENT) != 0)
825                 (*mapp)->dm_flags |= DMF_COHERENT;
826         /*
827          * Try to preallocate DVMA space.  If this fails, it is retried at
828          * load time.
829          */
830         iommu_dvma_valloc(dt, is, *mapp, IOMMU_SIZE_ROUNDUP(dt->dt_maxsize));
831         IS_LOCK(is);
832         iommu_map_insq(is, *mapp);
833         IS_UNLOCK(is);
834         return (0);
835 }
836
837 static void
838 iommu_dvmamem_free(bus_dma_tag_t dt, void *vaddr, bus_dmamap_t map)
839 {
840         struct iommu_state *is = dt->dt_cookie;
841
842         iommu_dvma_vfree(is, map);
843         sparc64_dma_free_map(dt, map);
844         free(vaddr, M_IOMMU);
845 }
846
847 static int
848 iommu_dvmamap_create(bus_dma_tag_t dt, int flags, bus_dmamap_t *mapp)
849 {
850         struct iommu_state *is = dt->dt_cookie;
851         bus_size_t totsz, presz, currsz;
852         int error, i, maxpre;
853
854         if ((error = sparc64_dma_alloc_map(dt, mapp)) != 0)
855                 return (error);
856         if ((flags & BUS_DMA_COHERENT) != 0)
857                 (*mapp)->dm_flags |= DMF_COHERENT;
858         /*
859          * Preallocate DVMA space; if this fails now, it is retried at load
860          * time.  Through bus_dmamap_load_mbuf() and bus_dmamap_load_uio(),
861          * it is possible to have multiple discontiguous segments in a single
862          * map, which is handled by allocating additional resources, instead
863          * of increasing the size, to avoid fragmentation.
864          * Clamp preallocation to IOMMU_MAX_PRE.  In some situations we can
865          * handle more; that case is handled by reallocating at map load time.
866          */
867         totsz = ulmin(IOMMU_SIZE_ROUNDUP(dt->dt_maxsize), IOMMU_MAX_PRE);
868         error = iommu_dvma_valloc(dt, is, *mapp, totsz);
869         if (error != 0)
870                 return (0);
871         /*
872          * Try to be smart about preallocating some additional segments if
873          * needed.
874          */
875         maxpre = imin(dt->dt_nsegments, IOMMU_MAX_PRE_SEG);
876         presz = dt->dt_maxsize / maxpre;
877         KASSERT(presz != 0, ("%s: bogus preallocation size , nsegments = %d, "
878             "maxpre = %d, maxsize = %lu", __func__, dt->dt_nsegments, maxpre,
879             dt->dt_maxsize));
880         for (i = 1; i < maxpre && totsz < IOMMU_MAX_PRE; i++) {
881                 currsz = round_io_page(ulmin(presz, IOMMU_MAX_PRE - totsz));
882                 error = iommu_dvma_valloc(dt, is, *mapp, currsz);
883                 if (error != 0)
884                         break;
885                 totsz += currsz;
886         }
887         IS_LOCK(is);
888         iommu_map_insq(is, *mapp);
889         IS_UNLOCK(is);
890         return (0);
891 }
892
893 static int
894 iommu_dvmamap_destroy(bus_dma_tag_t dt, bus_dmamap_t map)
895 {
896         struct iommu_state *is = dt->dt_cookie;
897
898         iommu_dvma_vfree(is, map);
899         sparc64_dma_free_map(dt, map);
900         return (0);
901 }
902
903 /*
904  * IOMMU DVMA operations, common to PCI and SBus
905  */
906 static int
907 iommu_dvmamap_load_buffer(bus_dma_tag_t dt, struct iommu_state *is,
908     bus_dmamap_t map, void *buf, bus_size_t buflen, struct thread *td,
909     int flags, bus_dma_segment_t *segs, int *segp, int align)
910 {
911         bus_addr_t amask, dvmaddr, dvmoffs;
912         bus_size_t sgsize, esize;
913         vm_offset_t vaddr, voffs;
914         vm_paddr_t curaddr;
915         pmap_t pmap = NULL;
916         int error, firstpg, sgcnt;
917         u_int slot;
918
919         KASSERT(buflen != 0, ("%s: buflen == 0!", __func__));
920         if (buflen > dt->dt_maxsize)
921                 return (EINVAL);
922
923         if (td != NULL)
924                 pmap = vmspace_pmap(td->td_proc->p_vmspace);
925
926         vaddr = (vm_offset_t)buf;
927         voffs = vaddr & IO_PAGE_MASK;
928         amask = align ? dt->dt_alignment - 1 : 0;
929
930         /* Try to find a slab that is large enough. */
931         error = iommu_dvma_vallocseg(dt, is, map, voffs, buflen, amask,
932             &dvmaddr);
933         if (error != 0)
934                 return (error);
935
936         sgcnt = *segp;
937         firstpg = 1;
938         map->dm_flags &= ~DMF_STREAMED;
939         map->dm_flags |= iommu_use_streaming(is, map, buflen) != 0 ?
940             DMF_STREAMED : 0;
941         for (; buflen > 0; ) {
942                 /*
943                  * Get the physical address for this page.
944                  */
945                 if (pmap != NULL)
946                         curaddr = pmap_extract(pmap, vaddr);
947                 else
948                         curaddr = pmap_kextract(vaddr);
949
950                 /*
951                  * Compute the segment size, and adjust counts.
952                  */
953                 sgsize = IO_PAGE_SIZE - ((u_long)vaddr & IO_PAGE_MASK);
954                 if (buflen < sgsize)
955                         sgsize = buflen;
956
957                 buflen -= sgsize;
958                 vaddr += sgsize;
959
960                 dvmoffs = trunc_io_page(dvmaddr);
961                 iommu_enter(is, dvmoffs, trunc_io_page(curaddr),
962                     (map->dm_flags & DMF_STREAMED) != 0, flags);
963                 if ((is->is_flags & IOMMU_FLUSH_CACHE) != 0) {
964                         slot = IOTSBSLOT(dvmoffs);
965                         if (buflen <= 0 || slot % 8 == 7)
966                                 IOMMU_WRITE8(is, is_iommu, IMR_CACHE_FLUSH,
967                                     is->is_ptsb + slot * 8);
968                 }
969
970                 /*
971                  * Chop the chunk up into segments of at most maxsegsz, but try
972                  * to fill each segment as well as possible.
973                  */
974                 if (!firstpg) {
975                         esize = ulmin(sgsize,
976                             dt->dt_maxsegsz - segs[sgcnt].ds_len);
977                         segs[sgcnt].ds_len += esize;
978                         sgsize -= esize;
979                         dvmaddr += esize;
980                 }
981                 while (sgsize > 0) {
982                         sgcnt++;
983                         if (sgcnt >= dt->dt_nsegments)
984                                 return (EFBIG);
985                         /*
986                          * No extra alignment here - the common practice in
987                          * the busdma code seems to be that only the first
988                          * segment needs to satisfy the alignment constraints
989                          * (and that only for bus_dmamem_alloc()ed maps).
990                          * It is assumed that such tags have maxsegsize >=
991                          * maxsize.
992                          */
993                         esize = ulmin(sgsize, dt->dt_maxsegsz);
994                         segs[sgcnt].ds_addr = dvmaddr;
995                         segs[sgcnt].ds_len = esize;
996                         sgsize -= esize;
997                         dvmaddr += esize;
998                 }
999
1000                 firstpg = 0;
1001         }
1002         *segp = sgcnt;
1003         return (0);
1004 }
1005
1006 static int
1007 iommu_dvmamap_load(bus_dma_tag_t dt, bus_dmamap_t map, void *buf,
1008     bus_size_t buflen, bus_dmamap_callback_t *cb, void *cba,
1009     int flags)
1010 {
1011         struct iommu_state *is = dt->dt_cookie;
1012         int error, seg = -1;
1013
1014         if ((map->dm_flags & DMF_LOADED) != 0) {
1015 #ifdef DIAGNOSTIC
1016                 printf("%s: map still in use\n", __func__);
1017 #endif
1018                 bus_dmamap_unload(dt, map);
1019         }
1020
1021         /*
1022          * Make sure that the map is not on a queue so that the resource list
1023          * may be safely accessed and modified without needing the lock to
1024          * cover the whole operation.
1025          */
1026         IS_LOCK(is);
1027         iommu_map_remq(is, map);
1028         IS_UNLOCK(is);
1029
1030         error = iommu_dvmamap_load_buffer(dt, is, map, buf, buflen, NULL,
1031             flags, dt->dt_segments, &seg, 1);
1032
1033         IS_LOCK(is);
1034         iommu_map_insq(is, map);
1035         if (error != 0) {
1036                 iommu_dvmamap_vunload(is, map);
1037                 IS_UNLOCK(is);
1038                 (*cb)(cba, dt->dt_segments, 0, error);
1039         } else {
1040                 IS_UNLOCK(is);
1041                 map->dm_flags |= DMF_LOADED;
1042                 (*cb)(cba, dt->dt_segments, seg + 1, 0);
1043         }
1044
1045         return (error);
1046 }
1047
1048 static int
1049 iommu_dvmamap_load_mbuf(bus_dma_tag_t dt, bus_dmamap_t map, struct mbuf *m0,
1050     bus_dmamap_callback2_t *cb, void *cba, int flags)
1051 {
1052         struct iommu_state *is = dt->dt_cookie;
1053         struct mbuf *m;
1054         int error = 0, first = 1, nsegs = -1;
1055
1056         M_ASSERTPKTHDR(m0);
1057
1058         if ((map->dm_flags & DMF_LOADED) != 0) {
1059 #ifdef DIAGNOSTIC
1060                 printf("%s: map still in use\n", __func__);
1061 #endif
1062                 bus_dmamap_unload(dt, map);
1063         }
1064
1065         IS_LOCK(is);
1066         iommu_map_remq(is, map);
1067         IS_UNLOCK(is);
1068
1069         if (m0->m_pkthdr.len <= dt->dt_maxsize) {
1070                 for (m = m0; m != NULL && error == 0; m = m->m_next) {
1071                         if (m->m_len == 0)
1072                                 continue;
1073                         error = iommu_dvmamap_load_buffer(dt, is, map,
1074                             m->m_data, m->m_len, NULL, flags, dt->dt_segments,
1075                             &nsegs, first);
1076                         first = 0;
1077                 }
1078         } else
1079                 error = EINVAL;
1080
1081         IS_LOCK(is);
1082         iommu_map_insq(is, map);
1083         if (error != 0) {
1084                 iommu_dvmamap_vunload(is, map);
1085                 IS_UNLOCK(is);
1086                 /* force "no valid mappings" in callback */
1087                 (*cb)(cba, dt->dt_segments, 0, 0, error);
1088         } else {
1089                 IS_UNLOCK(is);
1090                 map->dm_flags |= DMF_LOADED;
1091                 (*cb)(cba, dt->dt_segments, nsegs + 1, m0->m_pkthdr.len, 0);
1092         }
1093         return (error);
1094 }
1095
1096 static int
1097 iommu_dvmamap_load_mbuf_sg(bus_dma_tag_t dt, bus_dmamap_t map, struct mbuf *m0,
1098     bus_dma_segment_t *segs, int *nsegs, int flags)
1099 {
1100         struct iommu_state *is = dt->dt_cookie;
1101         struct mbuf *m;
1102         int error = 0, first = 1;
1103
1104         M_ASSERTPKTHDR(m0);
1105
1106         *nsegs = -1;
1107         if ((map->dm_flags & DMF_LOADED) != 0) {
1108 #ifdef DIAGNOSTIC
1109                 printf("%s: map still in use\n", __func__);
1110 #endif
1111                 bus_dmamap_unload(dt, map);
1112         }
1113
1114         IS_LOCK(is);
1115         iommu_map_remq(is, map);
1116         IS_UNLOCK(is);
1117
1118         if (m0->m_pkthdr.len <= dt->dt_maxsize) {
1119                 for (m = m0; m != NULL && error == 0; m = m->m_next) {
1120                         if (m->m_len == 0)
1121                                 continue;
1122                         error = iommu_dvmamap_load_buffer(dt, is, map,
1123                             m->m_data, m->m_len, NULL, flags, segs,
1124                             nsegs, first);
1125                         first = 0;
1126                 }
1127         } else
1128                 error = EINVAL;
1129
1130         IS_LOCK(is);
1131         iommu_map_insq(is, map);
1132         if (error != 0) {
1133                 iommu_dvmamap_vunload(is, map);
1134                 IS_UNLOCK(is);
1135         } else {
1136                 IS_UNLOCK(is);
1137                 map->dm_flags |= DMF_LOADED;
1138                 ++*nsegs;
1139         }
1140         return (error);
1141 }
1142
1143 static int
1144 iommu_dvmamap_load_uio(bus_dma_tag_t dt, bus_dmamap_t map, struct uio *uio,
1145     bus_dmamap_callback2_t *cb,  void *cba, int flags)
1146 {
1147         struct iommu_state *is = dt->dt_cookie;
1148         struct iovec *iov;
1149         struct thread *td = NULL;
1150         bus_size_t minlen, resid;
1151         int nsegs = -1, error = 0, first = 1, i;
1152
1153         if ((map->dm_flags & DMF_LOADED) != 0) {
1154 #ifdef DIAGNOSTIC
1155                 printf("%s: map still in use\n", __func__);
1156 #endif
1157                 bus_dmamap_unload(dt, map);
1158         }
1159
1160         IS_LOCK(is);
1161         iommu_map_remq(is, map);
1162         IS_UNLOCK(is);
1163
1164         resid = uio->uio_resid;
1165         iov = uio->uio_iov;
1166
1167         if (uio->uio_segflg == UIO_USERSPACE) {
1168                 td = uio->uio_td;
1169                 KASSERT(td != NULL,
1170                     ("%s: USERSPACE but no proc", __func__));
1171         }
1172
1173         for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) {
1174                 /*
1175                  * Now at the first iovec to load.  Load each iovec
1176                  * until we have exhausted the residual count.
1177                  */
1178                 minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len;
1179                 if (minlen == 0)
1180                         continue;
1181
1182                 error = iommu_dvmamap_load_buffer(dt, is, map,
1183                     iov[i].iov_base, minlen, td, flags, dt->dt_segments,
1184                     &nsegs, first);
1185                 first = 0;
1186
1187                 resid -= minlen;
1188         }
1189
1190         IS_LOCK(is);
1191         iommu_map_insq(is, map);
1192         if (error) {
1193                 iommu_dvmamap_vunload(is, map);
1194                 IS_UNLOCK(is);
1195                 /* force "no valid mappings" in callback */
1196                 (*cb)(cba, dt->dt_segments, 0, 0, error);
1197         } else {
1198                 IS_UNLOCK(is);
1199                 map->dm_flags |= DMF_LOADED;
1200                 (*cb)(cba, dt->dt_segments, nsegs + 1, uio->uio_resid, 0);
1201         }
1202         return (error);
1203 }
1204
1205 static void
1206 iommu_dvmamap_unload(bus_dma_tag_t dt, bus_dmamap_t map)
1207 {
1208         struct iommu_state *is = dt->dt_cookie;
1209
1210         if ((map->dm_flags & DMF_LOADED) == 0)
1211                 return;
1212         IS_LOCK(is);
1213         iommu_dvmamap_vunload(is, map);
1214         iommu_map_insq(is, map);
1215         IS_UNLOCK(is);
1216         map->dm_flags &= ~DMF_LOADED;
1217 }
1218
1219 static void
1220 iommu_dvmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
1221 {
1222         struct iommu_state *is = dt->dt_cookie;
1223         struct bus_dmamap_res *r;
1224         vm_offset_t va;
1225         vm_size_t len;
1226         int streamed = 0;
1227
1228         if ((map->dm_flags & DMF_LOADED) == 0)
1229                 return;
1230         /* XXX This is probably bogus. */
1231         if ((op & BUS_DMASYNC_PREREAD) != 0)
1232                 membar(Sync);
1233         if ((map->dm_flags & DMF_STREAMED) != 0 &&
1234             ((op & BUS_DMASYNC_POSTREAD) != 0 ||
1235             (op & BUS_DMASYNC_PREWRITE) != 0)) {
1236                 IS_LOCK(is);
1237                 SLIST_FOREACH(r, &map->dm_reslist, dr_link) {
1238                         va = (vm_offset_t)BDR_START(r);
1239                         len = r->dr_used;
1240                         /*
1241                          * If we have a streaming buffer, flush it here
1242                          * first.
1243                          */
1244                         while (len > 0) {
1245                                 if ((IOMMU_GET_TTE(is, va) &
1246                                     IOTTE_STREAM) != 0) {
1247                                         streamed = 1;
1248                                         iommu_strbuf_flush(is, va);
1249                                 }
1250                                 len -= ulmin(len, IO_PAGE_SIZE);
1251                                 va += IO_PAGE_SIZE;
1252                         }
1253                 }
1254                 if (streamed)
1255                         iommu_strbuf_sync(is);
1256                 IS_UNLOCK(is);
1257         }
1258         if ((op & BUS_DMASYNC_PREWRITE) != 0)
1259                 membar(Sync);
1260 }
1261
1262 #ifdef IOMMU_DIAG
1263
1264 /*
1265  * Perform an IOMMU diagnostic access and print the tag belonging to va.
1266  */
1267 static void
1268 iommu_diag(struct iommu_state *is, vm_offset_t va)
1269 {
1270         int i;
1271         uint64_t data, tag;
1272
1273         if ((is->is_flags & IOMMU_FIRE) != 0)
1274                 return;
1275         IS_LOCK_ASSERT(is);
1276         IOMMU_WRITE8(is, is_dva, 0, trunc_io_page(va));
1277         membar(StoreStore | StoreLoad);
1278         printf("%s: tte entry %#lx", __func__, IOMMU_GET_TTE(is, va));
1279         if (is->is_dtcmp != 0) {
1280                 printf(", tag compare register is %#lx\n",
1281                     IOMMU_READ8(is, is_dtcmp, 0));
1282         } else
1283                 printf("\n");
1284         for (i = 0; i < 16; i++) {
1285                 tag = IOMMU_READ8(is, is_dtag, i * 8);
1286                 data = IOMMU_READ8(is, is_ddram, i * 8);
1287                 printf("%s: tag %d: %#lx, vpn %#lx, err %lx; "
1288                     "data %#lx, pa %#lx, v %d, c %d\n", __func__, i,
1289                     tag, (tag & IOMMU_DTAG_VPNMASK) << IOMMU_DTAG_VPNSHIFT,
1290                     (tag & IOMMU_DTAG_ERRMASK) >> IOMMU_DTAG_ERRSHIFT, data,
1291                     (data & IOMMU_DDATA_PGMASK) << IOMMU_DDATA_PGSHIFT,
1292                     (data & IOMMU_DDATA_V) != 0, (data & IOMMU_DDATA_C) != 0);
1293         }
1294 }
1295
1296 #endif /* IOMMU_DIAG */
1297
1298 struct bus_dma_methods iommu_dma_methods = {
1299         iommu_dvmamap_create,
1300         iommu_dvmamap_destroy,
1301         iommu_dvmamap_load,
1302         iommu_dvmamap_load_mbuf,
1303         iommu_dvmamap_load_mbuf_sg,
1304         iommu_dvmamap_load_uio,
1305         iommu_dvmamap_unload,
1306         iommu_dvmamap_sync,
1307         iommu_dvmamem_alloc,
1308         iommu_dvmamem_free,
1309 };