]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/sparc64/sparc64/iommu.c
merge fix for boot-time hang on centos' xen
[FreeBSD/FreeBSD.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  * Currently, the IOTSBs are synchronized, because determining the bus the map
107  * is to be loaded for is not possible with the current busdma code.
108  * The code is structured so that the IOMMUs can be easily divorced when that
109  * is fixed.
110  *
111  * TODO:
112  * - As soon as there is a newbus way to get a parent dma tag, divorce the
113  *   IOTSBs.
114  * - Support sub-page boundaries.
115  * - Fix alignment handling for small allocations (the possible page offset
116  *   of malloc()ed memory is not handled at all).  Revise interaction of
117  *   alignment with the load_mbuf and load_uio functions.
118  * - Handle lowaddr and highaddr in some way, and try to work out a way
119  *   for filter callbacks to work.  Currently, only lowaddr is honored
120  *   in that no addresses above it are considered at all.
121  * - Implement BUS_DMA_ALLOCNOW in bus_dma_tag_create as far as possible.
122  * - Check the possible return values and callback error arguments;
123  *   the callback currently gets called in error conditions where it should
124  *   not be.
125  * - When running out of DVMA space, return EINPROGRESS in the non-
126  *   BUS_DMA_NOWAIT case and delay the callback until sufficient space
127  *   becomes available.
128  * - Use the streaming cache unless BUS_DMA_COHERENT is specified; do not
129  *   flush the streaming cache when coherent mappings are synced.
130  * - Add bounce buffers to support machines with more than 16GB of RAM.
131  */
132
133 #include "opt_iommu.h"
134
135 #include <sys/param.h>
136 #include <sys/kernel.h>
137 #include <sys/lock.h>
138 #include <sys/malloc.h>
139 #include <sys/mbuf.h>
140 #include <sys/mutex.h>
141 #include <sys/proc.h>
142 #include <sys/systm.h>
143 #include <sys/uio.h>
144
145 #include <vm/vm.h>
146 #include <vm/pmap.h>
147 #include <vm/vm_map.h>
148
149 #include <machine/bus.h>
150 #include <machine/bus_private.h>
151 #include <machine/iommureg.h>
152 #include <machine/pmap.h>
153 #include <machine/resource.h>
154
155 #include <sys/rman.h>
156
157 #include <machine/iommuvar.h>
158
159 /*
160  * Tuning constants.
161  */
162 #define IOMMU_MAX_PRE           (32 * 1024)
163 #define IOMMU_MAX_PRE_SEG       3
164
165 /* Threshold for using the streaming buffer. */
166 #define IOMMU_STREAM_THRESH     128
167
168 MALLOC_DEFINE(M_IOMMU, "dvmamem", "IOMMU DVMA Buffers");
169
170 static  int iommu_strbuf_flush_sync(struct iommu_state *);
171 #ifdef IOMMU_DIAG
172 static  void iommu_diag(struct iommu_state *, vm_offset_t va);
173 #endif
174
175 /*
176  * Protects iommu_maplruq, dm_reslist of all maps on the queue and all
177  * iommu states as long as the TSBs are synchronized.
178  */
179 struct mtx iommu_mtx;
180
181 /*
182  * The following 4 variables need to be moved to the per-IOMMU state once
183  * the IOTSBs are divorced.
184  * LRU queue handling for lazy resource allocation.
185  */
186 static TAILQ_HEAD(iommu_maplruq_head, bus_dmamap) iommu_maplruq =
187    TAILQ_HEAD_INITIALIZER(iommu_maplruq);
188
189 /* DVMA space rman. */
190 static struct rman iommu_dvma_rman;
191
192 /* Virtual and physical address of the TSB. */
193 static uint64_t *iommu_tsb;
194 static vm_offset_t iommu_ptsb;
195
196 /* List of all IOMMUs. */
197 static STAILQ_HEAD(, iommu_state) iommu_insts =
198    STAILQ_HEAD_INITIALIZER(iommu_insts);
199
200 /*
201  * Helpers. Some of these take unused iommu states as parameters, to ease the
202  * transition to divorced TSBs.
203  */
204 #define IOMMU_READ8(is, reg, off)                                       \
205         bus_space_read_8((is)->is_bustag, (is)->is_bushandle,           \
206             (is)->reg + (off))
207 #define IOMMU_WRITE8(is, reg, off, v)                                   \
208         bus_space_write_8((is)->is_bustag, (is)->is_bushandle,          \
209             (is)->reg + (off), (v))
210
211 #define IOMMU_HAS_SB(is)                                                \
212         ((is)->is_sb[0] != 0 || (is)->is_sb[1] != 0)
213
214 /*
215  * Always overallocate one page; this is needed to handle alignment of the
216  * buffer, so it makes sense using a lazy allocation scheme.
217  */
218 #define IOMMU_SIZE_ROUNDUP(sz)                                          \
219         (round_io_page(sz) + IO_PAGE_SIZE)
220
221 #define IOMMU_SET_TTE(is, va, tte)                                      \
222         (iommu_tsb[IOTSBSLOT(va)] = (tte))
223 #define IOMMU_GET_TTE(is, va)                                           \
224         iommu_tsb[IOTSBSLOT(va)]
225
226 /* Resource helpers */
227 #define IOMMU_RES_START(res)                                            \
228         ((bus_addr_t)rman_get_start(res) << IO_PAGE_SHIFT)
229 #define IOMMU_RES_END(res)                                              \
230         ((bus_addr_t)(rman_get_end(res) + 1) << IO_PAGE_SHIFT)
231 #define IOMMU_RES_SIZE(res)                                             \
232         ((bus_size_t)rman_get_size(res) << IO_PAGE_SHIFT)
233
234 /* Helpers for struct bus_dmamap_res */
235 #define BDR_START(r)    IOMMU_RES_START((r)->dr_res)
236 #define BDR_END(r)      IOMMU_RES_END((r)->dr_res)
237 #define BDR_SIZE(r)     IOMMU_RES_SIZE((r)->dr_res)
238
239 /* Locking macros. */
240 #define IS_LOCK(is)     mtx_lock(&iommu_mtx)
241 #define IS_LOCK_ASSERT(is)      mtx_assert(&iommu_mtx, MA_OWNED)
242 #define IS_UNLOCK(is)   mtx_unlock(&iommu_mtx)
243
244
245 /* Flush a page from the TLB.  No locking required, since this is atomic. */
246 static __inline void
247 iommu_tlb_flush(struct iommu_state *is, bus_addr_t va)
248 {
249         struct iommu_state *it;
250
251         /*
252          * Since the TSB is shared for now, the TLBs of all IOMMUs
253          * need to be flushed.
254          */
255         STAILQ_FOREACH(it, &iommu_insts, is_link)
256                 IOMMU_WRITE8(it, is_iommu, IMR_FLUSH, va);
257 }
258
259 /*
260  * Flush a page from the streaming buffer.  No locking required, since this
261  * is atomic.
262  */
263 static __inline void
264 iommu_strbuf_flushpg(struct iommu_state *is, bus_addr_t va)
265 {
266         int i;
267
268         for (i = 0; i < 2; i++)
269                 if (is->is_sb[i] != 0)
270                         IOMMU_WRITE8(is, is_sb[i], ISR_PGFLUSH, va);
271 }
272
273 /*
274  * Flush an address from the streaming buffer(s); this is an asynchronous
275  * operation.  To make sure that it has completed, iommu_strbuf_sync() needs
276  * to be called.  No locking required.
277  */
278 static __inline void
279 iommu_strbuf_flush(struct iommu_state *is, bus_addr_t va)
280 {
281         struct iommu_state *it;
282
283         /*
284          * Need to flush the streaming buffers of all IOMMUs, we cannot
285          * determine which one was used for the transaction.
286          */
287         STAILQ_FOREACH(it, &iommu_insts, is_link)
288                 iommu_strbuf_flushpg(it, va);
289 }
290
291 /* Synchronize all outstanding flush operations. */
292 static __inline void
293 iommu_strbuf_sync(struct iommu_state *is)
294 {
295         struct iommu_state *it;
296
297         IS_LOCK_ASSERT(is);
298         /*
299          * Need to sync the streaming buffers of all IOMMUs, we cannot
300          * determine which one was used for the transaction.
301          */
302         STAILQ_FOREACH(it, &iommu_insts, is_link)
303                 iommu_strbuf_flush_sync(it);
304 }
305
306 /* LRU queue handling for lazy resource allocation. */
307 static __inline void
308 iommu_map_insq(struct iommu_state *is, bus_dmamap_t map)
309 {
310
311         IS_LOCK_ASSERT(is);
312         if (!SLIST_EMPTY(&map->dm_reslist)) {
313                 if (map->dm_onq)
314                         TAILQ_REMOVE(&iommu_maplruq, map, dm_maplruq);
315                 TAILQ_INSERT_TAIL(&iommu_maplruq, map, dm_maplruq);
316                 map->dm_onq = 1;
317         }
318 }
319
320 static __inline void
321 iommu_map_remq(struct iommu_state *is, bus_dmamap_t map)
322 {
323
324         IS_LOCK_ASSERT(is);
325         if (map->dm_onq)
326                 TAILQ_REMOVE(&iommu_maplruq, map, dm_maplruq);
327         map->dm_onq = 0;
328 }
329
330 /*
331  * initialise the UltraSPARC IOMMU (PCI or SBus):
332  *      - allocate and setup the iotsb.
333  *      - enable the IOMMU
334  *      - initialise the streaming buffers (if they exist)
335  *      - create a private DVMA map.
336  */
337 void
338 iommu_init(const char *name, struct iommu_state *is, int tsbsize,
339     uint32_t iovabase, int resvpg)
340 {
341         struct iommu_state *first;
342         vm_size_t size;
343         vm_offset_t offs;
344         uint64_t end;
345         int i;
346
347         /*
348          * Setup the iommu.
349          *
350          * The sun4u iommu is part of the PCI or SBus controller so we
351          * will deal with it here..
352          *
353          * The IOMMU address space always ends at 0xffffe000, but the starting
354          * address depends on the size of the map.  The map size is 1024 * 2 ^
355          * is->is_tsbsize entries, where each entry is 8 bytes.  The start of
356          * the map can be calculated by (0xffffe000 << (8 + is->is_tsbsize)).
357          */
358         is->is_cr = (tsbsize << IOMMUCR_TSBSZ_SHIFT) | IOMMUCR_EN;
359         is->is_tsbsize = tsbsize;
360         is->is_dvmabase = iovabase;
361         if (iovabase == -1)
362                 is->is_dvmabase = IOTSB_VSTART(is->is_tsbsize);
363
364         size = IOTSB_BASESZ << is->is_tsbsize;
365         printf("%s: DVMA map: %#lx to %#lx\n", name,
366             is->is_dvmabase, is->is_dvmabase +
367             (size << (IO_PAGE_SHIFT - IOTTE_SHIFT)) - 1);
368
369         if (STAILQ_EMPTY(&iommu_insts)) {
370                 /*
371                  * First IOMMU to be registered; set up resource mamangement
372                  * and allocate TSB memory.
373                  */
374                 mtx_init(&iommu_mtx, "iommu", NULL, MTX_DEF);
375                 end = is->is_dvmabase + (size << (IO_PAGE_SHIFT - IOTTE_SHIFT));
376                 iommu_dvma_rman.rm_type = RMAN_ARRAY;
377                 iommu_dvma_rman.rm_descr = "DVMA Memory";
378                 if (rman_init(&iommu_dvma_rman) != 0 ||
379                     rman_manage_region(&iommu_dvma_rman,
380                     (is->is_dvmabase >> IO_PAGE_SHIFT) + resvpg,
381                     (end >> IO_PAGE_SHIFT) - 1) != 0)
382                         panic("%s: could not initialize DVMA rman", __func__);
383                 /*
384                  * Allocate memory for I/O page tables.  They need to be
385                  * physically contiguous.
386                  */
387                 iommu_tsb = contigmalloc(size, M_DEVBUF, M_NOWAIT, 0, ~0UL,
388                     PAGE_SIZE, 0);
389                 if (iommu_tsb == 0)
390                         panic("%s: contigmalloc failed", __func__);
391                 iommu_ptsb = pmap_kextract((vm_offset_t)iommu_tsb);
392                 bzero(iommu_tsb, size);
393         } else {
394                 /*
395                  * Not the first IOMMU; just check that the parameters match
396                  * those of the first one.
397                  */
398                 first = STAILQ_FIRST(&iommu_insts);
399                 if (is->is_tsbsize != first->is_tsbsize ||
400                     is->is_dvmabase != first->is_dvmabase) {
401                         panic("%s: secondary IOMMU state does not "
402                             "match primary", __func__);
403                 }
404         }
405         STAILQ_INSERT_TAIL(&iommu_insts, is, is_link);
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] = (int64_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         int i;
438
439         IOMMU_WRITE8(is, is_iommu, IMR_TSB, iommu_ptsb);
440         /* Enable IOMMU in diagnostic mode */
441         IOMMU_WRITE8(is, is_iommu, IMR_CTL, is->is_cr | IOMMUCR_DE);
442
443         for (i = 0; i < 2; i++) {
444                 if (is->is_sb[i] != 0) {
445                         /* Enable diagnostics mode? */
446                         IOMMU_WRITE8(is, is_sb[i], ISR_CTL, STRBUF_EN);
447
448                         /* No streaming buffers? Disable them */
449                         if (IOMMU_READ8(is, is_sb[i], ISR_CTL) == 0)
450                                 is->is_sb[i] = 0;
451                 }
452         }
453 }
454
455 /*
456  * Enter a mapping into the TSB.  No locking required, since each TSB slot is
457  * uniquely assigned to a single map.
458  */
459 static void
460 iommu_enter(struct iommu_state *is, vm_offset_t va, vm_paddr_t pa,
461     int stream, int flags)
462 {
463         int64_t tte;
464
465         KASSERT(va >= is->is_dvmabase,
466             ("%s: va %#lx not in DVMA space", __func__, va));
467         KASSERT(pa < IOMMU_MAXADDR,
468             ("%s: XXX: physical address too large (%#lx)", __func__, pa));
469
470         tte = MAKEIOTTE(pa, !(flags & BUS_DMA_NOWRITE),
471             !(flags & BUS_DMA_NOCACHE), stream);
472
473         IOMMU_SET_TTE(is, va, tte);
474         iommu_tlb_flush(is, va);
475 #ifdef IOMMU_DIAG
476         IS_LOCK(is);
477         iommu_diag(is, va);
478         IS_UNLOCK(is);
479 #endif
480 }
481
482 /*
483  * Remove mappings created by iommu_enter().  Flush the streaming buffer,
484  * but do not synchronize it.  Returns whether a streaming buffer flush
485  * was performed.
486  */
487 static int
488 iommu_remove(struct iommu_state *is, vm_offset_t va, vm_size_t len)
489 {
490         int streamed = 0;
491
492 #ifdef IOMMU_DIAG
493         iommu_diag(is, va);
494 #endif
495
496         KASSERT(va >= is->is_dvmabase,
497             ("%s: va 0x%lx not in DVMA space", __func__, (u_long)va));
498         KASSERT(va + len >= va,
499             ("%s: va 0x%lx + len 0x%lx wraps", __func__, (long)va, (long)len));
500
501         va = trunc_io_page(va);
502         while (len > 0) {
503                 if ((IOMMU_GET_TTE(is, va) & IOTTE_STREAM) != 0) {
504                         streamed = 1;
505                         iommu_strbuf_flush(is, va);
506                 }
507                 len -= ulmin(len, IO_PAGE_SIZE);
508                 IOMMU_SET_TTE(is, va, 0);
509                 iommu_tlb_flush(is, va);
510                 va += IO_PAGE_SIZE;
511         }
512         return (streamed);
513 }
514
515 /* Decode an IOMMU fault for host bridge error handlers. */
516 void
517 iommu_decode_fault(struct iommu_state *is, vm_offset_t phys)
518 {
519         bus_addr_t va;
520         long idx;
521
522         idx = phys - iommu_ptsb;
523         if (phys < iommu_ptsb ||
524             idx > (PAGE_SIZE << is->is_tsbsize))
525                 return;
526         va = is->is_dvmabase +
527             (((bus_addr_t)idx >> IOTTE_SHIFT) << IO_PAGE_SHIFT);
528         printf("IOMMU fault virtual address %#lx\n", (u_long)va);
529 }
530
531 /*
532  * A barrier operation which makes sure that all previous streaming buffer
533  * flushes complete before it returns.
534  */
535 static int
536 iommu_strbuf_flush_sync(struct iommu_state *is)
537 {
538         struct timeval cur, end;
539         int i;
540
541         IS_LOCK_ASSERT(is);
542         if (!IOMMU_HAS_SB(is))
543                 return (0);
544
545         /*
546          * Streaming buffer flushes:
547          *
548          *   1 Tell strbuf to flush by storing va to strbuf_pgflush.  If
549          *     we're not on a cache line boundary (64-bits):
550          *   2 Store 0 in flag
551          *   3 Store pointer to flag in flushsync
552          *   4 wait till flushsync becomes 0x1
553          *
554          * If it takes more than .5 sec, something went wrong.
555          */
556         *is->is_flushva[0] = 1;
557         *is->is_flushva[1] = 1;
558         membar(StoreStore);
559         for (i = 0; i < 2; i++) {
560                 if (is->is_sb[i] != 0) {
561                         *is->is_flushva[i] = 0;
562                         IOMMU_WRITE8(is, is_sb[i], ISR_FLUSHSYNC,
563                             is->is_flushpa[i]);
564                 }
565         }
566
567         microuptime(&cur);
568         end.tv_sec = 0;
569         /*
570          * 0.5s is the recommended timeout from the U2S manual.  The actual
571          * time required should be smaller by at least a factor of 1000.
572          * We have no choice but to busy-wait.
573          */
574         end.tv_usec = 500000;
575         timevaladd(&end, &cur);
576
577         while ((!*is->is_flushva[0] || !*is->is_flushva[1]) &&
578             timevalcmp(&cur, &end, <=))
579                 microuptime(&cur);
580
581         if (!*is->is_flushva[0] || !*is->is_flushva[1]) {
582                 panic("%s: flush timeout %ld, %ld at %#lx", __func__,
583                     *is->is_flushva[0], *is->is_flushva[1], is->is_flushpa[0]);
584         }
585
586         return (1);
587 }
588
589 /* Determine whether we may enable streaming on a mapping. */
590 static __inline int
591 iommu_use_streaming(struct iommu_state *is, bus_dmamap_t map, bus_size_t size)
592 {
593
594         /*
595          * This cannot be enabled yet, as many driver are still missing
596          * bus_dmamap_sync() calls.  As soon as there is a BUS_DMA_STREAMING
597          * flag, this should be reenabled conditionally on it.
598          */
599 #ifdef notyet
600         return (size >= IOMMU_STREAM_THRESH && IOMMU_HAS_SB(is) &&
601             (map->dm_flags & DMF_COHERENT) == 0);
602 #else
603         return (0);
604 #endif
605 }
606
607 /*
608  * Allocate DVMA virtual memory for a map.  The map may not be on a queue,
609  * so that it can be freely modified.
610  */
611 static int
612 iommu_dvma_valloc(bus_dma_tag_t t, struct iommu_state *is, bus_dmamap_t map,
613     bus_size_t size)
614 {
615         struct resource *res;
616         struct bus_dmamap_res *bdr;
617         bus_size_t align, sgsize;
618
619         KASSERT(!map->dm_onq, ("%s: map on queue!", __func__));
620         if ((bdr = malloc(sizeof(*bdr), M_IOMMU, M_NOWAIT)) == NULL)
621                 return (EAGAIN);
622         /*
623          * If a boundary is specified, a map cannot be larger than it; however
624          * we do not clip currently, as that does not play well with the lazy
625          * allocation code.
626          * Alignment to a page boundary is always enforced.
627          */
628         align = (t->dt_alignment + IO_PAGE_MASK) >> IO_PAGE_SHIFT;
629         sgsize = round_io_page(size) >> IO_PAGE_SHIFT;
630         if (t->dt_boundary > 0 && t->dt_boundary < IO_PAGE_SIZE)
631                 panic("%s: illegal boundary specified", __func__);
632         res = rman_reserve_resource_bound(&iommu_dvma_rman, 0L,
633             t->dt_lowaddr >> IO_PAGE_SHIFT, sgsize,
634             t->dt_boundary >> IO_PAGE_SHIFT,
635             RF_ACTIVE | rman_make_alignment_flags(align), NULL);
636         if (res == NULL) {
637                 free(bdr, M_IOMMU);
638                 return (ENOMEM);
639         }
640
641         bdr->dr_res = res;
642         bdr->dr_used = 0;
643         SLIST_INSERT_HEAD(&map->dm_reslist, bdr, dr_link);
644         return (0);
645 }
646
647 /* Unload the map and mark all resources as unused, but do not free them. */
648 static void
649 iommu_dvmamap_vunload(struct iommu_state *is, bus_dmamap_t map)
650 {
651         struct bus_dmamap_res *r;
652         int streamed = 0;
653
654         IS_LOCK_ASSERT(is);     /* for iommu_strbuf_sync() below. */
655         SLIST_FOREACH(r, &map->dm_reslist, dr_link) {
656                 streamed |= iommu_remove(is, BDR_START(r), r->dr_used);
657                 r->dr_used = 0;
658         }
659         if (streamed)
660                 iommu_strbuf_sync(is);
661 }
662
663 /* Free a DVMA virtual memory resource. */
664 static __inline void
665 iommu_dvma_vfree_res(bus_dmamap_t map, struct bus_dmamap_res *r)
666 {
667
668         KASSERT(r->dr_used == 0, ("%s: resource busy!", __func__));
669         if (r->dr_res != NULL && rman_release_resource(r->dr_res) != 0)
670                 printf("warning: DVMA space lost\n");
671         SLIST_REMOVE(&map->dm_reslist, r, bus_dmamap_res, dr_link);
672         free(r, M_IOMMU);
673 }
674
675 /* Free all DVMA virtual memory for a map. */
676 static void
677 iommu_dvma_vfree(struct iommu_state *is, bus_dmamap_t map)
678 {
679
680         IS_LOCK(is);
681         iommu_map_remq(is, map);
682         iommu_dvmamap_vunload(is, map);
683         IS_UNLOCK(is);
684         while (!SLIST_EMPTY(&map->dm_reslist))
685                 iommu_dvma_vfree_res(map, SLIST_FIRST(&map->dm_reslist));
686 }
687
688 /* Prune a map, freeing all unused DVMA resources. */
689 static bus_size_t
690 iommu_dvma_vprune(struct iommu_state *is, bus_dmamap_t map)
691 {
692         struct bus_dmamap_res *r, *n;
693         bus_size_t freed = 0;
694
695         IS_LOCK_ASSERT(is);
696         for (r = SLIST_FIRST(&map->dm_reslist); r != NULL; r = n) {
697                 n = SLIST_NEXT(r, dr_link);
698                 if (r->dr_used == 0) {
699                         freed += BDR_SIZE(r);
700                         iommu_dvma_vfree_res(map, r);
701                 }
702         }
703         if (SLIST_EMPTY(&map->dm_reslist))
704                 iommu_map_remq(is, map);
705         return (freed);
706 }
707
708 /*
709  * Try to find a suitably-sized (and if requested, -aligned) slab of DVMA
710  * memory with IO page offset voffs.
711  */
712 static bus_addr_t
713 iommu_dvma_vfindseg(bus_dmamap_t map, vm_offset_t voffs, bus_size_t size,
714     bus_addr_t amask)
715 {
716         struct bus_dmamap_res *r;
717         bus_addr_t dvmaddr, dvmend;
718
719         KASSERT(!map->dm_onq, ("%s: map on queue!", __func__));
720         SLIST_FOREACH(r, &map->dm_reslist, dr_link) {
721                 dvmaddr = round_io_page(BDR_START(r) + r->dr_used);
722                 /* Alignment can only work with voffs == 0. */
723                 dvmaddr = (dvmaddr + amask) & ~amask;
724                 dvmaddr += voffs;
725                 dvmend = dvmaddr + size;
726                 if (dvmend <= BDR_END(r)) {
727                         r->dr_used = dvmend - BDR_START(r);
728                         return (dvmaddr);
729                 }
730         }
731         return (0);
732 }
733
734 /*
735  * Try to find or allocate a slab of DVMA space; see above.
736  */
737 static int
738 iommu_dvma_vallocseg(bus_dma_tag_t dt, struct iommu_state *is, bus_dmamap_t map,
739     vm_offset_t voffs, bus_size_t size, bus_addr_t amask, bus_addr_t *addr)
740 {
741         bus_dmamap_t tm, last;
742         bus_addr_t dvmaddr, freed;
743         int error, complete = 0;
744
745         dvmaddr = iommu_dvma_vfindseg(map, voffs, size, amask);
746
747         /* Need to allocate. */
748         if (dvmaddr == 0) {
749                 while ((error = iommu_dvma_valloc(dt, is, map,
750                         voffs + size)) == ENOMEM && !complete) {
751                         /*
752                          * Free the allocated DVMA of a few maps until
753                          * the required size is reached. This is an
754                          * approximation to not have to call the allocation
755                          * function too often; most likely one free run
756                          * will not suffice if not one map was large enough
757                          * itself due to fragmentation.
758                          */
759                         IS_LOCK(is);
760                         freed = 0;
761                         last = TAILQ_LAST(&iommu_maplruq, iommu_maplruq_head);
762                         do {
763                                 tm = TAILQ_FIRST(&iommu_maplruq);
764                                 complete = tm == last;
765                                 if (tm == NULL)
766                                         break;
767                                 freed += iommu_dvma_vprune(is, tm);
768                                 /* Move to the end. */
769                                 iommu_map_insq(is, tm);
770                         } while (freed < size && !complete);
771                         IS_UNLOCK(is);
772                 }
773                 if (error != 0)
774                         return (error);
775                 dvmaddr = iommu_dvma_vfindseg(map, voffs, size, amask);
776                 KASSERT(dvmaddr != 0, ("%s: allocation failed unexpectedly!",
777                     __func__));
778         }
779         *addr = dvmaddr;
780         return (0);
781 }
782
783 static int
784 iommu_dvmamem_alloc(bus_dma_tag_t dt, void **vaddr, int flags,
785     bus_dmamap_t *mapp)
786 {
787         struct iommu_state *is = dt->dt_cookie;
788         int error, mflags;
789
790         /*
791          * XXX: This will break for 32 bit transfers on machines with more
792          * than 16G (1 << 34 bytes) memory.
793          */
794         if ((error = sparc64_dma_alloc_map(dt, mapp)) != 0)
795                 return (error);
796
797         if ((flags & BUS_DMA_NOWAIT) != 0)
798                 mflags = M_NOWAIT;
799         else
800                 mflags = M_WAITOK;
801         if ((flags & BUS_DMA_ZERO) != 0)
802                 mflags |= M_ZERO;
803
804         if ((*vaddr = malloc(dt->dt_maxsize, M_IOMMU, mflags)) == NULL) {
805                 error = ENOMEM;
806                 sparc64_dma_free_map(dt, *mapp);
807                 return (error);
808         }
809         if ((flags & BUS_DMA_COHERENT) != 0)
810                 (*mapp)->dm_flags |= DMF_COHERENT;
811         /*
812          * Try to preallocate DVMA space.  If this fails, it is retried at
813          * load time.
814          */
815         iommu_dvma_valloc(dt, is, *mapp, IOMMU_SIZE_ROUNDUP(dt->dt_maxsize));
816         IS_LOCK(is);
817         iommu_map_insq(is, *mapp);
818         IS_UNLOCK(is);
819         return (0);
820 }
821
822 static void
823 iommu_dvmamem_free(bus_dma_tag_t dt, void *vaddr, bus_dmamap_t map)
824 {
825         struct iommu_state *is = dt->dt_cookie;
826
827         iommu_dvma_vfree(is, map);
828         sparc64_dma_free_map(dt, map);
829         free(vaddr, M_IOMMU);
830 }
831
832 static int
833 iommu_dvmamap_create(bus_dma_tag_t dt, int flags, bus_dmamap_t *mapp)
834 {
835         struct iommu_state *is = dt->dt_cookie;
836         bus_size_t totsz, presz, currsz;
837         int error, i, maxpre;
838
839         if ((error = sparc64_dma_alloc_map(dt, mapp)) != 0)
840                 return (error);
841         if ((flags & BUS_DMA_COHERENT) != 0)
842                 (*mapp)->dm_flags |= DMF_COHERENT;
843         /*
844          * Preallocate DVMA space; if this fails now, it is retried at load
845          * time.  Through bus_dmamap_load_mbuf() and bus_dmamap_load_uio(),
846          * it is possible to have multiple discontiguous segments in a single
847          * map, which is handled by allocating additional resources, instead
848          * of increasing the size, to avoid fragmentation.
849          * Clamp preallocation to IOMMU_MAX_PRE.  In some situations we can
850          * handle more; that case is handled by reallocating at map load time.
851          */
852         totsz = ulmin(IOMMU_SIZE_ROUNDUP(dt->dt_maxsize), IOMMU_MAX_PRE);
853         error = iommu_dvma_valloc(dt, is, *mapp, totsz);
854         if (error != 0)
855                 return (0);
856         /*
857          * Try to be smart about preallocating some additional segments if
858          * needed.
859          */
860         maxpre = imin(dt->dt_nsegments, IOMMU_MAX_PRE_SEG);
861         presz = dt->dt_maxsize / maxpre;
862         KASSERT(presz != 0, ("%s: bogus preallocation size , nsegments = %d, "
863             "maxpre = %d, maxsize = %lu", __func__, dt->dt_nsegments, maxpre,
864             dt->dt_maxsize));
865         for (i = 1; i < maxpre && totsz < IOMMU_MAX_PRE; i++) {
866                 currsz = round_io_page(ulmin(presz, IOMMU_MAX_PRE - totsz));
867                 error = iommu_dvma_valloc(dt, is, *mapp, currsz);
868                 if (error != 0)
869                         break;
870                 totsz += currsz;
871         }
872         IS_LOCK(is);
873         iommu_map_insq(is, *mapp);
874         IS_UNLOCK(is);
875         return (0);
876 }
877
878 static int
879 iommu_dvmamap_destroy(bus_dma_tag_t dt, bus_dmamap_t map)
880 {
881         struct iommu_state *is = dt->dt_cookie;
882
883         iommu_dvma_vfree(is, map);
884         sparc64_dma_free_map(dt, map);
885         return (0);
886 }
887
888 /*
889  * IOMMU DVMA operations, common to PCI and SBus.
890  */
891 static int
892 iommu_dvmamap_load_buffer(bus_dma_tag_t dt, struct iommu_state *is,
893     bus_dmamap_t map, void *buf, bus_size_t buflen, struct thread *td,
894     int flags, bus_dma_segment_t *segs, int *segp, int align)
895 {
896         bus_addr_t amask, dvmaddr;
897         bus_size_t sgsize, esize;
898         vm_offset_t vaddr, voffs;
899         vm_paddr_t curaddr;
900         int error, sgcnt, firstpg, stream;
901         pmap_t pmap = NULL;
902
903         KASSERT(buflen != 0, ("%s: buflen == 0!", __func__));
904         if (buflen > dt->dt_maxsize)
905                 return (EINVAL);
906
907         if (td != NULL)
908                 pmap = vmspace_pmap(td->td_proc->p_vmspace);
909
910         vaddr = (vm_offset_t)buf;
911         voffs = vaddr & IO_PAGE_MASK;
912         amask = align ? dt->dt_alignment - 1 : 0;
913
914         /* Try to find a slab that is large enough. */
915         error = iommu_dvma_vallocseg(dt, is, map, voffs, buflen, amask,
916             &dvmaddr);
917         if (error != 0)
918                 return (error);
919
920         sgcnt = *segp;
921         firstpg = 1;
922         stream = iommu_use_streaming(is, map, buflen);
923         for (; buflen > 0; ) {
924                 /*
925                  * Get the physical address for this page.
926                  */
927                 if (pmap != NULL)
928                         curaddr = pmap_extract(pmap, vaddr);
929                 else
930                         curaddr = pmap_kextract(vaddr);
931
932                 /*
933                  * Compute the segment size, and adjust counts.
934                  */
935                 sgsize = IO_PAGE_SIZE - ((u_long)vaddr & IO_PAGE_MASK);
936                 if (buflen < sgsize)
937                         sgsize = buflen;
938
939                 buflen -= sgsize;
940                 vaddr += sgsize;
941
942                 iommu_enter(is, trunc_io_page(dvmaddr), trunc_io_page(curaddr),
943                     stream, flags);
944
945                 /*
946                  * Chop the chunk up into segments of at most maxsegsz, but try
947                  * to fill each segment as well as possible.
948                  */
949                 if (!firstpg) {
950                         esize = ulmin(sgsize,
951                             dt->dt_maxsegsz - segs[sgcnt].ds_len);
952                         segs[sgcnt].ds_len += esize;
953                         sgsize -= esize;
954                         dvmaddr += esize;
955                 }
956                 while (sgsize > 0) {
957                         sgcnt++;
958                         if (sgcnt >= dt->dt_nsegments)
959                                 return (EFBIG);
960                         /*
961                          * No extra alignment here - the common practice in
962                          * the busdma code seems to be that only the first
963                          * segment needs to satisfy the alignment constraints
964                          * (and that only for bus_dmamem_alloc()ed maps).
965                          * It is assumed that such tags have maxsegsize >=
966                          * maxsize.
967                          */
968                         esize = ulmin(sgsize, dt->dt_maxsegsz);
969                         segs[sgcnt].ds_addr = dvmaddr;
970                         segs[sgcnt].ds_len = esize;
971                         sgsize -= esize;
972                         dvmaddr += esize;
973                 }
974
975                 firstpg = 0;
976         }
977         *segp = sgcnt;
978         return (0);
979 }
980
981 static int
982 iommu_dvmamap_load(bus_dma_tag_t dt, bus_dmamap_t map, void *buf,
983     bus_size_t buflen, bus_dmamap_callback_t *cb, void *cba,
984     int flags)
985 {
986         struct iommu_state *is = dt->dt_cookie;
987         int error, seg = -1;
988
989         if ((map->dm_flags & DMF_LOADED) != 0) {
990 #ifdef DIAGNOSTIC
991                 printf("%s: map still in use\n", __func__);
992 #endif
993                 bus_dmamap_unload(dt, map);
994         }
995
996         /*
997          * Make sure that the map is not on a queue so that the resource list
998          * may be safely accessed and modified without needing the lock to
999          * cover the whole operation.
1000          */
1001         IS_LOCK(is);
1002         iommu_map_remq(is, map);
1003         IS_UNLOCK(is);
1004
1005         error = iommu_dvmamap_load_buffer(dt, is, map, buf, buflen, NULL,
1006             flags, dt->dt_segments, &seg, 1);
1007
1008         IS_LOCK(is);
1009         iommu_map_insq(is, map);
1010         if (error != 0) {
1011                 iommu_dvmamap_vunload(is, map);
1012                 IS_UNLOCK(is);
1013                 (*cb)(cba, dt->dt_segments, 0, error);
1014         } else {
1015                 IS_UNLOCK(is);
1016                 map->dm_flags |= DMF_LOADED;
1017                 (*cb)(cba, dt->dt_segments, seg + 1, 0);
1018         }
1019
1020         return (error);
1021 }
1022
1023 static int
1024 iommu_dvmamap_load_mbuf(bus_dma_tag_t dt, bus_dmamap_t map, struct mbuf *m0,
1025     bus_dmamap_callback2_t *cb, void *cba, int flags)
1026 {
1027         struct iommu_state *is = dt->dt_cookie;
1028         struct mbuf *m;
1029         int error = 0, first = 1, nsegs = -1;
1030
1031         M_ASSERTPKTHDR(m0);
1032
1033         if ((map->dm_flags & DMF_LOADED) != 0) {
1034 #ifdef DIAGNOSTIC
1035                 printf("%s: map still in use\n", __func__);
1036 #endif
1037                 bus_dmamap_unload(dt, map);
1038         }
1039
1040         IS_LOCK(is);
1041         iommu_map_remq(is, map);
1042         IS_UNLOCK(is);
1043
1044         if (m0->m_pkthdr.len <= dt->dt_maxsize) {
1045                 for (m = m0; m != NULL && error == 0; m = m->m_next) {
1046                         if (m->m_len == 0)
1047                                 continue;
1048                         error = iommu_dvmamap_load_buffer(dt, is, map,
1049                             m->m_data, m->m_len, NULL, flags, dt->dt_segments,
1050                             &nsegs, first);
1051                         first = 0;
1052                 }
1053         } else
1054                 error = EINVAL;
1055
1056         IS_LOCK(is);
1057         iommu_map_insq(is, map);
1058         if (error != 0) {
1059                 iommu_dvmamap_vunload(is, map);
1060                 IS_UNLOCK(is);
1061                 /* force "no valid mappings" in callback */
1062                 (*cb)(cba, dt->dt_segments, 0, 0, error);
1063         } else {
1064                 IS_UNLOCK(is);
1065                 map->dm_flags |= DMF_LOADED;
1066                 (*cb)(cba, dt->dt_segments, nsegs + 1, m0->m_pkthdr.len, 0);
1067         }
1068         return (error);
1069 }
1070
1071 static int
1072 iommu_dvmamap_load_mbuf_sg(bus_dma_tag_t dt, bus_dmamap_t map, struct mbuf *m0,
1073     bus_dma_segment_t *segs, int *nsegs, int flags)
1074 {
1075         struct iommu_state *is = dt->dt_cookie;
1076         struct mbuf *m;
1077         int error = 0, first = 1;
1078
1079         M_ASSERTPKTHDR(m0);
1080
1081         *nsegs = -1;
1082         if ((map->dm_flags & DMF_LOADED) != 0) {
1083 #ifdef DIAGNOSTIC
1084                 printf("%s: map still in use\n", __func__);
1085 #endif
1086                 bus_dmamap_unload(dt, map);
1087         }
1088
1089         IS_LOCK(is);
1090         iommu_map_remq(is, map);
1091         IS_UNLOCK(is);
1092
1093         if (m0->m_pkthdr.len <= dt->dt_maxsize) {
1094                 for (m = m0; m != NULL && error == 0; m = m->m_next) {
1095                         if (m->m_len == 0)
1096                                 continue;
1097                         error = iommu_dvmamap_load_buffer(dt, is, map,
1098                             m->m_data, m->m_len, NULL, flags, segs,
1099                             nsegs, first);
1100                         first = 0;
1101                 }
1102         } else
1103                 error = EINVAL;
1104
1105         IS_LOCK(is);
1106         iommu_map_insq(is, map);
1107         if (error != 0) {
1108                 iommu_dvmamap_vunload(is, map);
1109                 IS_UNLOCK(is);
1110         } else {
1111                 IS_UNLOCK(is);
1112                 map->dm_flags |= DMF_LOADED;
1113                 ++*nsegs;
1114         }
1115         return (error);
1116 }
1117
1118 static int
1119 iommu_dvmamap_load_uio(bus_dma_tag_t dt, bus_dmamap_t map, struct uio *uio,
1120     bus_dmamap_callback2_t *cb,  void *cba, int flags)
1121 {
1122         struct iommu_state *is = dt->dt_cookie;
1123         struct iovec *iov;
1124         struct thread *td = NULL;
1125         bus_size_t minlen, resid;
1126         int nsegs = -1, error = 0, first = 1, i;
1127
1128         if ((map->dm_flags & DMF_LOADED) != 0) {
1129 #ifdef DIAGNOSTIC
1130                 printf("%s: map still in use\n", __func__);
1131 #endif
1132                 bus_dmamap_unload(dt, map);
1133         }
1134
1135         IS_LOCK(is);
1136         iommu_map_remq(is, map);
1137         IS_UNLOCK(is);
1138
1139         resid = uio->uio_resid;
1140         iov = uio->uio_iov;
1141
1142         if (uio->uio_segflg == UIO_USERSPACE) {
1143                 td = uio->uio_td;
1144                 KASSERT(td != NULL,
1145                     ("%s: USERSPACE but no proc", __func__));
1146         }
1147
1148         for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) {
1149                 /*
1150                  * Now at the first iovec to load.  Load each iovec
1151                  * until we have exhausted the residual count.
1152                  */
1153                 minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len;
1154                 if (minlen == 0)
1155                         continue;
1156
1157                 error = iommu_dvmamap_load_buffer(dt, is, map,
1158                     iov[i].iov_base, minlen, td, flags, dt->dt_segments,
1159                     &nsegs, first);
1160                 first = 0;
1161
1162                 resid -= minlen;
1163         }
1164
1165         IS_LOCK(is);
1166         iommu_map_insq(is, map);
1167         if (error) {
1168                 iommu_dvmamap_vunload(is, map);
1169                 IS_UNLOCK(is);
1170                 /* force "no valid mappings" in callback */
1171                 (*cb)(cba, dt->dt_segments, 0, 0, error);
1172         } else {
1173                 IS_UNLOCK(is);
1174                 map->dm_flags |= DMF_LOADED;
1175                 (*cb)(cba, dt->dt_segments, nsegs + 1, uio->uio_resid, 0);
1176         }
1177         return (error);
1178 }
1179
1180 static void
1181 iommu_dvmamap_unload(bus_dma_tag_t dt, bus_dmamap_t map)
1182 {
1183         struct iommu_state *is = dt->dt_cookie;
1184
1185         if ((map->dm_flags & DMF_LOADED) == 0)
1186                 return;
1187         IS_LOCK(is);
1188         iommu_dvmamap_vunload(is, map);
1189         iommu_map_insq(is, map);
1190         IS_UNLOCK(is);
1191         map->dm_flags &= ~DMF_LOADED;
1192 }
1193
1194 static void
1195 iommu_dvmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
1196 {
1197         struct iommu_state *is = dt->dt_cookie;
1198         struct bus_dmamap_res *r;
1199         vm_offset_t va;
1200         vm_size_t len;
1201         int streamed = 0;
1202
1203         if ((map->dm_flags & DMF_LOADED) == 0)
1204                 return;
1205         /* XXX This is probably bogus. */
1206         if ((op & BUS_DMASYNC_PREREAD) != 0)
1207                 membar(Sync);
1208         if (IOMMU_HAS_SB(is) &&
1209             ((op & BUS_DMASYNC_POSTREAD) != 0 ||
1210             (op & BUS_DMASYNC_PREWRITE) != 0)) {
1211                 IS_LOCK(is);
1212                 SLIST_FOREACH(r, &map->dm_reslist, dr_link) {
1213                         va = (vm_offset_t)BDR_START(r);
1214                         len = r->dr_used;
1215                         /*
1216                          * If we have a streaming buffer, flush it here
1217                          * first.
1218                          */
1219                         while (len > 0) {
1220                                 if ((IOMMU_GET_TTE(is, va) &
1221                                     IOTTE_STREAM) != 0) {
1222                                         streamed = 1;
1223                                         iommu_strbuf_flush(is, va);
1224                                 }
1225                                 len -= ulmin(len, IO_PAGE_SIZE);
1226                                 va += IO_PAGE_SIZE;
1227                         }
1228                 }
1229                 if (streamed)
1230                         iommu_strbuf_sync(is);
1231                 IS_UNLOCK(is);
1232         }
1233         if ((op & BUS_DMASYNC_PREWRITE) != 0)
1234                 membar(Sync);
1235 }
1236
1237 #ifdef IOMMU_DIAG
1238
1239 /*
1240  * Perform an IOMMU diagnostic access and print the tag belonging to va.
1241  */
1242 static void
1243 iommu_diag(struct iommu_state *is, vm_offset_t va)
1244 {
1245         int i;
1246         uint64_t data, tag;
1247
1248         IS_LOCK_ASSERT(is);
1249         IOMMU_WRITE8(is, is_dva, 0, trunc_io_page(va));
1250         membar(StoreStore | StoreLoad);
1251         printf("%s: tte entry %#lx", __func__, IOMMU_GET_TTE(is, va));
1252         if (is->is_dtcmp != 0) {
1253                 printf(", tag compare register is %#lx\n",
1254                     IOMMU_READ8(is, is_dtcmp, 0));
1255         } else
1256                 printf("\n");
1257         for (i = 0; i < 16; i++) {
1258                 tag = IOMMU_READ8(is, is_dtag, i * 8);
1259                 data = IOMMU_READ8(is, is_ddram, i * 8);
1260                 printf("%s: tag %d: %#lx, vpn %#lx, err %lx; "
1261                     "data %#lx, pa %#lx, v %d, c %d\n", __func__, i,
1262                     tag, (tag & IOMMU_DTAG_VPNMASK) << IOMMU_DTAG_VPNSHIFT,
1263                     (tag & IOMMU_DTAG_ERRMASK) >> IOMMU_DTAG_ERRSHIFT, data,
1264                     (data & IOMMU_DDATA_PGMASK) << IOMMU_DDATA_PGSHIFT,
1265                     (data & IOMMU_DDATA_V) != 0, (data & IOMMU_DDATA_C) != 0);
1266         }
1267 }
1268
1269 #endif /* IOMMU_DIAG */
1270
1271 struct bus_dma_methods iommu_dma_methods = {
1272         iommu_dvmamap_create,
1273         iommu_dvmamap_destroy,
1274         iommu_dvmamap_load,
1275         iommu_dvmamap_load_mbuf,
1276         iommu_dvmamap_load_mbuf_sg,
1277         iommu_dvmamap_load_uio,
1278         iommu_dvmamap_unload,
1279         iommu_dvmamap_sync,
1280         iommu_dvmamem_alloc,
1281         iommu_dvmamem_free,
1282 };