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