xref: /netbsd-src/sys/arch/sparc64/dev/ebus.c (revision 8a8f936f250a330d54f8a24ed0e92aadf9743a7b)
1 /*	$NetBSD: ebus.c,v 1.28 2001/09/26 20:53:10 eeh Exp $	*/
2 
3 /*
4  * Copyright (c) 1999, 2000 Matthew R. Green
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include "opt_ddb.h"
32 
33 /*
34  * UltraSPARC 5 and beyond ebus support.
35  *
36  * note that this driver is not complete:
37  *	- ebus2 dma code is completely unwritten
38  *	- interrupt establish is written and appears to work
39  *	- bus map code is written and appears to work
40  */
41 
42 #undef DEBUG
43 #define DEBUG
44 
45 #ifdef DEBUG
46 #define	EDB_PROM	0x01
47 #define EDB_CHILD	0x02
48 #define	EDB_INTRMAP	0x04
49 #define EDB_BUSMAP	0x08
50 #define EDB_BUSDMA	0x10
51 #define EDB_INTR	0x20
52 int ebus_debug = 0x0;
53 #define DPRINTF(l, s)   do { if (ebus_debug & l) printf s; } while (0)
54 #else
55 #define DPRINTF(l, s)
56 #endif
57 
58 #include <sys/param.h>
59 #include <sys/conf.h>
60 #include <sys/device.h>
61 #include <sys/errno.h>
62 #include <sys/extent.h>
63 #include <sys/malloc.h>
64 #include <sys/systm.h>
65 #include <sys/time.h>
66 
67 #define _SPARC_BUS_DMA_PRIVATE
68 #include <machine/bus.h>
69 #include <machine/autoconf.h>
70 #include <machine/openfirm.h>
71 
72 #include <dev/pci/pcivar.h>
73 #include <dev/pci/pcireg.h>
74 #include <dev/pci/pcidevs.h>
75 
76 #include <sparc64/dev/iommureg.h>
77 #include <sparc64/dev/iommuvar.h>
78 #include <sparc64/dev/psychoreg.h>
79 #include <sparc64/dev/psychovar.h>
80 #include <sparc64/dev/ebusreg.h>
81 #include <sparc64/dev/ebusvar.h>
82 #include <sparc64/sparc64/cache.h>
83 
84 int	ebus_match __P((struct device *, struct cfdata *, void *));
85 void	ebus_attach __P((struct device *, struct device *, void *));
86 
87 struct cfattach ebus_ca = {
88 	sizeof(struct ebus_softc), ebus_match, ebus_attach
89 };
90 
91 int	ebus_setup_attach_args __P((struct ebus_softc *, int,
92 	    struct ebus_attach_args *));
93 void	ebus_destroy_attach_args __P((struct ebus_attach_args *));
94 int	ebus_print __P((void *, const char *));
95 void	ebus_find_ino __P((struct ebus_softc *, struct ebus_attach_args *));
96 int	ebus_find_node __P((struct pci_attach_args *));
97 
98 /*
99  * here are our bus space and bus dma routines.
100  */
101 static paddr_t ebus_bus_mmap __P((bus_space_tag_t, bus_addr_t, off_t, int, int));
102 static int _ebus_bus_map __P((bus_space_tag_t, bus_type_t, bus_addr_t,
103 				bus_size_t, int, vaddr_t,
104 				bus_space_handle_t *));
105 static void *ebus_intr_establish __P((bus_space_tag_t, int, int, int,
106 				int (*) __P((void *)), void *));
107 
108 static int ebus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
109 			  bus_size_t, struct proc *, int));
110 static void ebus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
111 static void ebus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
112 				  bus_size_t, int));
113 int ebus_dmamem_alloc __P((bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t,
114 			   bus_dma_segment_t *, int, int *, int));
115 void ebus_dmamem_free __P((bus_dma_tag_t, bus_dma_segment_t *, int));
116 int ebus_dmamem_map __P((bus_dma_tag_t, bus_dma_segment_t *, int, size_t,
117 			 caddr_t *, int));
118 void ebus_dmamem_unmap __P((bus_dma_tag_t, caddr_t, size_t));
119 
120 int
121 ebus_match(parent, match, aux)
122 	struct device *parent;
123 	struct cfdata *match;
124 	void *aux;
125 {
126 	struct pci_attach_args *pa = aux;
127 	char name[10];
128 	int node;
129 
130 	/* Only attach if there's a PROM node. */
131 	node = PCITAG_NODE(pa->pa_tag);
132 	if (node == -1) return (0);
133 
134 	/* Match a real ebus */
135 	OF_getprop(node, "name", &name, sizeof(name));
136 	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
137 	    PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN &&
138 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_EBUS &&
139 		strcmp(name, "ebus") == 0)
140 		return (1);
141 
142 	/* Or a real ebus III */
143 	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
144 	    PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN &&
145 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_EBUSIII &&
146 		strcmp(name, "ebus") == 0)
147 		return (1);
148 
149 	/* Or a PCI-ISA bridge XXX I hope this is on-board. */
150 	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
151 	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_ISA) {
152 		return (1);
153 	}
154 
155 	return (0);
156 }
157 
158 /*
159  * attach an ebus and all it's children.  this code is modeled
160  * after the sbus code which does similar things.
161  */
162 void
163 ebus_attach(parent, self, aux)
164 	struct device *parent, *self;
165 	void *aux;
166 {
167 	struct ebus_softc *sc = (struct ebus_softc *)self;
168 	struct pci_attach_args *pa = aux;
169 	struct ebus_attach_args eba;
170 	struct ebus_interrupt_map_mask *immp;
171 	int node, nmapmask, error;
172 	char devinfo[256];
173 
174 	printf("\n");
175 
176 	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo);
177 	printf("%s: %s, revision 0x%02x\n", self->dv_xname, devinfo,
178 	    PCI_REVISION(pa->pa_class));
179 
180 	sc->sc_parent = (struct psycho_softc *)parent;
181 	sc->sc_memtag = pa->pa_memt;
182 	sc->sc_iotag = pa->pa_iot;
183 	sc->sc_childbustag = ebus_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE);
184 	sc->sc_dmatag = ebus_alloc_dma_tag(sc, pa->pa_dmat);
185 
186 	node = PCITAG_NODE(pa->pa_tag);
187 	if (node == -1)
188 		panic("could not find ebus node");
189 
190 	sc->sc_node = node;
191 
192 	/*
193 	 * fill in our softc with information from the prom
194 	 */
195 	sc->sc_intmap = NULL;
196 	sc->sc_range = NULL;
197 	error = PROM_getprop(node, "interrupt-map",
198 			sizeof(struct ebus_interrupt_map),
199 			&sc->sc_nintmap, (void **)&sc->sc_intmap);
200 	switch (error) {
201 	case 0:
202 		immp = &sc->sc_intmapmask;
203 		error = PROM_getprop(node, "interrupt-map-mask",
204 			    sizeof(struct ebus_interrupt_map_mask), &nmapmask,
205 			    (void **)&immp);
206 		if (error)
207 			panic("could not get ebus interrupt-map-mask");
208 		if (nmapmask != 1)
209 			panic("ebus interrupt-map-mask is broken");
210 		break;
211 	case ENOENT:
212 		break;
213 	default:
214 		panic("ebus interrupt-map: error %d", error);
215 		break;
216 	}
217 
218 	error = PROM_getprop(node, "ranges", sizeof(struct ebus_ranges),
219 	    &sc->sc_nrange, (void **)&sc->sc_range);
220 	if (error)
221 		panic("ebus ranges: error %d", error);
222 
223 	/*
224 	 * now attach all our children
225 	 */
226 	DPRINTF(EDB_CHILD, ("ebus node %08x, searching children...\n", node));
227 	for (node = firstchild(node); node; node = nextsibling(node)) {
228 		char *name = PROM_getpropstring(node, "name");
229 
230 		if (ebus_setup_attach_args(sc, node, &eba) != 0) {
231 			printf("ebus_attach: %s: incomplete\n", name);
232 			continue;
233 		} else {
234 			DPRINTF(EDB_CHILD, ("- found child `%s', attaching\n",
235 			    eba.ea_name));
236 			(void)config_found(self, &eba, ebus_print);
237 		}
238 		ebus_destroy_attach_args(&eba);
239 	}
240 }
241 
242 int
243 ebus_setup_attach_args(sc, node, ea)
244 	struct ebus_softc	*sc;
245 	int			node;
246 	struct ebus_attach_args	*ea;
247 {
248 	int	n, rv;
249 
250 	bzero(ea, sizeof(struct ebus_attach_args));
251 	rv = PROM_getprop(node, "name", 1, &n, (void **)&ea->ea_name);
252 	if (rv != 0)
253 		return (rv);
254 	ea->ea_name[n] = '\0';
255 
256 	ea->ea_node = node;
257 	ea->ea_bustag = sc->sc_childbustag;
258 	ea->ea_dmatag = sc->sc_dmatag;
259 
260 	rv = PROM_getprop(node, "reg", sizeof(struct ebus_regs), &ea->ea_nregs,
261 	    (void **)&ea->ea_regs);
262 	if (rv)
263 		return (rv);
264 
265 	rv = PROM_getprop(node, "address", sizeof(u_int32_t), &ea->ea_nvaddrs,
266 	    (void **)&ea->ea_vaddrs);
267 	if (rv != ENOENT) {
268 		if (rv)
269 			return (rv);
270 
271 		if (ea->ea_nregs != ea->ea_nvaddrs)
272 			printf("ebus loses: device %s: %d regs and %d addrs\n",
273 			    ea->ea_name, ea->ea_nregs, ea->ea_nvaddrs);
274 	} else
275 		ea->ea_nvaddrs = 0;
276 
277 	if (PROM_getprop(node, "interrupts", sizeof(u_int32_t), &ea->ea_nintrs,
278 	    (void **)&ea->ea_intrs))
279 		ea->ea_nintrs = 0;
280 	else
281 		ebus_find_ino(sc, ea);
282 
283 	return (0);
284 }
285 
286 void
287 ebus_destroy_attach_args(ea)
288 	struct ebus_attach_args	*ea;
289 {
290 
291 	if (ea->ea_name)
292 		free((void *)ea->ea_name, M_DEVBUF);
293 	if (ea->ea_regs)
294 		free((void *)ea->ea_regs, M_DEVBUF);
295 	if (ea->ea_intrs)
296 		free((void *)ea->ea_intrs, M_DEVBUF);
297 	if (ea->ea_vaddrs)
298 		free((void *)ea->ea_vaddrs, M_DEVBUF);
299 }
300 
301 int
302 ebus_print(aux, p)
303 	void *aux;
304 	const char *p;
305 {
306 	struct ebus_attach_args *ea = aux;
307 	int i;
308 
309 	if (p)
310 		printf("%s at %s", ea->ea_name, p);
311 	for (i = 0; i < ea->ea_nregs; i++)
312 		printf("%s %x-%x", i == 0 ? " addr" : ",",
313 		    ea->ea_regs[i].lo,
314 		    ea->ea_regs[i].lo + ea->ea_regs[i].size - 1);
315 	for (i = 0; i < ea->ea_nintrs; i++)
316 		printf(" ipl %d", ea->ea_intrs[i]);
317 	return (UNCONF);
318 }
319 
320 
321 /*
322  * find the INO values for each interrupt and fill them in.
323  *
324  * for each "reg" property of this device, mask it's hi and lo
325  * values with the "interrupt-map-mask"'s hi/lo values, and also
326  * mask the interrupt number with the interrupt mask.  search the
327  * "interrupt-map" list for matching values of hi, lo and interrupt
328  * to give the INO for this interrupt.
329  */
330 void
331 ebus_find_ino(sc, ea)
332 	struct ebus_softc *sc;
333 	struct ebus_attach_args *ea;
334 {
335 	u_int32_t hi, lo, intr;
336 	int i, j, k;
337 
338 	if (sc->sc_nintmap == 0) {
339 		for (i = 0; i < ea->ea_nintrs; i++) {
340 			OF_mapintr(ea->ea_node, &ea->ea_intrs[i],
341 				sizeof(ea->ea_intrs[0]),
342 				sizeof(ea->ea_intrs[0]));
343 		}
344 		return;
345 	}
346 
347 	DPRINTF(EDB_INTRMAP,
348 	    ("ebus_find_ino: searching %d interrupts", ea->ea_nintrs));
349 
350 	for (j = 0; j < ea->ea_nintrs; j++) {
351 
352 		intr = ea->ea_intrs[j] & sc->sc_intmapmask.intr;
353 
354 		DPRINTF(EDB_INTRMAP,
355 		    ("; intr %x masked to %x", ea->ea_intrs[j], intr));
356 		for (i = 0; i < ea->ea_nregs; i++) {
357 			hi = ea->ea_regs[i].hi & sc->sc_intmapmask.hi;
358 			lo = ea->ea_regs[i].lo & sc->sc_intmapmask.lo;
359 
360 			DPRINTF(EDB_INTRMAP,
361 			    ("; reg hi.lo %08x.%08x masked to %08x.%08x",
362 			    ea->ea_regs[i].hi, ea->ea_regs[i].lo, hi, lo));
363 			for (k = 0; k < sc->sc_nintmap; k++) {
364 				DPRINTF(EDB_INTRMAP,
365 				    ("; checking hi.lo %08x.%08x intr %x",
366 				    sc->sc_intmap[k].hi, sc->sc_intmap[k].lo,
367 				    sc->sc_intmap[k].intr));
368 				if (hi == sc->sc_intmap[k].hi &&
369 				    lo == sc->sc_intmap[k].lo &&
370 				    intr == sc->sc_intmap[k].intr) {
371 					ea->ea_intrs[j] =
372 					    sc->sc_intmap[k].cintr;
373 					DPRINTF(EDB_INTRMAP,
374 					    ("; FOUND IT! changing to %d\n",
375 					    sc->sc_intmap[k].cintr));
376 					goto next_intr;
377 				}
378 			}
379 		}
380 next_intr:;
381 	}
382 }
383 
384 
385 /*
386  * bus space and bus dma below here
387  */
388 bus_space_tag_t
389 ebus_alloc_bus_tag(sc, type)
390 	struct ebus_softc *sc;
391 	int type;
392 {
393 	bus_space_tag_t bt;
394 
395 	bt = (bus_space_tag_t)
396 		malloc(sizeof(struct sparc_bus_space_tag), M_DEVBUF, M_NOWAIT);
397 	if (bt == NULL)
398 		panic("could not allocate ebus bus tag");
399 
400 	bzero(bt, sizeof *bt);
401 	bt->cookie = sc;
402 	bt->parent = sc->sc_memtag;
403 	bt->type = type;
404 	bt->sparc_bus_map = _ebus_bus_map;
405 	bt->sparc_bus_mmap = ebus_bus_mmap;
406 	bt->sparc_intr_establish = ebus_intr_establish;
407 	return (bt);
408 }
409 
410 /* XXX? */
411 bus_dma_tag_t
412 ebus_alloc_dma_tag(sc, pdt)
413 	struct ebus_softc *sc;
414 	bus_dma_tag_t pdt;
415 {
416 	bus_dma_tag_t dt;
417 
418 	dt = (bus_dma_tag_t)
419 		malloc(sizeof(struct sparc_bus_dma_tag), M_DEVBUF, M_NOWAIT);
420 	if (dt == NULL)
421 		panic("could not allocate ebus dma tag");
422 
423 	bzero(dt, sizeof *dt);
424 	dt->_cookie = sc;
425 	dt->_parent = pdt;
426 #define PCOPY(x)	dt->x = pdt->x
427 	PCOPY(_dmamap_create);
428 	PCOPY(_dmamap_destroy);
429 	dt->_dmamap_load = ebus_dmamap_load;
430 	PCOPY(_dmamap_load_mbuf);
431 	PCOPY(_dmamap_load_uio);
432 	PCOPY(_dmamap_load_raw);
433 	dt->_dmamap_unload = ebus_dmamap_unload;
434 	dt->_dmamap_sync = ebus_dmamap_sync;
435 	dt->_dmamem_alloc = ebus_dmamem_alloc;
436 	dt->_dmamem_free = ebus_dmamem_free;
437 	dt->_dmamem_map = ebus_dmamem_map;
438 	dt->_dmamem_unmap = ebus_dmamem_unmap;
439 	PCOPY(_dmamem_mmap);
440 #undef	PCOPY
441 	return (dt);
442 }
443 
444 /*
445  * bus space support.  <sparc64/dev/psychoreg.h> has a discussion
446  * about PCI physical addresses, which also applies to ebus.
447  */
448 static int
449 _ebus_bus_map(t, btype, offset, size, flags, vaddr, hp)
450 	bus_space_tag_t t;
451 	bus_type_t btype;
452 	bus_addr_t offset;
453 	bus_size_t size;
454 	int	flags;
455 	vaddr_t vaddr;
456 	bus_space_handle_t *hp;
457 {
458 	struct ebus_softc *sc = t->cookie;
459 	bus_addr_t hi, lo;
460 	int i, ss;
461 
462 	DPRINTF(EDB_BUSMAP,
463 	    ("\n_ebus_bus_map: type %d off %016llx sz %x flags %d va %p",
464 	    (int)t->type, (unsigned long long)offset, (int)size, (int)flags,
465 	    (void *)vaddr));
466 
467 	hi = offset >> 32UL;
468 	lo = offset & 0xffffffff;
469 	DPRINTF(EDB_BUSMAP, (" (hi %08x lo %08x)", (u_int)hi, (u_int)lo));
470 	for (i = 0; i < sc->sc_nrange; i++) {
471 		bus_addr_t pciaddr;
472 
473 		if (hi != sc->sc_range[i].child_hi)
474 			continue;
475 		if (lo < sc->sc_range[i].child_lo ||
476 		    (lo + size) >
477 		      (sc->sc_range[i].child_lo + sc->sc_range[i].size))
478 			continue;
479 
480 		/* Isolate address space and find the right tag */
481 		ss = (sc->sc_range[i].phys_hi>>24)&3;
482 		switch (ss) {
483 		case 1:	/* I/O space */
484 			t = sc->sc_iotag;
485 			break;
486 		case 2:	/* Memory space */
487 			t = sc->sc_memtag;
488 			break;
489 		case 0:	/* Config space */
490 		case 3:	/* 64-bit Memory space */
491 		default: /* WTF? */
492 			/* We don't handle these */
493 			panic("_ebus_bus_map: illegal space %x", ss);
494 			break;
495 		}
496 		pciaddr = ((bus_addr_t)sc->sc_range[i].phys_mid << 32UL) |
497 				       sc->sc_range[i].phys_lo;
498 		pciaddr += lo;
499 		DPRINTF(EDB_BUSMAP,
500 		    ("\n_ebus_bus_map: mapping space %x paddr offset %qx pciaddr %qx\n",
501 		    ss, (unsigned long long)offset, (unsigned long long)pciaddr));
502 		/* pass it onto the psycho */
503 		return (bus_space_map2(t, sc->sc_range[i].phys_hi,
504 			pciaddr, size, flags, vaddr, hp));
505 	}
506 	DPRINTF(EDB_BUSMAP, (": FAILED\n"));
507 	return (EINVAL);
508 }
509 
510 static paddr_t
511 ebus_bus_mmap(t, paddr, off, prot, flags)
512 	bus_space_tag_t t;
513 	bus_addr_t paddr;
514 	off_t off;
515 	int prot;
516 	int flags;
517 {
518 	bus_addr_t offset = paddr;
519 	struct ebus_softc *sc = t->cookie;
520 	int i;
521 
522 	for (i = 0; i < sc->sc_nrange; i++) {
523 		bus_addr_t paddr = ((bus_addr_t)sc->sc_range[i].child_hi << 32) |
524 		    sc->sc_range[i].child_lo;
525 
526 		if (offset != paddr)
527 			continue;
528 
529 		DPRINTF(EDB_BUSMAP, ("\n_ebus_bus_mmap: mapping paddr %qx\n",
530 		    (unsigned long long)paddr));
531 		return (bus_space_mmap(sc->sc_memtag, paddr, off,
532 				       prot, flags));
533 	}
534 
535 	return (-1);
536 }
537 
538 /*
539  * install an interrupt handler for a PCI device
540  */
541 void *
542 ebus_intr_establish(t, pri, level, flags, handler, arg)
543 	bus_space_tag_t t;
544 	int pri;
545 	int level;
546 	int flags;
547 	int (*handler) __P((void *));
548 	void *arg;
549 {
550 	return (bus_intr_establish(t->parent, pri, level, flags, handler, arg));
551 }
552 
553 /*
554  * bus dma support
555  */
556 int
557 ebus_dmamap_load(t, map, buf, buflen, p, flags)
558 	bus_dma_tag_t t;
559 	bus_dmamap_t map;
560 	void *buf;
561 	bus_size_t buflen;
562 	struct proc *p;
563 	int flags;
564 {
565 	struct ebus_softc *sc = t->_cookie;
566 
567 	return (iommu_dvmamap_load(t, sc->sc_parent->sc_is, map, buf, buflen,
568 	    p, flags));
569 }
570 
571 void
572 ebus_dmamap_unload(t, map)
573 	bus_dma_tag_t t;
574 	bus_dmamap_t map;
575 {
576 	struct ebus_softc *sc = t->_cookie;
577 
578 	iommu_dvmamap_unload(t, sc->sc_parent->sc_is, map);
579 }
580 
581 void
582 ebus_dmamap_sync(t, map, offset, len, ops)
583 	bus_dma_tag_t t;
584 	bus_dmamap_t map;
585 	bus_addr_t offset;
586 	bus_size_t len;
587 	int ops;
588 {
589 	struct ebus_softc *sc = t->_cookie;
590 
591 	iommu_dvmamap_sync(t, sc->sc_parent->sc_is, map, offset, len, ops);
592 	bus_dmamap_sync(t->_parent, map, offset, len, ops);
593 }
594 
595 int
596 ebus_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags)
597 	bus_dma_tag_t t;
598 	bus_size_t size;
599 	bus_size_t alignment;
600 	bus_size_t boundary;
601 	bus_dma_segment_t *segs;
602 	int nsegs;
603 	int *rsegs;
604 	int flags;
605 {
606 	struct ebus_softc *sc = t->_cookie;
607 
608 	return (iommu_dvmamem_alloc(t, sc->sc_parent->sc_is, size, alignment,
609 	    boundary, segs, nsegs, rsegs, flags));
610 }
611 
612 void
613 ebus_dmamem_free(t, segs, nsegs)
614 	bus_dma_tag_t t;
615 	bus_dma_segment_t *segs;
616 	int nsegs;
617 {
618 	struct ebus_softc *sc = t->_cookie;
619 
620 	iommu_dvmamem_free(t, sc->sc_parent->sc_is, segs, nsegs);
621 }
622 
623 int
624 ebus_dmamem_map(t, segs, nsegs, size, kvap, flags)
625 	bus_dma_tag_t t;
626 	bus_dma_segment_t *segs;
627 	int nsegs;
628 	size_t size;
629 	caddr_t *kvap;
630 	int flags;
631 {
632 	struct ebus_softc *sc = t->_cookie;
633 
634 	return (iommu_dvmamem_map(t, sc->sc_parent->sc_is, segs, nsegs,
635 	    size, kvap, flags));
636 }
637 
638 void
639 ebus_dmamem_unmap(t, kva, size)
640 	bus_dma_tag_t t;
641 	caddr_t kva;
642 	size_t size;
643 {
644 	struct ebus_softc *sc = t->_cookie;
645 
646 	iommu_dvmamem_unmap(t, sc->sc_parent->sc_is, kva, size);
647 }
648